12
12
#include "Definitions.hpp"
13
13
#include "circuit_optimizer/CircuitOptimizer.hpp"
14
14
#include "ir/QuantumComputation.hpp"
15
+ #include "ir/operations/Control.hpp"
15
16
#include "ir/operations/OpType.hpp"
16
17
#include "ir/operations/Operation.hpp"
17
18
#include "ir/operations/StandardOperation.hpp"
18
19
19
- #include <algorithm>
20
20
#include <cmath>
21
21
#include <complex>
22
22
#include <cstddef>
@@ -39,8 +39,8 @@ template <typename T>
39
39
}
40
40
41
41
template <typename T>
42
- [[nodiscard]] auto isNormalized(const std::vector<T>& vec, double EPS ) -> bool {
43
- return std::abs(1 - twoNorm(vec)) < EPS ;
42
+ [[nodiscard]] auto isNormalized(const std::vector<T>& vec, double Eps ) -> bool {
43
+ return std::abs(1 - twoNorm(vec)) < Eps ;
44
44
}
45
45
46
46
[[nodiscard]] auto kroneckerProduct(const Matrix& matrixA,
@@ -105,7 +105,7 @@ template <typename T>
105
105
[[nodiscard]] auto multiplex(OpType targetGate, std::vector<double> angles,
106
106
bool lastCnot) -> QuantumComputation {
107
107
size_t const listLen = angles.size();
108
- Qubit const localNumQubits = static_cast<Qubit>(
108
+ auto const localNumQubits = static_cast<Qubit>(
109
109
std::floor(std::log2(static_cast<double>(listLen))) + 1);
110
110
QuantumComputation multiplexer{localNumQubits};
111
111
// recursion base case
@@ -155,15 +155,15 @@ template <typename T>
155
155
}
156
156
157
157
[[nodiscard]] auto blochAngles(std::complex<double> const complexA,
158
- std::complex<double> const complexB, double EPS )
158
+ std::complex<double> const complexB, double Eps )
159
159
-> std::tuple<std::complex<double>, double, double> {
160
160
double theta{0};
161
161
double phi{0};
162
162
double finalT{0};
163
163
double const magA = std::abs(complexA);
164
164
double const magB = std::abs(complexB);
165
165
double const finalR = sqrt(pow(magA, 2) + pow(magB, 2));
166
- if (finalR > EPS ) {
166
+ if (finalR > Eps ) {
167
167
theta = 2 * acos(magA / finalR);
168
168
double const aAngle = std::arg(complexA);
169
169
double const bAngle = std::arg(complexB);
@@ -177,10 +177,10 @@ template <typename T>
177
177
// rotations make up block diagonal matrix U
178
178
[[nodiscard]] auto
179
179
rotationsToDisentangle(const std::vector<std::complex<double>>& amplitudes,
180
- double EPS )
180
+ double Eps )
181
181
-> std::tuple<std::vector<std::complex<double>>, std::vector<double>,
182
182
std::vector<double>> {
183
- size_t amplitudesHalf = amplitudes.size() / 2;
183
+ size_t const amplitudesHalf = amplitudes.size() / 2;
184
184
std::vector<std::complex<double>> remainingVector;
185
185
std::vector<double> thetas;
186
186
std::vector<double> phis;
@@ -191,7 +191,7 @@ rotationsToDisentangle(const std::vector<std::complex<double>>& amplitudes,
191
191
192
192
for (size_t i = 0; i < amplitudesHalf; ++i) {
193
193
auto [remains, theta, phi] =
194
- blochAngles(amplitudes[2 * i], amplitudes[2 * i + 1], EPS );
194
+ blochAngles(amplitudes[2 * i], amplitudes[2 * i + 1], Eps );
195
195
remainingVector.emplace_back(remains);
196
196
// minus sign because we move it to zero
197
197
thetas.emplace_back(-theta);
@@ -203,21 +203,21 @@ rotationsToDisentangle(const std::vector<std::complex<double>>& amplitudes,
203
203
// creates circuit that takes desired vector to zero
204
204
[[nodiscard]] auto
205
205
gatesToUncompute(std::vector<std::complex<double>>& amplitudes,
206
- size_t numQubits, double EPS ) -> QuantumComputation {
206
+ size_t numQubits, double Eps ) -> QuantumComputation {
207
207
QuantumComputation disentangler{numQubits};
208
208
for (size_t i = 0; i < numQubits; ++i) {
209
209
// rotations to disentangle LSB
210
210
auto [remainingParams, thetas, phis] =
211
- rotationsToDisentangle(amplitudes, EPS );
211
+ rotationsToDisentangle(amplitudes, Eps );
212
212
amplitudes = remainingParams;
213
213
// perform required rotations
214
214
bool addLastCnot = true;
215
215
double const phisNorm = twoNorm(phis);
216
216
double const thetasNorm = twoNorm(thetas);
217
- if (phisNorm > EPS && thetasNorm > EPS ) {
217
+ if (phisNorm > Eps && thetasNorm > Eps ) {
218
218
addLastCnot = false;
219
219
}
220
- if (phisNorm > EPS ) {
220
+ if (phisNorm > Eps ) {
221
221
// call multiplex with RZGate
222
222
QuantumComputation rzMultiplexer = multiplex(RZ, phis, addLastCnot);
223
223
// append rzMultiplexer to disentangler, but it should only attach on
@@ -236,7 +236,7 @@ gatesToUncompute(std::vector<std::complex<double>>& amplitudes,
236
236
}
237
237
disentangler.emplace_back<Operation>(rzMultiplexer.asOperation());
238
238
}
239
- if (thetasNorm > EPS ) {
239
+ if (thetasNorm > Eps ) {
240
240
// call multiplex with RYGate
241
241
QuantumComputation ryMultiplexer = multiplex(RY, thetas, addLastCnot);
242
242
// append reversed ry_multiplexer to disentangler, but it should only
@@ -261,17 +261,17 @@ gatesToUncompute(std::vector<std::complex<double>>& amplitudes,
261
261
// adjust global phase according to the last e^(it)
262
262
double const arg = -std::arg(std::accumulate(
263
263
amplitudes.begin(), amplitudes.end(), std::complex<double>(0, 0)));
264
- if (std::abs(arg) > EPS ) {
264
+ if (std::abs(arg) > Eps ) {
265
265
disentangler.gphase(arg);
266
266
}
267
267
return disentangler;
268
268
}
269
269
270
270
auto createStatePreparationCircuit(
271
- std::vector<std::complex<double>>& amplitudes, double EPS )
271
+ std::vector<std::complex<double>>& amplitudes, double Eps )
272
272
-> QuantumComputation {
273
273
274
- if (!isNormalized(amplitudes, EPS )) {
274
+ if (!isNormalized(amplitudes, Eps )) {
275
275
throw std::invalid_argument{
276
276
"Using State Preparation with Amplitudes that are not normalized"};
277
277
}
@@ -284,7 +284,7 @@ auto createStatePreparationCircuit(
284
284
}
285
285
const auto numQubits = static_cast<size_t>(std::log2(amplitudes.size()));
286
286
QuantumComputation toZeroCircuit =
287
- gatesToUncompute(amplitudes, numQubits, EPS );
287
+ gatesToUncompute(amplitudes, numQubits, Eps );
288
288
289
289
// invert circuit
290
290
toZeroCircuit.invert();
0 commit comments