Line data Source code
1 : // Copyright © 2021 HQS Quantum Simulations GmbH. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
4 : // in compliance with the License. You may obtain a copy of the License at
5 : //
6 : // http://www.apache.org/licenses/LICENSE-2.0
7 : //
8 : // Unless required by applicable law or agreed to in writing, software distributed under the
9 : // License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
10 : // express or implied. See the License for the specific language governing permissions and
11 : // limitations under the License.
12 : //
13 :
14 : //! Definition Operation that defines the classical registers and variables in the Circuit.
15 : //!
16 : //! In general, every circuit will have at least one Definition operation. The main
17 : //! reasons one would need a Definition operation in a circuit is for measurements.
18 : //! If you need to measure something in a circuit using a MeasureQubit operation
19 : //! (see qoqo.operations.measurememnt_operations.py), you need to define the classical
20 : //! register used to store the measurement result.
21 : //!
22 : //! You need to add the Define operation to the circuit before what you are defining is used.
23 : //! Therefore, qoqo uses the convention that Definition operations are added first to the circuit,
24 : //! before you add any other operations.
25 : //!
26 : //! There are 5 types of Definitions:
27 : //! (1) DefinitionFloat, where the register defined contains a float or floats.
28 : //! (2) DefinitionComplex, where the register defined contains a complex or complexes.
29 : //! (3) DefinitionUsize, where the register defined contains an integer or integers.
30 : //! (4) DefinitionBit, where the register defined contains a bit or bits.
31 : //! (5) InputSymbolic, where the user can define a floating point type value to replace a certain symbolic parameter.
32 : //!
33 :
34 : use crate::operations::{Define, InvolveQubits, InvolvedQubits, Operate, RoqoqoError, Substitute};
35 :
36 : /// DefinitionFloat is the Definition for a floating point type register.
37 : ///
38 : #[derive(
39 3 : Debug,
40 18 : Clone,
41 22 : PartialEq,
42 28 : roqoqo_derive::Operate,
43 2 : roqoqo_derive::Substitute,
44 1 : roqoqo_derive::Define,
45 : )]
46 : #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
47 : pub struct DefinitionFloat {
48 : /// The name of the register that is defined.
49 : name: String,
50 : /// The length of the register that is defined, usually the number of qubits to be measured.
51 : length: usize,
52 : /// True/False if the variable is an output to the program.
53 : is_output: bool,
54 : }
55 :
56 : #[allow(non_upper_case_globals)]
57 : const TAGS_DefinitionFloat: &[&str; 3] = &["Operation", "Definition", "DefinitionFloat"];
58 :
59 : // Implementing the InvolveQubits trait for DefinitionFloat.
60 : impl InvolveQubits for DefinitionFloat {
61 : /// Lists all involved Qubits (here, none).
62 1 : fn involved_qubits(&self) -> InvolvedQubits {
63 1 : InvolvedQubits::None
64 1 : }
65 : }
66 :
67 : /// DefinitionComplex is the Definition for a Complex type register.
68 : ///
69 : #[derive(
70 1 : Debug,
71 3 : Clone,
72 8 : PartialEq,
73 15 : roqoqo_derive::Operate,
74 2 : roqoqo_derive::Substitute,
75 1 : roqoqo_derive::Define,
76 : )]
77 : #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
78 : pub struct DefinitionComplex {
79 : /// The name of the register that is defined.
80 : name: String,
81 : /// The length of the register that is defined, usually the number of qubits to be measured.
82 : length: usize,
83 : /// True/False if the variable is an output to the program.
84 : is_output: bool,
85 : }
86 :
87 : #[allow(non_upper_case_globals)]
88 : const TAGS_DefinitionComplex: &[&str; 3] = &["Operation", "Definition", "DefinitionComplex"];
89 :
90 : // Implementing the InvolveQubits trait for DefinitionComplex.
91 : impl InvolveQubits for DefinitionComplex {
92 : /// Lists all involved Qubits (here, none).
93 1 : fn involved_qubits(&self) -> InvolvedQubits {
94 1 : InvolvedQubits::None
95 1 : }
96 : }
97 :
98 : /// DefinitionUsize is the Definition for an Integer type register.
99 : ///
100 : #[derive(
101 1 : Debug,
102 3 : Clone,
103 8 : PartialEq,
104 15 : roqoqo_derive::Operate,
105 2 : roqoqo_derive::Substitute,
106 1 : roqoqo_derive::Define,
107 : )]
108 : #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
109 : pub struct DefinitionUsize {
110 : /// The name of the register that is defined.
111 : name: String,
112 : /// The length of the register that is defined, usually the number of qubits to be measured.
113 : length: usize,
114 : /// True/False if the variable is an output to the program.
115 : is_output: bool,
116 : }
117 :
118 : #[allow(non_upper_case_globals)]
119 : const TAGS_DefinitionUsize: &[&str; 3] = &["Operation", "Definition", "DefinitionUsize"];
120 :
121 : // Implementing the InvolveQubits trait for DefinitionUsize.
122 : impl InvolveQubits for DefinitionUsize {
123 : /// Lists all involved Qubits (here, none).
124 1 : fn involved_qubits(&self) -> InvolvedQubits {
125 1 : InvolvedQubits::None
126 1 : }
127 : }
128 :
129 : /// DefinitionBit is the Definition for a Bit type register.
130 : ///
131 : #[derive(
132 1 : Debug,
133 6 : Clone,
134 11 : PartialEq,
135 20 : roqoqo_derive::Operate,
136 2 : roqoqo_derive::Substitute,
137 1 : roqoqo_derive::Define,
138 : )]
139 : #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
140 : pub struct DefinitionBit {
141 : /// The name of the register that is defined.
142 : name: String,
143 : /// The length of the register that is defined, usually the number of qubits to be measured.
144 : length: usize,
145 : /// True/False if the variable is an output to the program.
146 : is_output: bool,
147 : }
148 :
149 : #[allow(non_upper_case_globals)]
150 : const TAGS_DefinitionBit: &[&str; 3] = &["Operation", "Definition", "DefinitionBit"];
151 :
152 : // Implementing the InvolveQubits trait for DefinitionBit.
153 : impl InvolveQubits for DefinitionBit {
154 : /// Lists all involved Qubits (here, none).
155 1 : fn involved_qubits(&self) -> InvolvedQubits {
156 1 : InvolvedQubits::None
157 1 : }
158 : }
159 :
160 : /// InputSymbolic is the Definition for a floating point type parameter which will replace a certain symbolic parameter.
161 : ///
162 : #[derive(
163 1 : Debug,
164 3 : Clone,
165 9 : PartialEq,
166 18 : roqoqo_derive::Operate,
167 3 : roqoqo_derive::Substitute,
168 2 : roqoqo_derive::Define,
169 : )]
170 : #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
171 : pub struct InputSymbolic {
172 : /// The name of the register that is defined.
173 : name: String,
174 : /// The floating point type value by which to replace the quantities marked as "name".
175 : input: f64,
176 : }
177 :
178 : #[allow(non_upper_case_globals)]
179 : const TAGS_InputSymbolic: &[&str; 3] = &["Operation", "Definition", "InputSymbolic"];
180 :
181 : // Implementing the InvolveQubits trait for InputSymbolic.
182 : impl InvolveQubits for InputSymbolic {
183 : /// Lists all involved Qubits (here, none).
184 1 : fn involved_qubits(&self) -> InvolvedQubits {
185 1 : InvolvedQubits::None
186 1 : }
187 : }
|