Maestro 0.2.11
Unified interface for quantum circuit simulation
Loading...
Searching...
No Matches
QCSimSimulator.h
Go to the documentation of this file.
1
12
13#pragma once
14
15#ifndef _QCSIMSIMULATOR_H
16#define _QCSIMSIMULATOR_H
17
18#ifdef INCLUDED_BY_FACTORY
19
20#include "QCSimState.h"
21
22#define _USE_MATH_DEFINES
23#include <math.h>
24
25namespace Simulators {
26// TODO: Maybe use the pimpl idiom
27// https://en.cppreference.com/w/cpp/language/pimpl to hide the implementation
28// for good but during development this should be good enough
29namespace Private {
30
31class IndividualSimulator;
32
44class QCSimSimulator : public QCSimState {
45 friend class IndividualSimulator;
46
47 public:
48 QCSimSimulator() = default;
49 // allow no copy or assignment
50 QCSimSimulator(const QCSimSimulator &) = delete;
51 QCSimSimulator &operator=(const QCSimSimulator &) = delete;
52
53 // but allow moving
54 QCSimSimulator(QCSimSimulator &&other) = default;
55 QCSimSimulator &operator=(QCSimSimulator &&other) = default;
56
57
63 void ApplyGenericOneQubitGate(Types::qubit_t qubit,
64 const Eigen::Matrix2cd& gate) override {
65 if (GetSimulationType() != SimulationType::kMatrixProductState &&
66 GetSimulationType() != SimulationType::kTensorNetwork&&
67 GetSimulationType() != SimulationType::kStatevector)
68 throw std::runtime_error("QCSimSimulator::ApplyGenericOneQubitGate: Unsupported simulation type.");
69
70 const QC::Gates::AppliedGate<> agate(gate, qubit);
71
72 if (GetSimulationType() == SimulationType::kMatrixProductState)
73 mpsSimulator->ApplyGate(agate);
74 else if (GetSimulationType() == SimulationType::kTensorNetwork)
75 tensorNetwork->AddGate(agate, qubit);
76 else if (GetSimulationType() == SimulationType::kStatevector)
77 state->ApplyGate(agate);
78
79 NotifyObservers({qubit});
80 }
81
88 void ApplyGenericTwoQubitGate(Types::qubit_t qubit0, Types::qubit_t qubit1,
89 const Eigen::Matrix4cd& gate) override {
90 if (GetSimulationType() != SimulationType::kMatrixProductState &&
91 GetSimulationType() != SimulationType::kTensorNetwork &&
92 GetSimulationType() != SimulationType::kStatevector)
93 throw std::runtime_error(
94 "QCSimSimulator::ApplyGenericTwoQubitGate: Unsupported simulation "
95 "type.");
96
97 const QC::Gates::AppliedGate<> agate(gate, qubit0, qubit1);
98
99 if (GetSimulationType() == SimulationType::kMatrixProductState)
100 mpsSimulator->ApplyGate(agate);
101 else if (GetSimulationType() == SimulationType::kTensorNetwork)
102 tensorNetwork->AddGate(agate, qubit0, qubit1);
103 else if (GetSimulationType() == SimulationType::kStatevector)
104 state->ApplyGate(agate);
105
106 NotifyObservers({qubit0, qubit1});
107 }
108
116 void ApplyP(Types::qubit_t qubit, double lambda) override {
117 pgate.SetPhaseShift(lambda);
118 if (GetSimulationType() == SimulationType::kMatrixProductState)
119 mpsSimulator->ApplyGate(pgate, static_cast<unsigned int>(qubit));
120 else if (GetSimulationType() == SimulationType::kStabilizer) {
121 if (std::abs(lambda - M_PI_2) > 1e-10)
122 throw std::runtime_error(
123 "QCSimSimulator::ApplyP: Invalid phase shift "
124 "angle for a Clifford gate.");
125 cliffordSimulator->ApplyS(static_cast<unsigned int>(qubit));
126 } else if (GetSimulationType() == SimulationType::kTensorNetwork)
127 tensorNetwork->AddGate(pgate, static_cast<unsigned int>(qubit));
128 else if (GetSimulationType() == SimulationType::kPauliPropagator)
129 pp->ApplyP(static_cast<unsigned int>(qubit), lambda);
130 else if (GetSimulationType() == SimulationType::kPathIntegral) {
131 QC::Gates::AppliedGate<> agate(pgate.getRawOperatorMatrix(), qubit);
132 pathIntegralSimulator->ApplyGate(agate);
133 }
134 else
135 state->ApplyGate(pgate, static_cast<unsigned int>(qubit));
136 NotifyObservers({qubit});
137 }
138
145 void ApplyX(Types::qubit_t qubit) override {
146 if (GetSimulationType() == SimulationType::kMatrixProductState)
147 mpsSimulator->ApplyGate(xgate, static_cast<unsigned int>(qubit));
148 else if (GetSimulationType() == SimulationType::kStabilizer)
149 cliffordSimulator->ApplyX(static_cast<unsigned int>(qubit));
150 else if (GetSimulationType() == SimulationType::kTensorNetwork)
151 tensorNetwork->AddGate(xgate, static_cast<unsigned int>(qubit));
152 else if (GetSimulationType() == SimulationType::kPauliPropagator)
153 pp->ApplyX(static_cast<unsigned int>(qubit));
154 else if (GetSimulationType() == SimulationType::kPathIntegral) {
155 QC::Gates::AppliedGate<> agate(xgate.getRawOperatorMatrix(), qubit);
156 pathIntegralSimulator->ApplyGate(agate);
157 }
158 else
159 state->ApplyGate(xgate, static_cast<unsigned int>(qubit));
160 NotifyObservers({qubit});
161 }
162
169 void ApplyY(Types::qubit_t qubit) override {
170 if (GetSimulationType() == SimulationType::kMatrixProductState)
171 mpsSimulator->ApplyGate(ygate, static_cast<unsigned int>(qubit));
172 else if (GetSimulationType() == SimulationType::kStabilizer)
173 cliffordSimulator->ApplyY(static_cast<unsigned int>(qubit));
174 else if (GetSimulationType() == SimulationType::kTensorNetwork)
175 tensorNetwork->AddGate(ygate, static_cast<unsigned int>(qubit));
176 else if (GetSimulationType() == SimulationType::kPauliPropagator)
177 pp->ApplyY(static_cast<unsigned int>(qubit));
178 else if (GetSimulationType() == SimulationType::kPathIntegral) {
179 QC::Gates::AppliedGate<> agate(ygate.getRawOperatorMatrix(), qubit);
180 pathIntegralSimulator->ApplyGate(agate);
181 }
182 else
183 state->ApplyGate(ygate, static_cast<unsigned int>(qubit));
184 NotifyObservers({qubit});
185 }
186
193 void ApplyZ(Types::qubit_t qubit) override {
194 if (GetSimulationType() == SimulationType::kMatrixProductState)
195 mpsSimulator->ApplyGate(zgate, static_cast<unsigned int>(qubit));
196 else if (GetSimulationType() == SimulationType::kStabilizer)
197 cliffordSimulator->ApplyZ(static_cast<unsigned int>(qubit));
198 else if (GetSimulationType() == SimulationType::kTensorNetwork)
199 tensorNetwork->AddGate(zgate, static_cast<unsigned int>(qubit));
200 else if (GetSimulationType() == SimulationType::kPauliPropagator)
201 pp->ApplyZ(static_cast<unsigned int>(qubit));
202 else if (GetSimulationType() == SimulationType::kPathIntegral) {
203 QC::Gates::AppliedGate<> agate(zgate.getRawOperatorMatrix(), qubit);
204 pathIntegralSimulator->ApplyGate(agate);
205 }
206 else
207 state->ApplyGate(zgate, static_cast<unsigned int>(qubit));
208 NotifyObservers({qubit});
209 }
210
217 void ApplyH(Types::qubit_t qubit) override {
218 if (GetSimulationType() == SimulationType::kMatrixProductState)
219 mpsSimulator->ApplyGate(h, static_cast<unsigned int>(qubit));
220 else if (GetSimulationType() == SimulationType::kStabilizer)
221 cliffordSimulator->ApplyH(static_cast<unsigned int>(qubit));
222 else if (GetSimulationType() == SimulationType::kTensorNetwork)
223 tensorNetwork->AddGate(h, static_cast<unsigned int>(qubit));
224 else if (GetSimulationType() == SimulationType::kPauliPropagator)
225 pp->ApplyH(static_cast<unsigned int>(qubit));
226 else if (GetSimulationType() == SimulationType::kPathIntegral) {
227 QC::Gates::AppliedGate<> agate(h.getRawOperatorMatrix(), qubit);
228 pathIntegralSimulator->ApplyGate(agate);
229 }
230 else
231 state->ApplyGate(h, static_cast<unsigned int>(qubit));
232 NotifyObservers({qubit});
233 }
234
241 void ApplyS(Types::qubit_t qubit) override {
242 if (GetSimulationType() == SimulationType::kMatrixProductState)
243 mpsSimulator->ApplyGate(sgate, static_cast<unsigned int>(qubit));
244 else if (GetSimulationType() == SimulationType::kStabilizer)
245 cliffordSimulator->ApplyS(static_cast<unsigned int>(qubit));
246 else if (GetSimulationType() == SimulationType::kTensorNetwork)
247 tensorNetwork->AddGate(sgate, static_cast<unsigned int>(qubit));
248 else if (GetSimulationType() == SimulationType::kPauliPropagator)
249 pp->ApplyS(static_cast<unsigned int>(qubit));
250 else if (GetSimulationType() == SimulationType::kPathIntegral) {
251 QC::Gates::AppliedGate<> agate(sgate.getRawOperatorMatrix(), qubit);
252 pathIntegralSimulator->ApplyGate(agate);
253 }
254 else
255 state->ApplyGate(sgate, static_cast<unsigned int>(qubit));
256 NotifyObservers({qubit});
257 }
258
265 void ApplySDG(Types::qubit_t qubit) override {
266 if (GetSimulationType() == SimulationType::kMatrixProductState)
267 mpsSimulator->ApplyGate(sdggate, static_cast<unsigned int>(qubit));
268 else if (GetSimulationType() == SimulationType::kStabilizer)
269 cliffordSimulator->ApplySdg(static_cast<unsigned int>(qubit));
270 else if (GetSimulationType() == SimulationType::kTensorNetwork)
271 tensorNetwork->AddGate(sdggate, static_cast<unsigned int>(qubit));
272 else if (GetSimulationType() == SimulationType::kPauliPropagator)
273 pp->ApplySDG(static_cast<unsigned int>(qubit));
274 else if (GetSimulationType() == SimulationType::kPathIntegral) {
275 QC::Gates::AppliedGate<> agate(sdggate.getRawOperatorMatrix(), qubit);
276 pathIntegralSimulator->ApplyGate(agate);
277 }
278 else
279 state->ApplyGate(sdggate, static_cast<unsigned int>(qubit));
280 NotifyObservers({qubit});
281 }
282
289 void ApplyT(Types::qubit_t qubit) override {
290 if (GetSimulationType() == SimulationType::kMatrixProductState)
291 mpsSimulator->ApplyGate(tgate, static_cast<unsigned int>(qubit));
292 else if (GetSimulationType() == SimulationType::kStabilizer)
293 throw std::runtime_error(
294 "QCSimSimulator::ApplyT: The stabilizer simulator does not support "
295 "non-clifford gates.");
296 else if (GetSimulationType() == SimulationType::kTensorNetwork)
297 tensorNetwork->AddGate(tgate, static_cast<unsigned int>(qubit));
298 else if (GetSimulationType() == SimulationType::kPauliPropagator)
299 pp->ApplyT(static_cast<unsigned int>(qubit));
300 else if (GetSimulationType() == SimulationType::kPathIntegral) {
301 QC::Gates::AppliedGate<> agate(tgate.getRawOperatorMatrix(), qubit);
302 pathIntegralSimulator->ApplyGate(agate);
303 }
304 else
305 state->ApplyGate(tgate, static_cast<unsigned int>(qubit));
306 NotifyObservers({qubit});
307 }
308
315 void ApplyTDG(Types::qubit_t qubit) override {
316 if (GetSimulationType() == SimulationType::kMatrixProductState)
317 mpsSimulator->ApplyGate(tdggate, static_cast<unsigned int>(qubit));
318 else if (GetSimulationType() == SimulationType::kStabilizer)
319 throw std::runtime_error(
320 "QCSimSimulator::ApplyTDG: The stabilizer simulator does not support "
321 "non-clifford gates.");
322 else if (GetSimulationType() == SimulationType::kTensorNetwork)
323 tensorNetwork->AddGate(tdggate, static_cast<unsigned int>(qubit));
324 else if (GetSimulationType() == SimulationType::kPauliPropagator)
325 pp->ApplyTDG(static_cast<unsigned int>(qubit));
326 else if (GetSimulationType() == SimulationType::kPathIntegral) {
327 QC::Gates::AppliedGate<> agate(tdggate.getRawOperatorMatrix(), qubit);
328 pathIntegralSimulator->ApplyGate(agate);
329 }
330 else
331 state->ApplyGate(tdggate, static_cast<unsigned int>(qubit));
332 NotifyObservers({qubit});
333 }
334
341 void ApplySx(Types::qubit_t qubit) override {
342 if (GetSimulationType() == SimulationType::kMatrixProductState)
343 mpsSimulator->ApplyGate(sxgate, static_cast<unsigned int>(qubit));
344 else if (GetSimulationType() == SimulationType::kStabilizer)
345 cliffordSimulator->ApplySx(static_cast<unsigned int>(qubit));
346 else if (GetSimulationType() == SimulationType::kTensorNetwork)
347 tensorNetwork->AddGate(sxgate, static_cast<unsigned int>(qubit));
348 else if (GetSimulationType() == SimulationType::kPauliPropagator)
349 pp->ApplySX(static_cast<unsigned int>(qubit));
350 else if (GetSimulationType() == SimulationType::kPathIntegral) {
351 QC::Gates::AppliedGate<> agate(sxgate.getRawOperatorMatrix(), qubit);
352 pathIntegralSimulator->ApplyGate(agate);
353 }
354 else
355 state->ApplyGate(sxgate, static_cast<unsigned int>(qubit));
356 NotifyObservers({qubit});
357 }
358
365 void ApplySxDAG(Types::qubit_t qubit) override {
366 if (GetSimulationType() == SimulationType::kMatrixProductState)
367 mpsSimulator->ApplyGate(sxdaggate, static_cast<unsigned int>(qubit));
368 else if (GetSimulationType() == SimulationType::kStabilizer)
369 cliffordSimulator->ApplySxDag(static_cast<unsigned int>(qubit));
370 else if (GetSimulationType() == SimulationType::kTensorNetwork)
371 tensorNetwork->AddGate(sxdaggate, static_cast<unsigned int>(qubit));
372 else if (GetSimulationType() == SimulationType::kPauliPropagator)
373 pp->ApplySXDG(static_cast<unsigned int>(qubit));
374 else if (GetSimulationType() == SimulationType::kPathIntegral) {
375 QC::Gates::AppliedGate<> agate(sxdaggate.getRawOperatorMatrix(), qubit);
376 pathIntegralSimulator->ApplyGate(agate);
377 }
378 else
379 state->ApplyGate(sxdaggate, static_cast<unsigned int>(qubit));
380 NotifyObservers({qubit});
381 }
382
389 void ApplyK(Types::qubit_t qubit) override {
390 if (GetSimulationType() == SimulationType::kMatrixProductState)
391 mpsSimulator->ApplyGate(k, static_cast<unsigned int>(qubit));
392 else if (GetSimulationType() == SimulationType::kStabilizer)
393 cliffordSimulator->ApplyK(static_cast<unsigned int>(qubit));
394 else if (GetSimulationType() == SimulationType::kTensorNetwork)
395 tensorNetwork->AddGate(k, static_cast<unsigned int>(qubit));
396 else if (GetSimulationType() == SimulationType::kPauliPropagator)
397 pp->ApplyK(static_cast<unsigned int>(qubit));
398 else if (GetSimulationType() == SimulationType::kPathIntegral) {
399 QC::Gates::AppliedGate<> agate(k.getRawOperatorMatrix(), qubit);
400 pathIntegralSimulator->ApplyGate(agate);
401 }
402 else
403 state->ApplyGate(k, static_cast<unsigned int>(qubit));
404 NotifyObservers({qubit});
405 }
406
414 void ApplyRx(Types::qubit_t qubit, double theta) override {
415 rxgate.SetTheta(theta);
416 if (GetSimulationType() == SimulationType::kMatrixProductState)
417 mpsSimulator->ApplyGate(rxgate, static_cast<unsigned int>(qubit));
418 else if (GetSimulationType() == SimulationType::kStabilizer)
419 throw std::runtime_error(
420 "QCSimSimulator::ApplyRx: The stabilizer "
421 "simulator does not support the Rx gate.");
422 else if (GetSimulationType() == SimulationType::kTensorNetwork)
423 tensorNetwork->AddGate(rxgate, static_cast<unsigned int>(qubit));
424 else if (GetSimulationType() == SimulationType::kPauliPropagator)
425 pp->ApplyRX(static_cast<unsigned int>(qubit), theta);
426 else if (GetSimulationType() == SimulationType::kPathIntegral) {
427 QC::Gates::AppliedGate<> agate(rxgate.getRawOperatorMatrix(), qubit);
428 pathIntegralSimulator->ApplyGate(agate);
429 }
430 else
431 state->ApplyGate(rxgate, static_cast<unsigned int>(qubit));
432 NotifyObservers({qubit});
433 }
434
442 void ApplyRy(Types::qubit_t qubit, double theta) override {
443 rygate.SetTheta(theta);
444 if (GetSimulationType() == SimulationType::kMatrixProductState)
445 mpsSimulator->ApplyGate(rygate, static_cast<unsigned int>(qubit));
446 else if (GetSimulationType() == SimulationType::kStabilizer)
447 throw std::runtime_error(
448 "QCSimSimulator::ApplyRy: The stabilizer "
449 "simulator does not support the Ry gate.");
450 else if (GetSimulationType() == SimulationType::kTensorNetwork)
451 tensorNetwork->AddGate(rygate, static_cast<unsigned int>(qubit));
452 else if (GetSimulationType() == SimulationType::kPauliPropagator)
453 pp->ApplyRY(static_cast<unsigned int>(qubit), theta);
454 else if (GetSimulationType() == SimulationType::kPathIntegral) {
455 QC::Gates::AppliedGate<> agate(rygate.getRawOperatorMatrix(), qubit);
456 pathIntegralSimulator->ApplyGate(agate);
457 }
458 else
459 state->ApplyGate(rygate, static_cast<unsigned int>(qubit));
460 NotifyObservers({qubit});
461 }
462
470 void ApplyRz(Types::qubit_t qubit, double theta) override {
471 rzgate.SetTheta(theta);
472 if (GetSimulationType() == SimulationType::kMatrixProductState)
473 mpsSimulator->ApplyGate(rzgate, static_cast<unsigned int>(qubit));
474 else if (GetSimulationType() == SimulationType::kStabilizer)
475 throw std::runtime_error(
476 "QCSimSimulator::ApplyRz: The stabilizer "
477 "simulator does not support the Rz gate.");
478 else if (GetSimulationType() == SimulationType::kTensorNetwork)
479 tensorNetwork->AddGate(rzgate, static_cast<unsigned int>(qubit));
480 else if (GetSimulationType() == SimulationType::kPauliPropagator)
481 pp->ApplyRZ(static_cast<unsigned int>(qubit), theta);
482 else if (GetSimulationType() == SimulationType::kPathIntegral) {
483 QC::Gates::AppliedGate<> agate(rzgate.getRawOperatorMatrix(), qubit);
484 pathIntegralSimulator->ApplyGate(agate);
485 }
486 else
487 state->ApplyGate(rzgate, static_cast<unsigned int>(qubit));
488 NotifyObservers({qubit});
489 }
490
501 void ApplyU(Types::qubit_t qubit, double theta, double phi, double lambda,
502 double gamma) override {
503 ugate.SetParams(theta, phi, lambda, gamma);
504 if (GetSimulationType() == SimulationType::kMatrixProductState)
505 mpsSimulator->ApplyGate(ugate, static_cast<unsigned int>(qubit));
506 else if (GetSimulationType() == SimulationType::kStabilizer)
507 throw std::runtime_error(
508 "QCSimSimulator::ApplyU: The stabilizer "
509 "simulator does not support the U gate.");
510 else if (GetSimulationType() == SimulationType::kTensorNetwork)
511 tensorNetwork->AddGate(ugate, static_cast<unsigned int>(qubit));
512 else if (GetSimulationType() == SimulationType::kPauliPropagator)
513 pp->ApplyU(static_cast<unsigned int>(qubit), theta, phi, lambda, gamma);
514 else if (GetSimulationType() == SimulationType::kPathIntegral) {
515 QC::Gates::AppliedGate<> agate(ugate.getRawOperatorMatrix(), qubit);
516 pathIntegralSimulator->ApplyGate(agate);
517 }
518 else
519 state->ApplyGate(ugate, static_cast<unsigned int>(qubit));
520 NotifyObservers({qubit});
521 }
522
530 void ApplyCX(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit) override {
531 if (GetSimulationType() == SimulationType::kMatrixProductState)
532 mpsSimulator->ApplyGate(cxgate, static_cast<unsigned int>(tgt_qubit),
533 static_cast<unsigned int>(ctrl_qubit));
534 else if (GetSimulationType() == SimulationType::kStabilizer)
535 cliffordSimulator->ApplyCX(static_cast<unsigned int>(tgt_qubit),
536 static_cast<unsigned int>(ctrl_qubit));
537 else if (GetSimulationType() == SimulationType::kTensorNetwork)
538 tensorNetwork->AddGate(cxgate, static_cast<unsigned int>(ctrl_qubit),
539 static_cast<unsigned int>(tgt_qubit));
540 else if (GetSimulationType() == SimulationType::kPauliPropagator)
541 pp->ApplyCX(static_cast<unsigned int>(ctrl_qubit),
542 static_cast<unsigned int>(tgt_qubit));
543 else if (GetSimulationType() == SimulationType::kPathIntegral) {
544 QC::Gates::AppliedGate<> agate(cxgate.getRawOperatorMatrix(),
545 tgt_qubit, ctrl_qubit);
546 pathIntegralSimulator->ApplyGate(agate);
547 }
548 else
549 state->ApplyGate(cxgate, static_cast<unsigned int>(tgt_qubit),
550 static_cast<unsigned int>(ctrl_qubit));
551 NotifyObservers({tgt_qubit, ctrl_qubit});
552 }
553
561 void ApplyCY(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit) override {
562 if (GetSimulationType() == SimulationType::kMatrixProductState)
563 mpsSimulator->ApplyGate(cygate, static_cast<unsigned int>(tgt_qubit),
564 static_cast<unsigned int>(ctrl_qubit));
565 else if (GetSimulationType() == SimulationType::kStabilizer)
566 cliffordSimulator->ApplyCY(static_cast<unsigned int>(tgt_qubit),
567 static_cast<unsigned int>(ctrl_qubit));
568 else if (GetSimulationType() == SimulationType::kTensorNetwork)
569 tensorNetwork->AddGate(cygate, static_cast<unsigned int>(ctrl_qubit),
570 static_cast<unsigned int>(tgt_qubit));
571 else if (GetSimulationType() == SimulationType::kPauliPropagator)
572 pp->ApplyCY(static_cast<unsigned int>(ctrl_qubit),
573 static_cast<unsigned int>(tgt_qubit));
574 else if (GetSimulationType() == SimulationType::kPathIntegral) {
575 QC::Gates::AppliedGate<> agate(cygate.getRawOperatorMatrix(),
576 tgt_qubit, ctrl_qubit);
577 pathIntegralSimulator->ApplyGate(agate);
578 }
579 else
580 state->ApplyGate(cygate, static_cast<unsigned int>(tgt_qubit),
581 static_cast<unsigned int>(ctrl_qubit));
582 NotifyObservers({tgt_qubit, ctrl_qubit});
583 }
584
592 void ApplyCZ(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit) override {
593 if (GetSimulationType() == SimulationType::kMatrixProductState)
594 mpsSimulator->ApplyGate(czgate, static_cast<unsigned int>(tgt_qubit),
595 static_cast<unsigned int>(ctrl_qubit));
596 else if (GetSimulationType() == SimulationType::kStabilizer)
597 cliffordSimulator->ApplyCZ(static_cast<unsigned int>(tgt_qubit),
598 static_cast<unsigned int>(ctrl_qubit));
599 else if (GetSimulationType() == SimulationType::kTensorNetwork)
600 tensorNetwork->AddGate(czgate, static_cast<unsigned int>(ctrl_qubit),
601 static_cast<unsigned int>(tgt_qubit));
602 else if (GetSimulationType() == SimulationType::kPauliPropagator)
603 pp->ApplyCZ(static_cast<unsigned int>(ctrl_qubit),
604 static_cast<unsigned int>(tgt_qubit));
605 else if (GetSimulationType() == SimulationType::kPathIntegral) {
606 QC::Gates::AppliedGate<> agate(czgate.getRawOperatorMatrix(),
607 tgt_qubit, ctrl_qubit);
608 pathIntegralSimulator->ApplyGate(agate);
609 }
610 else
611 state->ApplyGate(czgate, static_cast<unsigned int>(tgt_qubit),
612 static_cast<unsigned int>(ctrl_qubit));
613 NotifyObservers({tgt_qubit, ctrl_qubit});
614 }
615
624 void ApplyCP(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit,
625 double lambda) override {
626 cpgate.SetPhaseShift(lambda);
627 if (GetSimulationType() == SimulationType::kMatrixProductState)
628 mpsSimulator->ApplyGate(cpgate, static_cast<unsigned int>(tgt_qubit),
629 static_cast<unsigned int>(ctrl_qubit));
630 else if (GetSimulationType() == SimulationType::kStabilizer)
631 throw std::runtime_error(
632 "QCSimSimulator::ApplyCP: The stabilizer "
633 "simulator does not support the CP gate.");
634 else if (GetSimulationType() == SimulationType::kTensorNetwork)
635 tensorNetwork->AddGate(cpgate, static_cast<unsigned int>(ctrl_qubit),
636 static_cast<unsigned int>(tgt_qubit));
637 else if (GetSimulationType() == SimulationType::kPauliPropagator)
638 pp->ApplyCP(static_cast<unsigned int>(ctrl_qubit),
639 static_cast<unsigned int>(tgt_qubit), lambda);
640 else if (GetSimulationType() == SimulationType::kPathIntegral) {
641 QC::Gates::AppliedGate<> agate(cpgate.getRawOperatorMatrix(),
642 tgt_qubit, ctrl_qubit);
643 pathIntegralSimulator->ApplyGate(agate);
644 }
645 else
646 state->ApplyGate(cpgate, static_cast<unsigned int>(tgt_qubit),
647 static_cast<unsigned int>(ctrl_qubit));
648 NotifyObservers({tgt_qubit, ctrl_qubit});
649 }
650
659 void ApplyCRx(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit,
660 double theta) override {
661 crxgate.SetTheta(theta);
662 if (GetSimulationType() == SimulationType::kMatrixProductState)
663 mpsSimulator->ApplyGate(crxgate, static_cast<unsigned int>(tgt_qubit),
664 static_cast<unsigned int>(ctrl_qubit));
665 else if (GetSimulationType() == SimulationType::kStabilizer)
666 throw std::runtime_error(
667 "QCSimSimulator::ApplyCRx: The stabilizer "
668 "simulator does not support the CRx gate.");
669 else if (GetSimulationType() == SimulationType::kTensorNetwork)
670 tensorNetwork->AddGate(crxgate, static_cast<unsigned int>(ctrl_qubit),
671 static_cast<unsigned int>(tgt_qubit));
672 else if (GetSimulationType() == SimulationType::kPauliPropagator)
673 pp->ApplyCRX(static_cast<unsigned int>(ctrl_qubit),
674 static_cast<unsigned int>(tgt_qubit), theta);
675 else if (GetSimulationType() == SimulationType::kPathIntegral) {
676 QC::Gates::AppliedGate<> agate(crxgate.getRawOperatorMatrix(),
677 tgt_qubit, ctrl_qubit);
678 pathIntegralSimulator->ApplyGate(agate);
679 }
680 else
681 state->ApplyGate(crxgate, static_cast<unsigned int>(tgt_qubit),
682 static_cast<unsigned int>(ctrl_qubit));
683 NotifyObservers({tgt_qubit, ctrl_qubit});
684 }
685
694 void ApplyCRy(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit,
695 double theta) override {
696 crygate.SetTheta(theta);
697 if (GetSimulationType() == SimulationType::kMatrixProductState)
698 mpsSimulator->ApplyGate(crygate, static_cast<unsigned int>(tgt_qubit),
699 static_cast<unsigned int>(ctrl_qubit));
700 else if (GetSimulationType() == SimulationType::kStabilizer)
701 throw std::runtime_error(
702 "QCSimSimulator::ApplyCRy: The stabilizer "
703 "simulator does not support the CRy gate.");
704 else if (GetSimulationType() == SimulationType::kTensorNetwork)
705 tensorNetwork->AddGate(crygate, static_cast<unsigned int>(ctrl_qubit),
706 static_cast<unsigned int>(tgt_qubit));
707 else if (GetSimulationType() == SimulationType::kPauliPropagator)
708 pp->ApplyCRY(static_cast<unsigned int>(ctrl_qubit),
709 static_cast<unsigned int>(tgt_qubit), theta);
710 else if (GetSimulationType() == SimulationType::kPathIntegral) {
711 QC::Gates::AppliedGate<> agate(crygate.getRawOperatorMatrix(),
712 tgt_qubit, ctrl_qubit);
713 pathIntegralSimulator->ApplyGate(agate);
714 }
715 else
716 state->ApplyGate(crygate, static_cast<unsigned int>(tgt_qubit),
717 static_cast<unsigned int>(ctrl_qubit));
718 NotifyObservers({tgt_qubit, ctrl_qubit});
719 }
720
729 void ApplyCRz(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit,
730 double theta) override {
731 crzgate.SetTheta(theta);
732 if (GetSimulationType() == SimulationType::kMatrixProductState)
733 mpsSimulator->ApplyGate(crzgate, static_cast<unsigned int>(tgt_qubit),
734 static_cast<unsigned int>(ctrl_qubit));
735 else if (GetSimulationType() == SimulationType::kStabilizer)
736 throw std::runtime_error(
737 "QCSimSimulator::ApplyCRz: The stabilizer "
738 "simulator does not support the CRz gate.");
739 else if (GetSimulationType() == SimulationType::kTensorNetwork)
740 tensorNetwork->AddGate(crzgate, static_cast<unsigned int>(ctrl_qubit),
741 static_cast<unsigned int>(tgt_qubit));
742 else if (GetSimulationType() == SimulationType::kPauliPropagator)
743 pp->ApplyCRZ(static_cast<unsigned int>(ctrl_qubit),
744 static_cast<unsigned int>(tgt_qubit), theta);
745 else if (GetSimulationType() == SimulationType::kPathIntegral) {
746 QC::Gates::AppliedGate<> agate(crzgate.getRawOperatorMatrix(), tgt_qubit,
747 ctrl_qubit);
748 pathIntegralSimulator->ApplyGate(agate);
749 }
750 else
751 state->ApplyGate(crzgate, static_cast<unsigned int>(tgt_qubit),
752 static_cast<unsigned int>(ctrl_qubit));
753 NotifyObservers({tgt_qubit, ctrl_qubit});
754 }
755
763 void ApplyCH(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit) override {
764 if (GetSimulationType() == SimulationType::kMatrixProductState)
765 mpsSimulator->ApplyGate(ch, static_cast<unsigned int>(tgt_qubit),
766 static_cast<unsigned int>(ctrl_qubit));
767 else if (GetSimulationType() == SimulationType::kStabilizer)
768 throw std::runtime_error(
769 "QCSimSimulator::ApplyCH: The stabilizer "
770 "simulator does not support the CH gate.");
771 else if (GetSimulationType() == SimulationType::kTensorNetwork)
772 tensorNetwork->AddGate(ch, static_cast<unsigned int>(ctrl_qubit),
773 static_cast<unsigned int>(tgt_qubit));
774 else if (GetSimulationType() == SimulationType::kPauliPropagator)
775 pp->ApplyCH(static_cast<unsigned int>(ctrl_qubit),
776 static_cast<unsigned int>(tgt_qubit));
777 else if (GetSimulationType() == SimulationType::kPathIntegral) {
778 QC::Gates::AppliedGate<> agate(ch.getRawOperatorMatrix(), tgt_qubit,
779 ctrl_qubit);
780 pathIntegralSimulator->ApplyGate(agate);
781 }
782 else
783 state->ApplyGate(ch, static_cast<unsigned int>(tgt_qubit),
784 static_cast<unsigned int>(ctrl_qubit));
785 NotifyObservers({tgt_qubit, ctrl_qubit});
786 }
787
795 void ApplyCSx(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit) override {
796 if (GetSimulationType() == SimulationType::kMatrixProductState)
797 mpsSimulator->ApplyGate(csx, static_cast<unsigned int>(tgt_qubit),
798 static_cast<unsigned int>(ctrl_qubit));
799 else if (GetSimulationType() == SimulationType::kStabilizer)
800 throw std::runtime_error(
801 "QCSimSimulator::ApplyCSx: The stabilizer "
802 "simulator does not support the CSx gate.");
803 else if (GetSimulationType() == SimulationType::kTensorNetwork)
804 tensorNetwork->AddGate(csx, static_cast<unsigned int>(ctrl_qubit),
805 static_cast<unsigned int>(tgt_qubit));
806 else if (GetSimulationType() == SimulationType::kPauliPropagator)
807 pp->ApplyCSX(static_cast<unsigned int>(ctrl_qubit),
808 static_cast<unsigned int>(tgt_qubit));
809 else if (GetSimulationType() == SimulationType::kPathIntegral) {
810 QC::Gates::AppliedGate<> agate(csx.getRawOperatorMatrix(), tgt_qubit,
811 ctrl_qubit);
812 pathIntegralSimulator->ApplyGate(agate);
813 }
814 else
815 state->ApplyGate(csx, static_cast<unsigned int>(tgt_qubit),
816 static_cast<unsigned int>(ctrl_qubit));
817 NotifyObservers({tgt_qubit, ctrl_qubit});
818 }
819
827 void ApplyCSxDAG(Types::qubit_t ctrl_qubit,
828 Types::qubit_t tgt_qubit) override {
829 if (GetSimulationType() == SimulationType::kMatrixProductState)
830 mpsSimulator->ApplyGate(csxdag, static_cast<unsigned int>(tgt_qubit),
831 static_cast<unsigned int>(ctrl_qubit));
832 else if (GetSimulationType() == SimulationType::kStabilizer)
833 throw std::runtime_error(
834 "QCSimSimulator::ApplyCSxDAG: The stabilizer "
835 "simulator does not support the CSxDag gate.");
836 else if (GetSimulationType() == SimulationType::kTensorNetwork)
837 tensorNetwork->AddGate(csxdag, static_cast<unsigned int>(ctrl_qubit),
838 static_cast<unsigned int>(tgt_qubit));
839 else if (GetSimulationType() == SimulationType::kPauliPropagator)
840 pp->ApplyCSXDAG(static_cast<unsigned int>(ctrl_qubit),
841 static_cast<unsigned int>(tgt_qubit));
842 else if (GetSimulationType() == SimulationType::kPathIntegral) {
843 QC::Gates::AppliedGate<> agate(csxdag.getRawOperatorMatrix(), tgt_qubit,
844 ctrl_qubit);
845 pathIntegralSimulator->ApplyGate(agate);
846 }
847 else
848 state->ApplyGate(csxdag, static_cast<unsigned int>(tgt_qubit),
849 static_cast<unsigned int>(ctrl_qubit));
850 NotifyObservers({tgt_qubit, ctrl_qubit});
851 }
852
860 void ApplySwap(Types::qubit_t qubit0, Types::qubit_t qubit1) override {
861 if (GetSimulationType() == SimulationType::kMatrixProductState)
862 mpsSimulator->ApplyGate(swapgate, static_cast<unsigned int>(qubit1),
863 static_cast<unsigned int>(qubit0));
864 else if (GetSimulationType() == SimulationType::kStabilizer)
865 cliffordSimulator->ApplySwap(static_cast<unsigned int>(qubit1),
866 static_cast<unsigned int>(qubit0));
867 else if (GetSimulationType() == SimulationType::kTensorNetwork)
868 tensorNetwork->AddGate(swapgate, static_cast<unsigned int>(qubit0),
869 static_cast<unsigned int>(qubit1));
870 else if (GetSimulationType() == SimulationType::kPauliPropagator)
871 pp->ApplySWAP(static_cast<unsigned int>(qubit0),
872 static_cast<unsigned int>(qubit1));
873 else if (GetSimulationType() == SimulationType::kPathIntegral) {
874 QC::Gates::AppliedGate<> agate(swapgate.getRawOperatorMatrix(), qubit1,
875 qubit0);
876 pathIntegralSimulator->ApplyGate(agate);
877 }
878 else
879 state->ApplyGate(swapgate, static_cast<unsigned int>(qubit1),
880 static_cast<unsigned int>(qubit0));
881 NotifyObservers({qubit1, qubit0});
882 }
883
892 void ApplyCCX(Types::qubit_t qubit0, Types::qubit_t qubit1,
893 Types::qubit_t qubit2) override {
894 if (GetSimulationType() == SimulationType::kMatrixProductState) {
895 const size_t q1 = qubit0; // control 1
896 const size_t q2 = qubit1; // control 2
897 const size_t q3 = qubit2; // target
898
899 // Sleator-Weinfurter decomposition
900 mpsSimulator->ApplyGate(csx, static_cast<unsigned int>(q3),
901 static_cast<unsigned int>(q2));
902 NotifyObservers({qubit1, qubit2});
903
904 mpsSimulator->ApplyGate(cxgate, static_cast<unsigned int>(q2),
905 static_cast<unsigned int>(q1));
906 NotifyObservers({qubit0, qubit1});
907
908 mpsSimulator->ApplyGate(csxdag, static_cast<unsigned int>(q3),
909 static_cast<unsigned int>(q2));
910 NotifyObservers({qubit1, qubit2});
911
912 mpsSimulator->ApplyGate(cxgate, static_cast<unsigned int>(q2),
913 static_cast<unsigned int>(q1));
914 NotifyObservers({qubit0, qubit1});
915
916 mpsSimulator->ApplyGate(csx, static_cast<unsigned int>(q3),
917 static_cast<unsigned int>(q1));
918 NotifyObservers({qubit0, qubit2});
919 } else if (GetSimulationType() == SimulationType::kStabilizer)
920 throw std::runtime_error(
921 "QCSimSimulator::ApplyCCX: The stabilizer "
922 "simulator does not support the CCX gate.");
923 else if (GetSimulationType() == SimulationType::kTensorNetwork) {
924 const size_t q1 = qubit0; // control 1
925 const size_t q2 = qubit1; // control 2
926 const size_t q3 = qubit2; // target
927
928 // Sleator-Weinfurter decomposition
929 tensorNetwork->AddGate(csx, static_cast<unsigned int>(q2),
930 static_cast<unsigned int>(q3));
931 NotifyObservers({qubit1, qubit2});
932
933 tensorNetwork->AddGate(cxgate, static_cast<unsigned int>(q1),
934 static_cast<unsigned int>(q2));
935 NotifyObservers({qubit0, qubit1});
936
937 tensorNetwork->AddGate(csxdag, static_cast<unsigned int>(q2),
938 static_cast<unsigned int>(q3));
939 NotifyObservers({qubit1, qubit2});
940
941 tensorNetwork->AddGate(cxgate, static_cast<unsigned int>(q1),
942 static_cast<unsigned int>(q2));
943 NotifyObservers({qubit0, qubit1});
944
945 tensorNetwork->AddGate(csx, static_cast<unsigned int>(q1),
946 static_cast<unsigned int>(q3));
947 NotifyObservers({qubit0, qubit2});
948 } else if (GetSimulationType() == SimulationType::kPauliPropagator) {
949 pp->ApplyCCX(static_cast<unsigned int>(qubit0),
950 static_cast<unsigned int>(qubit1),
951 static_cast<unsigned int>(qubit2));
952 NotifyObservers({qubit2, qubit1, qubit0});
953 } else if (GetSimulationType() == SimulationType::kPathIntegral) {
954 QC::Gates::AppliedGate<> agate(ccxgate.getRawOperatorMatrix(), qubit2,
955 qubit1, qubit0);
956 pathIntegralSimulator->ApplyGate(agate);
957 NotifyObservers({qubit2, qubit1, qubit0});
958 } else {
959 state->ApplyGate(ccxgate, static_cast<unsigned int>(qubit2),
960 static_cast<unsigned int>(qubit1),
961 static_cast<unsigned int>(qubit0));
962 NotifyObservers({qubit2, qubit1, qubit0});
963 }
964 }
965
974 void ApplyCSwap(Types::qubit_t ctrl_qubit, Types::qubit_t qubit0,
975 Types::qubit_t qubit1) override {
976 if (GetSimulationType() == SimulationType::kMatrixProductState) {
977 const size_t q1 = ctrl_qubit; // control
978 const size_t q2 = qubit0;
979 const size_t q3 = qubit1;
980
981 // TODO: find a better decomposition
982 // this one I've got with the qiskit transpiler
983 mpsSimulator->ApplyGate(cxgate, static_cast<unsigned int>(q2),
984 static_cast<unsigned int>(q3));
985 NotifyObservers({qubit1, qubit0});
986
987 mpsSimulator->ApplyGate(csx, static_cast<unsigned int>(q3),
988 static_cast<unsigned int>(q2));
989 NotifyObservers({qubit0, qubit1});
990
991 mpsSimulator->ApplyGate(cxgate, static_cast<unsigned int>(q2),
992 static_cast<unsigned int>(q1));
993 NotifyObservers({ctrl_qubit, qubit0});
994
995 pgate.SetPhaseShift(M_PI);
996 mpsSimulator->ApplyGate(pgate, static_cast<unsigned int>(q3));
997 NotifyObservers({qubit1});
998 pgate.SetPhaseShift(-M_PI_2);
999 mpsSimulator->ApplyGate(pgate, static_cast<unsigned int>(q2));
1000 NotifyObservers({qubit0});
1001
1002 mpsSimulator->ApplyGate(csx, static_cast<unsigned int>(q3),
1003 static_cast<unsigned int>(q2));
1004 NotifyObservers({qubit0, qubit1});
1005
1006 mpsSimulator->ApplyGate(cxgate, static_cast<unsigned int>(q2),
1007 static_cast<unsigned int>(q1));
1008 NotifyObservers({ctrl_qubit, qubit0});
1009
1010 pgate.SetPhaseShift(M_PI);
1011 mpsSimulator->ApplyGate(pgate, static_cast<unsigned int>(q3));
1012 NotifyObservers({qubit1});
1013
1014 mpsSimulator->ApplyGate(csx, static_cast<unsigned int>(q3),
1015 static_cast<unsigned int>(q1));
1016 NotifyObservers({ctrl_qubit, qubit1});
1017
1018 mpsSimulator->ApplyGate(cxgate, static_cast<unsigned int>(q2),
1019 static_cast<unsigned int>(q3));
1020 NotifyObservers({qubit1, qubit0});
1021 } else if (GetSimulationType() == SimulationType::kStabilizer)
1022 throw std::runtime_error(
1023 "QCSimSimulator::ApplyCSwap: The stabilizer "
1024 "simulator does not support the CSwap gate.");
1025 else if (GetSimulationType() == SimulationType::kTensorNetwork) {
1026 const size_t q1 = ctrl_qubit; // control
1027 const size_t q2 = qubit0;
1028 const size_t q3 = qubit1;
1029
1030 // TODO: find a better decomposition
1031 // this one I've got with the qiskit transpiler
1032 tensorNetwork->AddGate(cxgate, static_cast<unsigned int>(q3),
1033 static_cast<unsigned int>(q2));
1034 NotifyObservers({qubit1, qubit0});
1035
1036 tensorNetwork->AddGate(csx, static_cast<unsigned int>(q2),
1037 static_cast<unsigned int>(q3));
1038 NotifyObservers({qubit0, qubit1});
1039
1040 tensorNetwork->AddGate(cxgate, static_cast<unsigned int>(q1),
1041 static_cast<unsigned int>(q2));
1042 NotifyObservers({ctrl_qubit, qubit0});
1043
1044 pgate.SetPhaseShift(M_PI);
1045 tensorNetwork->AddGate(pgate, static_cast<unsigned int>(q3));
1046 NotifyObservers({qubit1});
1047 pgate.SetPhaseShift(-M_PI_2);
1048 tensorNetwork->AddGate(pgate, static_cast<unsigned int>(q2));
1049 NotifyObservers({qubit0});
1050
1051 tensorNetwork->AddGate(csx, static_cast<unsigned int>(q2),
1052 static_cast<unsigned int>(q3));
1053 NotifyObservers({qubit0, qubit1});
1054
1055 tensorNetwork->AddGate(cxgate, static_cast<unsigned int>(q1),
1056 static_cast<unsigned int>(q2));
1057 NotifyObservers({ctrl_qubit, qubit0});
1058
1059 pgate.SetPhaseShift(M_PI);
1060 tensorNetwork->AddGate(pgate, static_cast<unsigned int>(q3));
1061 NotifyObservers({qubit1});
1062
1063 tensorNetwork->AddGate(csx, static_cast<unsigned int>(q1),
1064 static_cast<unsigned int>(q3));
1065 NotifyObservers({ctrl_qubit, qubit1});
1066
1067 tensorNetwork->AddGate(cxgate, static_cast<unsigned int>(q3),
1068 static_cast<unsigned int>(q2));
1069 NotifyObservers({qubit1, qubit0});
1070 } else if (GetSimulationType() == SimulationType::kPauliPropagator) {
1071 pp->ApplyCSwap(static_cast<unsigned int>(ctrl_qubit),
1072 static_cast<unsigned int>(qubit0),
1073 static_cast<unsigned int>(qubit1));
1074 NotifyObservers({qubit1, qubit0, ctrl_qubit});
1075 } else if (GetSimulationType() == SimulationType::kPathIntegral) {
1076 QC::Gates::AppliedGate<> agate(cswapgate.getRawOperatorMatrix(),
1077 qubit1, qubit0, ctrl_qubit);
1078 pathIntegralSimulator->ApplyGate(agate);
1079 NotifyObservers({qubit1, qubit0, ctrl_qubit});
1080 } else {
1081 state->ApplyGate(cswapgate, static_cast<unsigned int>(qubit1),
1082 static_cast<unsigned int>(qubit0),
1083 static_cast<unsigned int>(ctrl_qubit));
1084 NotifyObservers({qubit1, qubit0, ctrl_qubit});
1085 }
1086 }
1087
1099 void ApplyCU(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit,
1100 double theta, double phi, double lambda, double gamma) override {
1101 cugate.SetParams(theta, phi, lambda, gamma);
1102 if (GetSimulationType() == SimulationType::kMatrixProductState)
1103 mpsSimulator->ApplyGate(cugate, static_cast<unsigned int>(tgt_qubit),
1104 static_cast<unsigned int>(ctrl_qubit));
1105 else if (GetSimulationType() == SimulationType::kStabilizer)
1106 throw std::runtime_error(
1107 "QCSimSimulator::ApplyCU: The stabilizer "
1108 "simulator does not support the CU gate.");
1109 else if (GetSimulationType() == SimulationType::kTensorNetwork)
1110 tensorNetwork->AddGate(cugate, static_cast<unsigned int>(ctrl_qubit),
1111 static_cast<unsigned int>(tgt_qubit));
1112 else if (GetSimulationType() == SimulationType::kPauliPropagator)
1113 pp->ApplyCU(static_cast<unsigned int>(ctrl_qubit),
1114 static_cast<unsigned int>(tgt_qubit), theta, phi, lambda,
1115 gamma);
1116 else if (GetSimulationType() == SimulationType::kPathIntegral) {
1117 QC::Gates::AppliedGate<> agate(cugate.getRawOperatorMatrix(), tgt_qubit,
1118 ctrl_qubit);
1119 pathIntegralSimulator->ApplyGate(agate);
1120 }
1121 else
1122 state->ApplyGate(cugate, static_cast<unsigned int>(tgt_qubit),
1123 static_cast<unsigned int>(ctrl_qubit));
1124 NotifyObservers({tgt_qubit, ctrl_qubit});
1125 }
1126
1134 void ApplyNop() override {
1135 // do nothing
1136 }
1137
1148 std::unique_ptr<ISimulator> Clone() override {
1149 auto cloned = std::make_unique<QCSimSimulator>();
1150
1151 cloned->simulationType = simulationType;
1152 cloned->nrQubits = nrQubits;
1153
1154 cloned->limitSize = limitSize;
1155 cloned->limitEntanglement = limitEntanglement;
1156 cloned->chi = chi;
1157 cloned->singularValueThreshold = singularValueThreshold;
1158
1159 cloned->enableMultithreading = enableMultithreading;
1160 cloned->useMPSMeasureNoCollapse = useMPSMeasureNoCollapse;
1161
1162 cloned->lookaheadDepth = lookaheadDepth;
1163 cloned->useOptimalMeetingPosition = useOptimalMeetingPosition;
1164 cloned->upcomingGates = upcomingGates;
1165 cloned->upcomingGateIndex = upcomingGateIndex;
1166 cloned->growthFactorGate = growthFactorGate;
1167 cloned->growthFactorSwap = growthFactorSwap;
1168
1169 if (state) cloned->state = state->Clone();
1170
1171 if (mpsSimulator) {
1172 cloned->mpsSimulator = mpsSimulator->Clone();
1173
1174 if (limitEntanglement && singularValueThreshold > 0.)
1175 cloned->mpsSimulator->setLimitEntanglement(singularValueThreshold);
1176 if (limitSize && chi > 0)
1177 cloned->mpsSimulator->setLimitBondDimension(chi);
1178
1179 cloned->dummySim = dummySim ? dummySim->Clone() : nullptr;
1180
1181 cloned->gateCounterObserver =
1182 std::make_shared<GateCounterObserver>(upcomingGateIndex);
1183 cloned->RegisterObserver(cloned->gateCounterObserver);
1184 }
1185
1186 if (cliffordSimulator)
1187 cloned->cliffordSimulator = cliffordSimulator->Clone();
1188
1189 if (tensorNetwork) cloned->tensorNetwork = tensorNetwork->Clone();
1190
1191 if (pp) cloned->pp = pp->Clone();
1192
1193 if (pathIntegralSimulator)
1194 cloned->pathIntegralSimulator = pathIntegralSimulator->Clone();
1195
1196 return cloned;
1197 }
1198
1199 private:
1200 QC::Gates::PhaseShiftGate<> pgate;
1201 QC::Gates::PauliXGate<> xgate;
1202 QC::Gates::PauliYGate<> ygate;
1203 QC::Gates::PauliZGate<> zgate;
1204 QC::Gates::HadamardGate<> h;
1205 // QC::Gates::UGate<> ugate;
1206 QC::Gates::SGate<> sgate;
1207 QC::Gates::SDGGate<> sdggate;
1208 QC::Gates::TGate<> tgate;
1209 QC::Gates::TDGGate<> tdggate;
1210 QC::Gates::SquareRootNOTGate<> sxgate;
1211 QC::Gates::SquareRootNOTDagGate<> sxdaggate;
1212 QC::Gates::HyGate<> k;
1213 QC::Gates::RxGate<> rxgate;
1214 QC::Gates::RyGate<> rygate;
1215 QC::Gates::RzGate<> rzgate;
1216 QC::Gates::UGate<> ugate;
1217 QC::Gates::CNOTGate<> cxgate;
1218 QC::Gates::ControlledYGate<> cygate;
1219 QC::Gates::ControlledZGate<> czgate;
1220 QC::Gates::ControlledPhaseShiftGate<> cpgate;
1221 QC::Gates::ControlledRxGate<> crxgate;
1222 QC::Gates::ControlledRyGate<> crygate;
1223 QC::Gates::ControlledRzGate<> crzgate;
1224 QC::Gates::ControlledHadamardGate<> ch;
1225 QC::Gates::ControlledSquareRootNOTGate<> csx;
1226 QC::Gates::ControlledSquareRootNOTDagGate<> csxdag;
1227 QC::Gates::SwapGate<> swapgate;
1228 QC::Gates::ToffoliGate<> ccxgate;
1229 QC::Gates::FredkinGate<> cswapgate;
1230 QC::Gates::ControlledUGate<> cugate;
1231};
1232
1233} // namespace Private
1234} // namespace Simulators
1235
1236#endif
1237
1238#endif // !_QCSIMSIMULATOR_H
int ApplyK(void *sim, int qubit)
int ApplyRx(void *sim, int qubit, double theta)
int ApplyX(void *sim, int qubit)
int ApplyU(void *sim, int qubit, double theta, double phi, double lambda, double gamma)
int ApplyCRy(void *sim, int controlQubit, int targetQubit, double theta)
int ApplyTDG(void *sim, int qubit)
int ApplyS(void *sim, int qubit)
int ApplyCX(void *sim, int controlQubit, int targetQubit)
int ApplyCRz(void *sim, int controlQubit, int targetQubit, double theta)
int ApplyCP(void *sim, int controlQubit, int targetQubit, double theta)
int ApplySDG(void *sim, int qubit)
int ApplyCSwap(void *sim, int controlQubit, int qubit1, int qubit2)
int ApplyCCX(void *sim, int controlQubit1, int controlQubit2, int targetQubit)
int ApplyY(void *sim, int qubit)
int ApplyZ(void *sim, int qubit)
int ApplyH(void *sim, int qubit)
int ApplyCY(void *sim, int controlQubit, int targetQubit)
int ApplyCU(void *sim, int controlQubit, int targetQubit, double theta, double phi, double lambda, double gamma)
int ApplySwap(void *sim, int qubit1, int qubit2)
int ApplyRy(void *sim, int qubit, double theta)
int ApplyP(void *sim, int qubit, double theta)
int ApplyCH(void *sim, int controlQubit, int targetQubit)
int GetSimulationType(void *sim)
int ApplyCZ(void *sim, int controlQubit, int targetQubit)
int ApplyRz(void *sim, int qubit, double theta)
int ApplyT(void *sim, int qubit)
int ApplyCRx(void *sim, int controlQubit, int targetQubit, double theta)
uint_fast64_t qubit_t
The type of a qubit.
Definition Types.h:21