Maestro 0.3.1
Unified interface for quantum circuit simulation
Loading...
Searching...
No Matches
QCSimExtendedStabilizer.h
Go to the documentation of this file.
1
12
13#pragma once
14
15#ifndef _QCSIM_EXTENDED_STABILIZER_H
16#define _QCSIM_EXTENDED_STABILIZER_H 1
17
18#include <memory>
19#include <random>
20#include <string>
21#include <utility>
22#include <vector>
23
24#include "ExtendedStabilizer.h"
25
26namespace Simulators {
27
29 public:
30 explicit QCSimExtendedStabilizer(size_t nrQubits)
31 : simulator(std::make_unique<QC::ExtendedStabilizer>(nrQubits)) {}
32
34 size_t nrQubits,
35 const QC::ExtendedStabilizerApproximationPolicy& policy)
36 : simulator(std::make_unique<QC::ExtendedStabilizer>(nrQubits, policy)) {}
37
38 size_t GetNrQubits() const { return simulator->GetNrQubits(); }
39
40 void Reset(size_t nrQubits) { simulator->Reset(nrQubits); }
41
42 void SetRandomSeed(std::mt19937::result_type seed) {
43 simulator->SetRandomSeed(seed);
44 }
45
46 void ApplyH(size_t qubit) { simulator->ApplyH(qubit); }
47
48 void ApplyS(size_t qubit) { simulator->ApplyS(qubit); }
49
50 void ApplyX(size_t qubit) { simulator->ApplyX(qubit); }
51
52 void ApplyY(size_t qubit) { simulator->ApplyY(qubit); }
53
54 void ApplyZ(size_t qubit) { simulator->ApplyZ(qubit); }
55
56 void ApplyK(size_t qubit) { simulator->ApplyK(qubit); }
57
58 bool Measure(size_t qubit) { return simulator->Measure(qubit); }
59
60 double GetQubitProbability(size_t qubit) const {
61 return simulator->GetQubitProbability(qubit);
62 }
63
64 double ExpectationValue(const std::string& pauliString) const {
65 return simulator->ExpectationValue(pauliString);
66 }
67
68 void SaveState() { simulator->SaveState(); }
69
70 void RestoreState() { simulator->RestoreState(); }
71
72 std::unique_ptr<QCSimExtendedStabilizer> Clone() const {
73 return std::unique_ptr<QCSimExtendedStabilizer>(
74 new QCSimExtendedStabilizer(simulator->Clone()));
75 }
76
77 const std::vector<QC::ExtendedFrame>& GetFrames() const noexcept {
78 return simulator->GetFrames();
79 }
80
81 const QC::ExtendedStabilizerApproximationPolicy& GetApproximationPolicy()
82 const noexcept {
83 return simulator->GetApproximationPolicy();
84 }
85
86 const QC::ExtendedStabilizerApproximationStatistics&
87 GetApproximationStatistics() const noexcept {
88 return simulator->GetApproximationStatistics();
89 }
90
91 double GetApproximationErrorBound() const noexcept {
92 return simulator->GetApproximationErrorBound();
93 }
94
96 const QC::ExtendedStabilizerApproximationPolicy& policy) {
97 simulator->SetApproximationPolicy(policy);
98 }
99
100 // Keep the gate names and control/target order consistent with the other
101 // Maestro QCSim wrappers. QCSim's ExtendedStabilizer uses target/control.
102 void ApplySDG(size_t qubit) { simulator->ApplySdg(qubit); }
103
104 void ApplySX(size_t qubit) { simulator->ApplySx(qubit); }
105
106 void ApplySXDG(size_t qubit) { simulator->ApplySxDag(qubit); }
107
108 void ApplySxDAG(size_t qubit) { ApplySXDG(qubit); }
109
110 void ApplyCX(size_t controlQubit, size_t targetQubit) {
111 simulator->ApplyCX(targetQubit, controlQubit);
112 }
113
114 void ApplyCY(size_t controlQubit, size_t targetQubit) {
115 simulator->ApplyCY(targetQubit, controlQubit);
116 }
117
118 void ApplyCZ(size_t controlQubit, size_t targetQubit) {
119 simulator->ApplyCZ(targetQubit, controlQubit);
120 }
121
122 void ApplySWAP(size_t qubit1, size_t qubit2) {
123 simulator->ApplySwap(qubit1, qubit2);
124 }
125
126 void ApplyISWAP(size_t qubit1, size_t qubit2) {
127 simulator->ApplyISwap(qubit1, qubit2);
128 }
129
130 void ApplyISWAPDG(size_t qubit1, size_t qubit2) {
131 simulator->ApplyISwapDag(qubit1, qubit2);
132 }
133
134 void ApplyRX(size_t qubit, double angle) {
135 simulator->ApplyRx(qubit, angle);
136 }
137
138 void ApplyRY(size_t qubit, double angle) {
139 simulator->ApplyRy(qubit, angle);
140 }
141
142 void ApplyRZ(size_t qubit, double angle) {
143 simulator->ApplyRz(qubit, angle);
144 }
145
146 void ApplyP(size_t qubit, double lambda) { ApplyRZ(qubit, lambda); }
147
148 void ApplyT(size_t qubit) { ApplyRZ(qubit, kPi / 4.0); }
149
150 void ApplyTDG(size_t qubit) { ApplyRZ(qubit, -kPi / 4.0); }
151
152 void ApplyU(size_t qubit, double theta, double phi, double lambda,
153 double gamma = 0.0) {
154 // A global phase has no observable effect for a non-controlled U gate.
155 (void)gamma;
156 ApplyRZ(qubit, lambda);
157 ApplyRY(qubit, theta);
158 ApplyRZ(qubit, phi);
159 }
160
161 void ApplyCH(size_t controlQubit, size_t targetQubit) {
162 ApplyH(targetQubit);
163 ApplySDG(targetQubit);
164 ApplyCX(controlQubit, targetQubit);
165 ApplyH(targetQubit);
166 ApplyT(targetQubit);
167 ApplyCX(controlQubit, targetQubit);
168 ApplyT(targetQubit);
169 ApplyH(targetQubit);
170 ApplyS(targetQubit);
171 ApplyX(targetQubit);
172 ApplyS(controlQubit);
173 }
174
175 void ApplyCU(size_t controlQubit, size_t targetQubit, double theta,
176 double phi, double lambda, double gamma = 0.0) {
177 if (gamma != 0.0) ApplyP(controlQubit, gamma);
178
179 const double lambdaPlusPhiHalf = 0.5 * (lambda + phi);
180 const double halfTheta = 0.5 * theta;
181 ApplyP(targetQubit, 0.5 * (lambda - phi));
182 ApplyP(controlQubit, lambdaPlusPhiHalf);
183 ApplyCX(controlQubit, targetQubit);
184 ApplyU(targetQubit, -halfTheta, 0.0, -lambdaPlusPhiHalf);
185 ApplyCX(controlQubit, targetQubit);
186 ApplyU(targetQubit, halfTheta, phi, 0.0);
187 }
188
189 void ApplyCRX(size_t controlQubit, size_t targetQubit, double angle) {
190 const double halfAngle = angle * 0.5;
191
192 ApplyH(targetQubit);
193 ApplyCX(controlQubit, targetQubit);
194 ApplyRZ(targetQubit, -halfAngle);
195 ApplyCX(controlQubit, targetQubit);
196 ApplyRZ(targetQubit, halfAngle);
197 ApplyH(targetQubit);
198 }
199
200 void ApplyCRx(size_t controlQubit, size_t targetQubit, double angle) {
201 ApplyCRX(controlQubit, targetQubit, angle);
202 }
203
204 void ApplyCRY(size_t controlQubit, size_t targetQubit, double angle) {
205 const double halfAngle = angle * 0.5;
206 ApplyRY(targetQubit, halfAngle);
207 ApplyCX(controlQubit, targetQubit);
208 ApplyRY(targetQubit, -halfAngle);
209 ApplyCX(controlQubit, targetQubit);
210 }
211
212 void ApplyCRy(size_t controlQubit, size_t targetQubit, double angle) {
213 ApplyCRY(controlQubit, targetQubit, angle);
214 }
215
216 void ApplyCRZ(size_t controlQubit, size_t targetQubit, double angle) {
217 const double halfAngle = angle * 0.5;
218
219 ApplyRZ(targetQubit, halfAngle);
220 ApplyCX(controlQubit, targetQubit);
221 ApplyRZ(targetQubit, -halfAngle);
222 ApplyCX(controlQubit, targetQubit);
223 }
224
225 void ApplyCRz(size_t controlQubit, size_t targetQubit, double angle) {
226 ApplyCRZ(controlQubit, targetQubit, angle);
227 }
228
229 void ApplyCP(size_t controlQubit, size_t targetQubit, double lambda) {
230 const double halfAngle = lambda * 0.5;
231 ApplyP(controlQubit, halfAngle);
232 ApplyCX(controlQubit, targetQubit);
233 ApplyP(targetQubit, -halfAngle);
234 ApplyCX(controlQubit, targetQubit);
235 ApplyP(targetQubit, halfAngle);
236 }
237
238 void ApplyCS(size_t controlQubit, size_t targetQubit) {
239 ApplyT(controlQubit);
240 ApplyT(targetQubit);
241 ApplyCX(controlQubit, targetQubit);
242 ApplyTDG(targetQubit);
243 ApplyCX(controlQubit, targetQubit);
244 }
245
246 void ApplyCSDAG(size_t controlQubit, size_t targetQubit) {
247 ApplyCX(controlQubit, targetQubit);
248 ApplyT(targetQubit);
249 ApplyCX(controlQubit, targetQubit);
250 ApplyTDG(controlQubit);
251 ApplyTDG(targetQubit);
252 }
253
254 void ApplyCSX(size_t controlQubit, size_t targetQubit) {
255 ApplyH(targetQubit);
256 ApplyCS(controlQubit, targetQubit);
257 ApplyH(targetQubit);
258 }
259
260 void ApplyCSx(size_t controlQubit, size_t targetQubit) {
261 ApplyCSX(controlQubit, targetQubit);
262 }
263
264 void ApplyCSXDAG(size_t controlQubit, size_t targetQubit) {
265 ApplyH(targetQubit);
266 ApplyCSDAG(controlQubit, targetQubit);
267 ApplyH(targetQubit);
268 }
269
270 void ApplyCSxDAG(size_t controlQubit, size_t targetQubit) {
271 ApplyCSXDAG(controlQubit, targetQubit);
272 }
273
274 void ApplyCSwap(size_t controlQubit, size_t targetQubit1,
275 size_t targetQubit2) {
276 const size_t q1 = controlQubit;
277 const size_t q2 = targetQubit1;
278 const size_t q3 = targetQubit2;
279
280 ApplyCX(q3, q2);
281 ApplyCSX(q2, q3);
282 ApplyCX(q1, q2);
283
284 ApplyP(q3, kPi);
285 ApplyP(q2, -kPi / 2.0);
286
287 ApplyCSX(q2, q3);
288 ApplyCX(q1, q2);
289
290 ApplyP(q3, kPi);
291 ApplyCSX(q1, q3);
292 ApplyCX(q3, q2);
293 }
294
295 void ApplyCCX(size_t controlQubit1, size_t controlQubit2,
296 size_t targetQubit) {
297 const size_t q1 = controlQubit1;
298 const size_t q2 = controlQubit2;
299 const size_t q3 = targetQubit;
300
301 ApplyCSX(q2, q3);
302 ApplyCX(q1, q2);
303 ApplyCSXDAG(q2, q3);
304 ApplyCX(q1, q2);
305 ApplyCSX(q1, q3);
306 }
307
308 private:
310 std::unique_ptr<QC::ExtendedStabilizer> simulatorToOwn)
311 : simulator(std::move(simulatorToOwn)) {}
312
313 std::unique_ptr<QC::ExtendedStabilizer> simulator;
314 static constexpr double kPi = 3.141592653589793238462643383279502884;
315};
316
317} // namespace Simulators
318
319#endif // _QCSIM_EXTENDED_STABILIZER_H
void ApplyCU(size_t controlQubit, size_t targetQubit, double theta, double phi, double lambda, double gamma=0.0)
std::unique_ptr< QCSimExtendedStabilizer > Clone() const
void ApplyCSXDAG(size_t controlQubit, size_t targetQubit)
double GetApproximationErrorBound() const noexcept
void ApplyCCX(size_t controlQubit1, size_t controlQubit2, size_t targetQubit)
void ApplySWAP(size_t qubit1, size_t qubit2)
void ApplyCSxDAG(size_t controlQubit, size_t targetQubit)
void ApplyISWAPDG(size_t qubit1, size_t qubit2)
const std::vector< QC::ExtendedFrame > & GetFrames() const noexcept
void ApplyCRY(size_t controlQubit, size_t targetQubit, double angle)
void ApplyCSwap(size_t controlQubit, size_t targetQubit1, size_t targetQubit2)
void ApplyRX(size_t qubit, double angle)
void ApplyCSX(size_t controlQubit, size_t targetQubit)
void ApplyCX(size_t controlQubit, size_t targetQubit)
QCSimExtendedStabilizer(size_t nrQubits, const QC::ExtendedStabilizerApproximationPolicy &policy)
void ApplyCS(size_t controlQubit, size_t targetQubit)
void ApplyCRZ(size_t controlQubit, size_t targetQubit, double angle)
void SetApproximationPolicy(const QC::ExtendedStabilizerApproximationPolicy &policy)
void ApplyISWAP(size_t qubit1, size_t qubit2)
void ApplyP(size_t qubit, double lambda)
void ApplyRY(size_t qubit, double angle)
void ApplyRZ(size_t qubit, double angle)
void ApplyCRx(size_t controlQubit, size_t targetQubit, double angle)
void ApplyCSx(size_t controlQubit, size_t targetQubit)
double ExpectationValue(const std::string &pauliString) const
void ApplyCRX(size_t controlQubit, size_t targetQubit, double angle)
const QC::ExtendedStabilizerApproximationPolicy & GetApproximationPolicy() const noexcept
const QC::ExtendedStabilizerApproximationStatistics & GetApproximationStatistics() const noexcept
double GetQubitProbability(size_t qubit) const
void ApplyCH(size_t controlQubit, size_t targetQubit)
void ApplyCP(size_t controlQubit, size_t targetQubit, double lambda)
void ApplyCRy(size_t controlQubit, size_t targetQubit, double angle)
void ApplyU(size_t qubit, double theta, double phi, double lambda, double gamma=0.0)
void ApplyCY(size_t controlQubit, size_t targetQubit)
void SetRandomSeed(std::mt19937::result_type seed)
void ApplyCSDAG(size_t controlQubit, size_t targetQubit)
void ApplyCRz(size_t controlQubit, size_t targetQubit, double angle)
void ApplyCZ(size_t controlQubit, size_t targetQubit)