Maestro 0.1.0
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
47public:
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
64 void ApplyP(Types::qubit_t qubit, double lambda) override {
65 pgate.SetPhaseShift(lambda);
66 if (GetSimulationType() == SimulationType::kMatrixProductState)
67 mpsSimulator->ApplyGate(pgate, static_cast<unsigned int>(qubit));
68 else if (GetSimulationType() == SimulationType::kStabilizer) {
69 if (std::abs(lambda - M_PI_2) > 1e-10)
70 throw std::runtime_error("QCSimSimulator::ApplyP: Invalid phase shift "
71 "angle for a Clifford gate.");
72 cliffordSimulator->ApplyS(static_cast<unsigned int>(qubit));
73 } else if (GetSimulationType() == SimulationType::kTensorNetwork)
74 tensorNetwork->AddGate(pgate, static_cast<unsigned int>(qubit));
75 else
76 state->ApplyGate(pgate, static_cast<unsigned int>(qubit));
77 NotifyObservers({qubit});
78 }
79
86 void ApplyX(Types::qubit_t qubit) override {
87 if (GetSimulationType() == SimulationType::kMatrixProductState)
88 mpsSimulator->ApplyGate(xgate, static_cast<unsigned int>(qubit));
89 else if (GetSimulationType() == SimulationType::kStabilizer)
90 cliffordSimulator->ApplyX(static_cast<unsigned int>(qubit));
91 else if (GetSimulationType() == SimulationType::kTensorNetwork)
92 tensorNetwork->AddGate(xgate, static_cast<unsigned int>(qubit));
93 else
94 state->ApplyGate(xgate, static_cast<unsigned int>(qubit));
95 NotifyObservers({qubit});
96 }
97
104 void ApplyY(Types::qubit_t qubit) override {
105 if (GetSimulationType() == SimulationType::kMatrixProductState)
106 mpsSimulator->ApplyGate(ygate, static_cast<unsigned int>(qubit));
107 else if (GetSimulationType() == SimulationType::kStabilizer)
108 cliffordSimulator->ApplyY(static_cast<unsigned int>(qubit));
109 else if (GetSimulationType() == SimulationType::kTensorNetwork)
110 tensorNetwork->AddGate(ygate, static_cast<unsigned int>(qubit));
111 else
112 state->ApplyGate(ygate, static_cast<unsigned int>(qubit));
113 NotifyObservers({qubit});
114 }
115
122 void ApplyZ(Types::qubit_t qubit) override {
123 if (GetSimulationType() == SimulationType::kMatrixProductState)
124 mpsSimulator->ApplyGate(zgate, static_cast<unsigned int>(qubit));
125 else if (GetSimulationType() == SimulationType::kStabilizer)
126 cliffordSimulator->ApplyZ(static_cast<unsigned int>(qubit));
127 else if (GetSimulationType() == SimulationType::kTensorNetwork)
128 tensorNetwork->AddGate(zgate, static_cast<unsigned int>(qubit));
129 else
130 state->ApplyGate(zgate, static_cast<unsigned int>(qubit));
131 NotifyObservers({qubit});
132 }
133
140 void ApplyH(Types::qubit_t qubit) override {
141 if (GetSimulationType() == SimulationType::kMatrixProductState)
142 mpsSimulator->ApplyGate(h, static_cast<unsigned int>(qubit));
143 else if (GetSimulationType() == SimulationType::kStabilizer)
144 cliffordSimulator->ApplyH(static_cast<unsigned int>(qubit));
145 else if (GetSimulationType() == SimulationType::kTensorNetwork)
146 tensorNetwork->AddGate(h, static_cast<unsigned int>(qubit));
147 else
148 state->ApplyGate(h, static_cast<unsigned int>(qubit));
149 NotifyObservers({qubit});
150 }
151
158 void ApplyS(Types::qubit_t qubit) override {
159 if (GetSimulationType() == SimulationType::kMatrixProductState)
160 mpsSimulator->ApplyGate(sgate, static_cast<unsigned int>(qubit));
161 else if (GetSimulationType() == SimulationType::kStabilizer)
162 cliffordSimulator->ApplyS(static_cast<unsigned int>(qubit));
163 else if (GetSimulationType() == SimulationType::kTensorNetwork)
164 tensorNetwork->AddGate(sgate, static_cast<unsigned int>(qubit));
165 else
166 state->ApplyGate(sgate, static_cast<unsigned int>(qubit));
167 NotifyObservers({qubit});
168 }
169
176 void ApplySDG(Types::qubit_t qubit) override {
177 if (GetSimulationType() == SimulationType::kMatrixProductState)
178 mpsSimulator->ApplyGate(sdggate, static_cast<unsigned int>(qubit));
179 else if (GetSimulationType() == SimulationType::kStabilizer)
180 cliffordSimulator->ApplySdg(static_cast<unsigned int>(qubit));
181 else if (GetSimulationType() == SimulationType::kTensorNetwork)
182 tensorNetwork->AddGate(sdggate, static_cast<unsigned int>(qubit));
183 else
184 state->ApplyGate(sdggate, static_cast<unsigned int>(qubit));
185 NotifyObservers({qubit});
186 }
187
194 void ApplyT(Types::qubit_t qubit) override {
195 if (GetSimulationType() == SimulationType::kMatrixProductState)
196 mpsSimulator->ApplyGate(tgate, static_cast<unsigned int>(qubit));
197 else if (GetSimulationType() == SimulationType::kStabilizer)
198 throw std::runtime_error(
199 "QCSimSimulator::ApplyT: The stabilizer simulator does not support "
200 "non-clifford gates.");
201 else if (GetSimulationType() == SimulationType::kTensorNetwork)
202 tensorNetwork->AddGate(tgate, static_cast<unsigned int>(qubit));
203 else
204 state->ApplyGate(tgate, static_cast<unsigned int>(qubit));
205 NotifyObservers({qubit});
206 }
207
214 void ApplyTDG(Types::qubit_t qubit) override {
215 if (GetSimulationType() == SimulationType::kMatrixProductState)
216 mpsSimulator->ApplyGate(tdggate, static_cast<unsigned int>(qubit));
217 else if (GetSimulationType() == SimulationType::kStabilizer)
218 throw std::runtime_error(
219 "QCSimSimulator::ApplyTDG: The stabilizer simulator does not support "
220 "non-clifford gates.");
221 else if (GetSimulationType() == SimulationType::kTensorNetwork)
222 tensorNetwork->AddGate(tdggate, static_cast<unsigned int>(qubit));
223 else
224 state->ApplyGate(tdggate, static_cast<unsigned int>(qubit));
225 NotifyObservers({qubit});
226 }
227
234 void ApplySx(Types::qubit_t qubit) override {
235 if (GetSimulationType() == SimulationType::kMatrixProductState)
236 mpsSimulator->ApplyGate(sxgate, static_cast<unsigned int>(qubit));
237 else if (GetSimulationType() == SimulationType::kStabilizer)
238 cliffordSimulator->ApplySx(static_cast<unsigned int>(qubit));
239 else if (GetSimulationType() == SimulationType::kTensorNetwork)
240 tensorNetwork->AddGate(sxgate, static_cast<unsigned int>(qubit));
241 else
242 state->ApplyGate(sxgate, static_cast<unsigned int>(qubit));
243 NotifyObservers({qubit});
244 }
245
252 void ApplySxDAG(Types::qubit_t qubit) override {
253 if (GetSimulationType() == SimulationType::kMatrixProductState)
254 mpsSimulator->ApplyGate(sxdaggate, static_cast<unsigned int>(qubit));
255 else if (GetSimulationType() == SimulationType::kStabilizer)
256 cliffordSimulator->ApplySxDag(static_cast<unsigned int>(qubit));
257 else if (GetSimulationType() == SimulationType::kTensorNetwork)
258 tensorNetwork->AddGate(sxdaggate, static_cast<unsigned int>(qubit));
259 else
260 state->ApplyGate(sxdaggate, static_cast<unsigned int>(qubit));
261 NotifyObservers({qubit});
262 }
263
270 void ApplyK(Types::qubit_t qubit) override {
271 if (GetSimulationType() == SimulationType::kMatrixProductState)
272 mpsSimulator->ApplyGate(k, static_cast<unsigned int>(qubit));
273 else if (GetSimulationType() == SimulationType::kStabilizer)
274 cliffordSimulator->ApplyK(static_cast<unsigned int>(qubit));
275 else if (GetSimulationType() == SimulationType::kTensorNetwork)
276 tensorNetwork->AddGate(k, static_cast<unsigned int>(qubit));
277 else
278 state->ApplyGate(k, static_cast<unsigned int>(qubit));
279 NotifyObservers({qubit});
280 }
281
289 void ApplyRx(Types::qubit_t qubit, double theta) override {
290 rxgate.SetTheta(theta);
291 if (GetSimulationType() == SimulationType::kMatrixProductState)
292 mpsSimulator->ApplyGate(rxgate, static_cast<unsigned int>(qubit));
293 else if (GetSimulationType() == SimulationType::kStabilizer)
294 throw std::runtime_error("QCSimSimulator::ApplyRx: The stabilizer "
295 "simulator does not support the Rx gate.");
296 else if (GetSimulationType() == SimulationType::kTensorNetwork)
297 tensorNetwork->AddGate(rxgate, static_cast<unsigned int>(qubit));
298 else
299 state->ApplyGate(rxgate, static_cast<unsigned int>(qubit));
300 NotifyObservers({qubit});
301 }
302
310 void ApplyRy(Types::qubit_t qubit, double theta) override {
311 rygate.SetTheta(theta);
312 if (GetSimulationType() == SimulationType::kMatrixProductState)
313 mpsSimulator->ApplyGate(rygate, static_cast<unsigned int>(qubit));
314 else if (GetSimulationType() == SimulationType::kStabilizer)
315 throw std::runtime_error("QCSimSimulator::ApplyRy: The stabilizer "
316 "simulator does not support the Ry gate.");
317 else if (GetSimulationType() == SimulationType::kTensorNetwork)
318 tensorNetwork->AddGate(rygate, static_cast<unsigned int>(qubit));
319 else
320 state->ApplyGate(rygate, static_cast<unsigned int>(qubit));
321 NotifyObservers({qubit});
322 }
323
331 void ApplyRz(Types::qubit_t qubit, double theta) override {
332 rzgate.SetTheta(theta);
333 if (GetSimulationType() == SimulationType::kMatrixProductState)
334 mpsSimulator->ApplyGate(rzgate, static_cast<unsigned int>(qubit));
335 else if (GetSimulationType() == SimulationType::kStabilizer)
336 throw std::runtime_error("QCSimSimulator::ApplyRz: The stabilizer "
337 "simulator does not support the Rz gate.");
338 else if (GetSimulationType() == SimulationType::kTensorNetwork)
339 tensorNetwork->AddGate(rzgate, static_cast<unsigned int>(qubit));
340 else
341 state->ApplyGate(rzgate, static_cast<unsigned int>(qubit));
342 NotifyObservers({qubit});
343 }
344
355 void ApplyU(Types::qubit_t qubit, double theta, double phi, double lambda,
356 double gamma) override {
357 ugate.SetParams(theta, phi, lambda, gamma);
358 if (GetSimulationType() == SimulationType::kMatrixProductState)
359 mpsSimulator->ApplyGate(ugate, static_cast<unsigned int>(qubit));
360 else if (GetSimulationType() == SimulationType::kStabilizer)
361 throw std::runtime_error("QCSimSimulator::ApplyU: The stabilizer "
362 "simulator does not support the U gate.");
363 else if (GetSimulationType() == SimulationType::kTensorNetwork)
364 tensorNetwork->AddGate(ugate, static_cast<unsigned int>(qubit));
365 else
366 state->ApplyGate(ugate, static_cast<unsigned int>(qubit));
367 NotifyObservers({qubit});
368 }
369
377 void ApplyCX(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit) override {
378 if (GetSimulationType() == SimulationType::kMatrixProductState)
379 mpsSimulator->ApplyGate(cxgate, static_cast<unsigned int>(tgt_qubit),
380 static_cast<unsigned int>(ctrl_qubit));
381 else if (GetSimulationType() == SimulationType::kStabilizer)
382 cliffordSimulator->ApplyCX(static_cast<unsigned int>(tgt_qubit),
383 static_cast<unsigned int>(ctrl_qubit));
384 else if (GetSimulationType() == SimulationType::kTensorNetwork)
385 tensorNetwork->AddGate(cxgate, static_cast<unsigned int>(ctrl_qubit),
386 static_cast<unsigned int>(tgt_qubit));
387 else
388 state->ApplyGate(cxgate, static_cast<unsigned int>(tgt_qubit),
389 static_cast<unsigned int>(ctrl_qubit));
390 NotifyObservers({tgt_qubit, ctrl_qubit});
391 }
392
400 void ApplyCY(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit) override {
401 if (GetSimulationType() == SimulationType::kMatrixProductState)
402 mpsSimulator->ApplyGate(cygate, static_cast<unsigned int>(tgt_qubit),
403 static_cast<unsigned int>(ctrl_qubit));
404 else if (GetSimulationType() == SimulationType::kStabilizer)
405 cliffordSimulator->ApplyCY(static_cast<unsigned int>(tgt_qubit),
406 static_cast<unsigned int>(ctrl_qubit));
407 else if (GetSimulationType() == SimulationType::kTensorNetwork)
408 tensorNetwork->AddGate(cygate, static_cast<unsigned int>(ctrl_qubit),
409 static_cast<unsigned int>(tgt_qubit));
410 else
411 state->ApplyGate(cygate, static_cast<unsigned int>(tgt_qubit),
412 static_cast<unsigned int>(ctrl_qubit));
413 NotifyObservers({tgt_qubit, ctrl_qubit});
414 }
415
423 void ApplyCZ(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit) override {
424 if (GetSimulationType() == SimulationType::kMatrixProductState)
425 mpsSimulator->ApplyGate(czgate, static_cast<unsigned int>(tgt_qubit),
426 static_cast<unsigned int>(ctrl_qubit));
427 else if (GetSimulationType() == SimulationType::kStabilizer)
428 cliffordSimulator->ApplyCZ(static_cast<unsigned int>(tgt_qubit),
429 static_cast<unsigned int>(ctrl_qubit));
430 else if (GetSimulationType() == SimulationType::kTensorNetwork)
431 tensorNetwork->AddGate(czgate, static_cast<unsigned int>(ctrl_qubit),
432 static_cast<unsigned int>(tgt_qubit));
433 else
434 state->ApplyGate(czgate, static_cast<unsigned int>(tgt_qubit),
435 static_cast<unsigned int>(ctrl_qubit));
436 NotifyObservers({tgt_qubit, ctrl_qubit});
437 }
438
447 void ApplyCP(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit,
448 double lambda) override {
449 cpgate.SetPhaseShift(lambda);
450 if (GetSimulationType() == SimulationType::kMatrixProductState)
451 mpsSimulator->ApplyGate(cpgate, static_cast<unsigned int>(tgt_qubit),
452 static_cast<unsigned int>(ctrl_qubit));
453 else if (GetSimulationType() == SimulationType::kStabilizer)
454 throw std::runtime_error("QCSimSimulator::ApplyCP: The stabilizer "
455 "simulator does not support the CP gate.");
456 else if (GetSimulationType() == SimulationType::kTensorNetwork)
457 tensorNetwork->AddGate(cpgate, static_cast<unsigned int>(ctrl_qubit),
458 static_cast<unsigned int>(tgt_qubit));
459 else
460 state->ApplyGate(cpgate, static_cast<unsigned int>(tgt_qubit),
461 static_cast<unsigned int>(ctrl_qubit));
462 NotifyObservers({tgt_qubit, ctrl_qubit});
463 }
464
473 void ApplyCRx(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit,
474 double theta) override {
475 crxgate.SetTheta(theta);
476 if (GetSimulationType() == SimulationType::kMatrixProductState)
477 mpsSimulator->ApplyGate(crxgate, static_cast<unsigned int>(tgt_qubit),
478 static_cast<unsigned int>(ctrl_qubit));
479 else if (GetSimulationType() == SimulationType::kStabilizer)
480 throw std::runtime_error("QCSimSimulator::ApplyCRx: The stabilizer "
481 "simulator does not support the CRx gate.");
482 else if (GetSimulationType() == SimulationType::kTensorNetwork)
483 tensorNetwork->AddGate(crxgate, static_cast<unsigned int>(ctrl_qubit),
484 static_cast<unsigned int>(tgt_qubit));
485 else
486 state->ApplyGate(crxgate, static_cast<unsigned int>(tgt_qubit),
487 static_cast<unsigned int>(ctrl_qubit));
488 NotifyObservers({tgt_qubit, ctrl_qubit});
489 }
490
499 void ApplyCRy(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit,
500 double theta) override {
501 crygate.SetTheta(theta);
502 if (GetSimulationType() == SimulationType::kMatrixProductState)
503 mpsSimulator->ApplyGate(crygate, static_cast<unsigned int>(tgt_qubit),
504 static_cast<unsigned int>(ctrl_qubit));
505 else if (GetSimulationType() == SimulationType::kStabilizer)
506 throw std::runtime_error("QCSimSimulator::ApplyCRy: The stabilizer "
507 "simulator does not support the CRy gate.");
508 else if (GetSimulationType() == SimulationType::kTensorNetwork)
509 tensorNetwork->AddGate(crygate, static_cast<unsigned int>(ctrl_qubit),
510 static_cast<unsigned int>(tgt_qubit));
511 else
512 state->ApplyGate(crygate, static_cast<unsigned int>(tgt_qubit),
513 static_cast<unsigned int>(ctrl_qubit));
514 NotifyObservers({tgt_qubit, ctrl_qubit});
515 }
516
525 void ApplyCRz(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit,
526 double theta) override {
527 crzgate.SetTheta(theta);
528 if (GetSimulationType() == SimulationType::kMatrixProductState)
529 mpsSimulator->ApplyGate(crzgate, static_cast<unsigned int>(tgt_qubit),
530 static_cast<unsigned int>(ctrl_qubit));
531 else if (GetSimulationType() == SimulationType::kStabilizer)
532 throw std::runtime_error("QCSimSimulator::ApplyCRz: The stabilizer "
533 "simulator does not support the CRz gate.");
534 else if (GetSimulationType() == SimulationType::kTensorNetwork)
535 tensorNetwork->AddGate(crzgate, static_cast<unsigned int>(ctrl_qubit),
536 static_cast<unsigned int>(tgt_qubit));
537 else
538 state->ApplyGate(crzgate, static_cast<unsigned int>(tgt_qubit),
539 static_cast<unsigned int>(ctrl_qubit));
540 NotifyObservers({tgt_qubit, ctrl_qubit});
541 }
542
550 void ApplyCH(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit) override {
551 if (GetSimulationType() == SimulationType::kMatrixProductState)
552 mpsSimulator->ApplyGate(ch, static_cast<unsigned int>(tgt_qubit),
553 static_cast<unsigned int>(ctrl_qubit));
554 else if (GetSimulationType() == SimulationType::kStabilizer)
555 throw std::runtime_error("QCSimSimulator::ApplyCH: The stabilizer "
556 "simulator does not support the CH gate.");
557 else if (GetSimulationType() == SimulationType::kTensorNetwork)
558 tensorNetwork->AddGate(ch, static_cast<unsigned int>(ctrl_qubit),
559 static_cast<unsigned int>(tgt_qubit));
560 else
561 state->ApplyGate(ch, static_cast<unsigned int>(tgt_qubit),
562 static_cast<unsigned int>(ctrl_qubit));
563 NotifyObservers({tgt_qubit, ctrl_qubit});
564 }
565
573 void ApplyCSx(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit) override {
574 if (GetSimulationType() == SimulationType::kMatrixProductState)
575 mpsSimulator->ApplyGate(csx, static_cast<unsigned int>(tgt_qubit),
576 static_cast<unsigned int>(ctrl_qubit));
577 else if (GetSimulationType() == SimulationType::kStabilizer)
578 throw std::runtime_error("QCSimSimulator::ApplyCSx: The stabilizer "
579 "simulator does not support the CSx gate.");
580 else if (GetSimulationType() == SimulationType::kTensorNetwork)
581 tensorNetwork->AddGate(csx, static_cast<unsigned int>(ctrl_qubit),
582 static_cast<unsigned int>(tgt_qubit));
583 else
584 state->ApplyGate(csx, static_cast<unsigned int>(tgt_qubit),
585 static_cast<unsigned int>(ctrl_qubit));
586 NotifyObservers({tgt_qubit, ctrl_qubit});
587 }
588
596 void ApplyCSxDAG(Types::qubit_t ctrl_qubit,
597 Types::qubit_t tgt_qubit) override {
598 if (GetSimulationType() == SimulationType::kMatrixProductState)
599 mpsSimulator->ApplyGate(csxdag, static_cast<unsigned int>(tgt_qubit),
600 static_cast<unsigned int>(ctrl_qubit));
601 else if (GetSimulationType() == SimulationType::kStabilizer)
602 throw std::runtime_error("QCSimSimulator::ApplyCSxDAG: The stabilizer "
603 "simulator does not support the CSxDag gate.");
604 else if (GetSimulationType() == SimulationType::kTensorNetwork)
605 tensorNetwork->AddGate(csxdag, static_cast<unsigned int>(ctrl_qubit),
606 static_cast<unsigned int>(tgt_qubit));
607 else
608 state->ApplyGate(csxdag, static_cast<unsigned int>(tgt_qubit),
609 static_cast<unsigned int>(ctrl_qubit));
610 NotifyObservers({tgt_qubit, ctrl_qubit});
611 }
612
620 void ApplySwap(Types::qubit_t qubit0, Types::qubit_t qubit1) override {
621 if (GetSimulationType() == SimulationType::kMatrixProductState)
622 mpsSimulator->ApplyGate(swapgate, static_cast<unsigned int>(qubit1),
623 static_cast<unsigned int>(qubit0));
624 else if (GetSimulationType() == SimulationType::kStabilizer)
625 cliffordSimulator->ApplySwap(static_cast<unsigned int>(qubit1),
626 static_cast<unsigned int>(qubit0));
627 else if (GetSimulationType() == SimulationType::kTensorNetwork)
628 tensorNetwork->AddGate(swapgate, static_cast<unsigned int>(qubit0),
629 static_cast<unsigned int>(qubit1));
630 else
631 state->ApplyGate(swapgate, static_cast<unsigned int>(qubit1),
632 static_cast<unsigned int>(qubit0));
633 NotifyObservers({qubit1, qubit0});
634 }
635
644 void ApplyCCX(Types::qubit_t qubit0, Types::qubit_t qubit1,
645 Types::qubit_t qubit2) override {
646 if (GetSimulationType() == SimulationType::kMatrixProductState) {
647 const size_t q1 = qubit0; // control 1
648 const size_t q2 = qubit1; // control 2
649 const size_t q3 = qubit2; // target
650
651 // Sleator-Weinfurter decomposition
652 mpsSimulator->ApplyGate(csx, static_cast<unsigned int>(q3),
653 static_cast<unsigned int>(q2));
654 mpsSimulator->ApplyGate(cxgate, static_cast<unsigned int>(q2),
655 static_cast<unsigned int>(q1));
656 mpsSimulator->ApplyGate(csxdag, static_cast<unsigned int>(q3),
657 static_cast<unsigned int>(q2));
658 mpsSimulator->ApplyGate(cxgate, static_cast<unsigned int>(q2),
659 static_cast<unsigned int>(q1));
660 mpsSimulator->ApplyGate(csx, static_cast<unsigned int>(q3),
661 static_cast<unsigned int>(q1));
662 } else if (GetSimulationType() == SimulationType::kStabilizer)
663 throw std::runtime_error("QCSimSimulator::ApplyCCX: The stabilizer "
664 "simulator does not support the CCX gate.");
665 else if (GetSimulationType() == SimulationType::kTensorNetwork) {
666 const size_t q1 = qubit0; // control 1
667 const size_t q2 = qubit1; // control 2
668 const size_t q3 = qubit2; // target
669
670 // Sleator-Weinfurter decomposition
671 tensorNetwork->AddGate(csx, static_cast<unsigned int>(q2),
672 static_cast<unsigned int>(q3));
673 tensorNetwork->AddGate(cxgate, static_cast<unsigned int>(q1),
674 static_cast<unsigned int>(q2));
675 tensorNetwork->AddGate(csxdag, static_cast<unsigned int>(q2),
676 static_cast<unsigned int>(q3));
677 tensorNetwork->AddGate(cxgate, static_cast<unsigned int>(q1),
678 static_cast<unsigned int>(q2));
679 tensorNetwork->AddGate(csx, static_cast<unsigned int>(q1),
680 static_cast<unsigned int>(q3));
681 } else
682 state->ApplyGate(ccxgate, static_cast<unsigned int>(qubit2),
683 static_cast<unsigned int>(qubit1),
684 static_cast<unsigned int>(qubit0));
685 NotifyObservers({qubit2, qubit1, qubit0});
686 }
687
696 void ApplyCSwap(Types::qubit_t ctrl_qubit, Types::qubit_t qubit0,
697 Types::qubit_t qubit1) override {
698 if (GetSimulationType() == SimulationType::kMatrixProductState) {
699 const size_t q1 = ctrl_qubit; // control
700 const size_t q2 = qubit0;
701 const size_t q3 = qubit1;
702
703 // TODO: find a better decomposition
704 // this one I've got with the qiskit transpiler
705 mpsSimulator->ApplyGate(cxgate, static_cast<unsigned int>(q2),
706 static_cast<unsigned int>(q3));
707 mpsSimulator->ApplyGate(csx, static_cast<unsigned int>(q3),
708 static_cast<unsigned int>(q2));
709 mpsSimulator->ApplyGate(cxgate, static_cast<unsigned int>(q2),
710 static_cast<unsigned int>(q1));
711
712 pgate.SetPhaseShift(M_PI);
713 mpsSimulator->ApplyGate(pgate, static_cast<unsigned int>(q3));
714 pgate.SetPhaseShift(-M_PI_2);
715 mpsSimulator->ApplyGate(pgate, static_cast<unsigned int>(q2));
716
717 mpsSimulator->ApplyGate(csx, static_cast<unsigned int>(q3),
718 static_cast<unsigned int>(q2));
719 mpsSimulator->ApplyGate(cxgate, static_cast<unsigned int>(q2),
720 static_cast<unsigned int>(q1));
721
722 pgate.SetPhaseShift(M_PI);
723 mpsSimulator->ApplyGate(pgate, static_cast<unsigned int>(q3));
724
725 mpsSimulator->ApplyGate(csx, static_cast<unsigned int>(q3),
726 static_cast<unsigned int>(q1));
727 mpsSimulator->ApplyGate(cxgate, static_cast<unsigned int>(q2),
728 static_cast<unsigned int>(q3));
729 } else if (GetSimulationType() == SimulationType::kStabilizer)
730 throw std::runtime_error("QCSimSimulator::ApplyCSwap: The stabilizer "
731 "simulator does not support the CSwap gate.");
732 else if (GetSimulationType() == SimulationType::kTensorNetwork) {
733 const size_t q1 = ctrl_qubit; // control
734 const size_t q2 = qubit0;
735 const size_t q3 = qubit1;
736
737 // TODO: find a better decomposition
738 // this one I've got with the qiskit transpiler
739 tensorNetwork->AddGate(cxgate, static_cast<unsigned int>(q3),
740 static_cast<unsigned int>(q2));
741 tensorNetwork->AddGate(csx, static_cast<unsigned int>(q2),
742 static_cast<unsigned int>(q3));
743 tensorNetwork->AddGate(cxgate, static_cast<unsigned int>(q1),
744 static_cast<unsigned int>(q2));
745
746 pgate.SetPhaseShift(M_PI);
747 tensorNetwork->AddGate(pgate, static_cast<unsigned int>(q3));
748 pgate.SetPhaseShift(-M_PI_2);
749 tensorNetwork->AddGate(pgate, static_cast<unsigned int>(q2));
750
751 tensorNetwork->AddGate(csx, static_cast<unsigned int>(q2),
752 static_cast<unsigned int>(q3));
753 tensorNetwork->AddGate(cxgate, static_cast<unsigned int>(q1),
754 static_cast<unsigned int>(q2));
755
756 pgate.SetPhaseShift(M_PI);
757 tensorNetwork->AddGate(pgate, static_cast<unsigned int>(q3));
758
759 tensorNetwork->AddGate(csx, static_cast<unsigned int>(q1),
760 static_cast<unsigned int>(q3));
761 tensorNetwork->AddGate(cxgate, static_cast<unsigned int>(q3),
762 static_cast<unsigned int>(q2));
763 } else
764 state->ApplyGate(cswapgate, static_cast<unsigned int>(qubit1),
765 static_cast<unsigned int>(qubit0),
766 static_cast<unsigned int>(ctrl_qubit));
767 NotifyObservers({qubit1, qubit0, ctrl_qubit});
768 }
769
781 void ApplyCU(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit,
782 double theta, double phi, double lambda, double gamma) override {
783 cugate.SetParams(theta, phi, lambda, gamma);
784 if (GetSimulationType() == SimulationType::kMatrixProductState)
785 mpsSimulator->ApplyGate(cugate, static_cast<unsigned int>(tgt_qubit),
786 static_cast<unsigned int>(ctrl_qubit));
787 else if (GetSimulationType() == SimulationType::kStabilizer)
788 throw std::runtime_error("QCSimSimulator::ApplyCU: The stabilizer "
789 "simulator does not support the CU gate.");
790 else if (GetSimulationType() == SimulationType::kTensorNetwork)
791 tensorNetwork->AddGate(cugate, static_cast<unsigned int>(ctrl_qubit),
792 static_cast<unsigned int>(tgt_qubit));
793 else
794 state->ApplyGate(cugate, static_cast<unsigned int>(tgt_qubit),
795 static_cast<unsigned int>(ctrl_qubit));
796 NotifyObservers({tgt_qubit, ctrl_qubit});
797 }
798
806 void ApplyNop() override {
807 // do nothing
808 }
809
820 std::unique_ptr<ISimulator> Clone() override {
821 auto cloned = std::make_unique<QCSimSimulator>();
822
823 cloned->simulationType = simulationType;
824 cloned->nrQubits = nrQubits;
825
826 cloned->limitSize = limitSize;
827 cloned->limitEntanglement = limitEntanglement;
828 cloned->chi = chi;
829 cloned->singularValueThreshold = singularValueThreshold;
830
831 cloned->enableMultithreading = enableMultithreading;
832 cloned->useMPSMeasureNoCollapse = useMPSMeasureNoCollapse;
833
834 if (state)
835 cloned->state = state->Clone();
836
837 if (mpsSimulator) {
838 cloned->mpsSimulator = mpsSimulator->Clone();
839
840 if (limitEntanglement && singularValueThreshold > 0.)
841 cloned->mpsSimulator->setLimitEntanglement(singularValueThreshold);
842 if (limitSize && chi > 0)
843 cloned->mpsSimulator->setLimitBondDimension(chi);
844 }
845
846 if (cliffordSimulator)
847 cloned->cliffordSimulator = cliffordSimulator->Clone();
848
849 if (tensorNetwork)
850 cloned->tensorNetwork = tensorNetwork->Clone();
851
852 return cloned;
853 }
854
855private:
856 QC::Gates::PhaseShiftGate<> pgate;
857 QC::Gates::PauliXGate<> xgate;
858 QC::Gates::PauliYGate<> ygate;
859 QC::Gates::PauliZGate<> zgate;
860 QC::Gates::HadamardGate<> h;
861 // QC::Gates::UGate<> ugate;
862 QC::Gates::SGate<> sgate;
863 QC::Gates::SDGGate<> sdggate;
864 QC::Gates::TGate<> tgate;
865 QC::Gates::TDGGate<> tdggate;
866 QC::Gates::SquareRootNOTGate<> sxgate;
867 QC::Gates::SquareRootNOTDagGate<> sxdaggate;
868 QC::Gates::HyGate<> k;
869 QC::Gates::RxGate<> rxgate;
870 QC::Gates::RyGate<> rygate;
871 QC::Gates::RzGate<> rzgate;
872 QC::Gates::UGate<> ugate;
873 QC::Gates::CNOTGate<> cxgate;
874 QC::Gates::ControlledYGate<> cygate;
875 QC::Gates::ControlledZGate<> czgate;
876 QC::Gates::ControlledPhaseShiftGate<> cpgate;
877 QC::Gates::ControlledRxGate<> crxgate;
878 QC::Gates::ControlledRyGate<> crygate;
879 QC::Gates::ControlledRzGate<> crzgate;
880 QC::Gates::ControlledHadamardGate<> ch;
881 QC::Gates::ControlledSquareRootNOTGate<> csx;
882 QC::Gates::ControlledSquareRootNOTDagGate<> csxdag;
883 QC::Gates::SwapGate<> swapgate;
884 QC::Gates::ToffoliGate<> ccxgate;
885 QC::Gates::FredkinGate<> cswapgate;
886 QC::Gates::ControlledUGate<> cugate;
887};
888
889} // namespace Private
890} // namespace Simulators
891
892#endif
893
894#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:20