15#ifndef _QCSIMSIMULATOR_H
16#define _QCSIMSIMULATOR_H
18#ifdef INCLUDED_BY_FACTORY
22#define _USE_MATH_DEFINES
31class IndividualSimulator;
44class QCSimSimulator :
public QCSimState {
45 friend class IndividualSimulator;
48 QCSimSimulator() =
default;
50 QCSimSimulator(
const QCSimSimulator &) =
delete;
51 QCSimSimulator &operator=(
const QCSimSimulator &) =
delete;
54 QCSimSimulator(QCSimSimulator &&other) =
default;
55 QCSimSimulator &operator=(QCSimSimulator &&other) =
default;
64 const Eigen::Matrix2cd& gate)
override {
70 throw std::runtime_error(
"QCSimSimulator::ApplyGenericOneQubitGate: Unsupported simulation type.");
72 const QC::Gates::AppliedGate<> agate(gate, qubit);
75 mpsSimulator->ApplyGate(agate);
77 tensorNetwork->AddGate(agate, qubit);
81 ApplyStatevectorOrDensityMatrix(agate);
83 NotifyObservers({qubit});
93 const Eigen::Matrix4cd& gate)
override {
99 throw std::runtime_error(
100 "QCSimSimulator::ApplyGenericTwoQubitGate: Unsupported simulation "
103 const QC::Gates::AppliedGate<> agate(gate, qubit0, qubit1);
106 mpsSimulator->ApplyGate(agate);
108 tensorNetwork->AddGate(agate, qubit0, qubit1);
112 ApplyStatevectorOrDensityMatrix(agate);
114 NotifyObservers({qubit0, qubit1});
125 pgate.SetPhaseShift(lambda);
127 mpsSimulator->ApplyGate(pgate,
static_cast<unsigned int>(qubit));
129 if (std::abs(lambda - M_PI_2) > 1e-10)
130 throw std::runtime_error(
131 "QCSimSimulator::ApplyP: Invalid phase shift "
132 "angle for a Clifford gate.");
133 cliffordSimulator->ApplyS(
static_cast<unsigned int>(qubit));
135 tensorNetwork->AddGate(pgate,
static_cast<unsigned int>(qubit));
137 extendedStabilizer->ApplyP(qubit, lambda);
139 pp->ApplyP(
static_cast<unsigned int>(qubit), lambda);
141 QC::Gates::AppliedGate<> agate(pgate.getRawOperatorMatrix(), qubit);
142 pathIntegralSimulator->ApplyGate(agate);
145 ApplyStatevectorOrDensityMatrix(pgate,
146 static_cast<unsigned int>(qubit));
147 NotifyObservers({qubit});
158 mpsSimulator->ApplyGate(xgate,
static_cast<unsigned int>(qubit));
160 cliffordSimulator->ApplyX(
static_cast<unsigned int>(qubit));
162 tensorNetwork->AddGate(xgate,
static_cast<unsigned int>(qubit));
164 extendedStabilizer->ApplyX(qubit);
166 pp->ApplyX(
static_cast<unsigned int>(qubit));
168 QC::Gates::AppliedGate<> agate(xgate.getRawOperatorMatrix(), qubit);
169 pathIntegralSimulator->ApplyGate(agate);
172 ApplyStatevectorOrDensityMatrix(xgate,
173 static_cast<unsigned int>(qubit));
174 NotifyObservers({qubit});
185 mpsSimulator->ApplyGate(ygate,
static_cast<unsigned int>(qubit));
187 cliffordSimulator->ApplyY(
static_cast<unsigned int>(qubit));
189 tensorNetwork->AddGate(ygate,
static_cast<unsigned int>(qubit));
191 extendedStabilizer->ApplyY(qubit);
193 pp->ApplyY(
static_cast<unsigned int>(qubit));
195 QC::Gates::AppliedGate<> agate(ygate.getRawOperatorMatrix(), qubit);
196 pathIntegralSimulator->ApplyGate(agate);
199 ApplyStatevectorOrDensityMatrix(ygate,
200 static_cast<unsigned int>(qubit));
201 NotifyObservers({qubit});
212 mpsSimulator->ApplyGate(zgate,
static_cast<unsigned int>(qubit));
214 cliffordSimulator->ApplyZ(
static_cast<unsigned int>(qubit));
216 tensorNetwork->AddGate(zgate,
static_cast<unsigned int>(qubit));
218 extendedStabilizer->ApplyZ(qubit);
220 pp->ApplyZ(
static_cast<unsigned int>(qubit));
222 QC::Gates::AppliedGate<> agate(zgate.getRawOperatorMatrix(), qubit);
223 pathIntegralSimulator->ApplyGate(agate);
226 ApplyStatevectorOrDensityMatrix(zgate,
227 static_cast<unsigned int>(qubit));
228 NotifyObservers({qubit});
239 mpsSimulator->ApplyGate(h,
static_cast<unsigned int>(qubit));
241 cliffordSimulator->ApplyH(
static_cast<unsigned int>(qubit));
243 tensorNetwork->AddGate(h,
static_cast<unsigned int>(qubit));
245 extendedStabilizer->ApplyH(qubit);
247 pp->ApplyH(
static_cast<unsigned int>(qubit));
249 QC::Gates::AppliedGate<> agate(h.getRawOperatorMatrix(), qubit);
250 pathIntegralSimulator->ApplyGate(agate);
253 ApplyStatevectorOrDensityMatrix(h,
static_cast<unsigned int>(qubit));
254 NotifyObservers({qubit});
265 mpsSimulator->ApplyGate(sgate,
static_cast<unsigned int>(qubit));
267 cliffordSimulator->ApplyS(
static_cast<unsigned int>(qubit));
269 tensorNetwork->AddGate(sgate,
static_cast<unsigned int>(qubit));
271 extendedStabilizer->ApplyS(qubit);
273 pp->ApplyS(
static_cast<unsigned int>(qubit));
275 QC::Gates::AppliedGate<> agate(sgate.getRawOperatorMatrix(), qubit);
276 pathIntegralSimulator->ApplyGate(agate);
279 ApplyStatevectorOrDensityMatrix(sgate,
280 static_cast<unsigned int>(qubit));
281 NotifyObservers({qubit});
292 mpsSimulator->ApplyGate(sdggate,
static_cast<unsigned int>(qubit));
294 cliffordSimulator->ApplySdg(
static_cast<unsigned int>(qubit));
296 tensorNetwork->AddGate(sdggate,
static_cast<unsigned int>(qubit));
298 extendedStabilizer->ApplySDG(qubit);
300 pp->ApplySDG(
static_cast<unsigned int>(qubit));
302 QC::Gates::AppliedGate<> agate(sdggate.getRawOperatorMatrix(), qubit);
303 pathIntegralSimulator->ApplyGate(agate);
306 ApplyStatevectorOrDensityMatrix(sdggate,
307 static_cast<unsigned int>(qubit));
308 NotifyObservers({qubit});
319 mpsSimulator->ApplyGate(tgate,
static_cast<unsigned int>(qubit));
321 throw std::runtime_error(
322 "QCSimSimulator::ApplyT: The stabilizer simulator does not support "
323 "non-clifford gates.");
325 tensorNetwork->AddGate(tgate,
static_cast<unsigned int>(qubit));
327 extendedStabilizer->ApplyT(qubit);
329 pp->ApplyT(
static_cast<unsigned int>(qubit));
331 QC::Gates::AppliedGate<> agate(tgate.getRawOperatorMatrix(), qubit);
332 pathIntegralSimulator->ApplyGate(agate);
335 ApplyStatevectorOrDensityMatrix(tgate,
336 static_cast<unsigned int>(qubit));
337 NotifyObservers({qubit});
348 mpsSimulator->ApplyGate(tdggate,
static_cast<unsigned int>(qubit));
350 throw std::runtime_error(
351 "QCSimSimulator::ApplyTDG: The stabilizer simulator does not support "
352 "non-clifford gates.");
354 tensorNetwork->AddGate(tdggate,
static_cast<unsigned int>(qubit));
356 extendedStabilizer->ApplyTDG(qubit);
358 pp->ApplyTDG(
static_cast<unsigned int>(qubit));
360 QC::Gates::AppliedGate<> agate(tdggate.getRawOperatorMatrix(), qubit);
361 pathIntegralSimulator->ApplyGate(agate);
364 ApplyStatevectorOrDensityMatrix(tdggate,
365 static_cast<unsigned int>(qubit));
366 NotifyObservers({qubit});
377 mpsSimulator->ApplyGate(sxgate,
static_cast<unsigned int>(qubit));
379 cliffordSimulator->ApplySx(
static_cast<unsigned int>(qubit));
381 tensorNetwork->AddGate(sxgate,
static_cast<unsigned int>(qubit));
383 extendedStabilizer->ApplySX(qubit);
385 pp->ApplySX(
static_cast<unsigned int>(qubit));
387 QC::Gates::AppliedGate<> agate(sxgate.getRawOperatorMatrix(), qubit);
388 pathIntegralSimulator->ApplyGate(agate);
391 ApplyStatevectorOrDensityMatrix(sxgate,
392 static_cast<unsigned int>(qubit));
393 NotifyObservers({qubit});
404 mpsSimulator->ApplyGate(sxdaggate,
static_cast<unsigned int>(qubit));
406 cliffordSimulator->ApplySxDag(
static_cast<unsigned int>(qubit));
408 tensorNetwork->AddGate(sxdaggate,
static_cast<unsigned int>(qubit));
410 extendedStabilizer->ApplySXDG(qubit);
412 pp->ApplySXDG(
static_cast<unsigned int>(qubit));
414 QC::Gates::AppliedGate<> agate(sxdaggate.getRawOperatorMatrix(), qubit);
415 pathIntegralSimulator->ApplyGate(agate);
418 ApplyStatevectorOrDensityMatrix(sxdaggate,
419 static_cast<unsigned int>(qubit));
420 NotifyObservers({qubit});
431 mpsSimulator->ApplyGate(k,
static_cast<unsigned int>(qubit));
433 cliffordSimulator->ApplyK(
static_cast<unsigned int>(qubit));
435 tensorNetwork->AddGate(k,
static_cast<unsigned int>(qubit));
437 extendedStabilizer->ApplyK(qubit);
439 pp->ApplyK(
static_cast<unsigned int>(qubit));
441 QC::Gates::AppliedGate<> agate(k.getRawOperatorMatrix(), qubit);
442 pathIntegralSimulator->ApplyGate(agate);
445 ApplyStatevectorOrDensityMatrix(k,
static_cast<unsigned int>(qubit));
446 NotifyObservers({qubit});
457 rxgate.SetTheta(theta);
459 mpsSimulator->ApplyGate(rxgate,
static_cast<unsigned int>(qubit));
461 throw std::runtime_error(
462 "QCSimSimulator::ApplyRx: The stabilizer "
463 "simulator does not support the Rx gate.");
465 tensorNetwork->AddGate(rxgate,
static_cast<unsigned int>(qubit));
467 extendedStabilizer->ApplyRX(qubit, theta);
469 pp->ApplyRX(
static_cast<unsigned int>(qubit), theta);
471 QC::Gates::AppliedGate<> agate(rxgate.getRawOperatorMatrix(), qubit);
472 pathIntegralSimulator->ApplyGate(agate);
475 ApplyStatevectorOrDensityMatrix(rxgate,
476 static_cast<unsigned int>(qubit));
477 NotifyObservers({qubit});
488 rygate.SetTheta(theta);
490 mpsSimulator->ApplyGate(rygate,
static_cast<unsigned int>(qubit));
492 throw std::runtime_error(
493 "QCSimSimulator::ApplyRy: The stabilizer "
494 "simulator does not support the Ry gate.");
496 tensorNetwork->AddGate(rygate,
static_cast<unsigned int>(qubit));
498 extendedStabilizer->ApplyRY(qubit, theta);
500 pp->ApplyRY(
static_cast<unsigned int>(qubit), theta);
502 QC::Gates::AppliedGate<> agate(rygate.getRawOperatorMatrix(), qubit);
503 pathIntegralSimulator->ApplyGate(agate);
506 ApplyStatevectorOrDensityMatrix(rygate,
507 static_cast<unsigned int>(qubit));
508 NotifyObservers({qubit});
519 rzgate.SetTheta(theta);
521 mpsSimulator->ApplyGate(rzgate,
static_cast<unsigned int>(qubit));
523 throw std::runtime_error(
524 "QCSimSimulator::ApplyRz: The stabilizer "
525 "simulator does not support the Rz gate.");
527 tensorNetwork->AddGate(rzgate,
static_cast<unsigned int>(qubit));
529 extendedStabilizer->ApplyRZ(qubit, theta);
531 pp->ApplyRZ(
static_cast<unsigned int>(qubit), theta);
533 QC::Gates::AppliedGate<> agate(rzgate.getRawOperatorMatrix(), qubit);
534 pathIntegralSimulator->ApplyGate(agate);
537 ApplyStatevectorOrDensityMatrix(rzgate,
538 static_cast<unsigned int>(qubit));
539 NotifyObservers({qubit});
553 double gamma)
override {
554 ugate.SetParams(theta, phi, lambda, gamma);
556 mpsSimulator->ApplyGate(ugate,
static_cast<unsigned int>(qubit));
558 throw std::runtime_error(
559 "QCSimSimulator::ApplyU: The stabilizer "
560 "simulator does not support the U gate.");
562 tensorNetwork->AddGate(ugate,
static_cast<unsigned int>(qubit));
564 extendedStabilizer->ApplyU(qubit, theta, phi, lambda, gamma);
566 pp->ApplyU(
static_cast<unsigned int>(qubit), theta, phi, lambda, gamma);
568 QC::Gates::AppliedGate<> agate(ugate.getRawOperatorMatrix(), qubit);
569 pathIntegralSimulator->ApplyGate(agate);
572 ApplyStatevectorOrDensityMatrix(ugate,
573 static_cast<unsigned int>(qubit));
574 NotifyObservers({qubit});
586 mpsSimulator->ApplyGate(cxgate,
static_cast<unsigned int>(tgt_qubit),
587 static_cast<unsigned int>(ctrl_qubit));
589 cliffordSimulator->ApplyCX(
static_cast<unsigned int>(tgt_qubit),
590 static_cast<unsigned int>(ctrl_qubit));
592 tensorNetwork->AddGate(cxgate,
static_cast<unsigned int>(ctrl_qubit),
593 static_cast<unsigned int>(tgt_qubit));
595 extendedStabilizer->ApplyCX(ctrl_qubit, tgt_qubit);
597 pp->ApplyCX(
static_cast<unsigned int>(ctrl_qubit),
598 static_cast<unsigned int>(tgt_qubit));
600 QC::Gates::AppliedGate<> agate(cxgate.getRawOperatorMatrix(),
601 tgt_qubit, ctrl_qubit);
602 pathIntegralSimulator->ApplyGate(agate);
605 ApplyStatevectorOrDensityMatrix(
606 cxgate,
static_cast<unsigned int>(tgt_qubit),
607 static_cast<unsigned int>(ctrl_qubit));
608 NotifyObservers({tgt_qubit, ctrl_qubit});
620 mpsSimulator->ApplyGate(cygate,
static_cast<unsigned int>(tgt_qubit),
621 static_cast<unsigned int>(ctrl_qubit));
623 cliffordSimulator->ApplyCY(
static_cast<unsigned int>(tgt_qubit),
624 static_cast<unsigned int>(ctrl_qubit));
626 tensorNetwork->AddGate(cygate,
static_cast<unsigned int>(ctrl_qubit),
627 static_cast<unsigned int>(tgt_qubit));
629 extendedStabilizer->ApplyCY(ctrl_qubit, tgt_qubit);
631 pp->ApplyCY(
static_cast<unsigned int>(ctrl_qubit),
632 static_cast<unsigned int>(tgt_qubit));
634 QC::Gates::AppliedGate<> agate(cygate.getRawOperatorMatrix(),
635 tgt_qubit, ctrl_qubit);
636 pathIntegralSimulator->ApplyGate(agate);
639 ApplyStatevectorOrDensityMatrix(
640 cygate,
static_cast<unsigned int>(tgt_qubit),
641 static_cast<unsigned int>(ctrl_qubit));
642 NotifyObservers({tgt_qubit, ctrl_qubit});
654 mpsSimulator->ApplyGate(czgate,
static_cast<unsigned int>(tgt_qubit),
655 static_cast<unsigned int>(ctrl_qubit));
657 cliffordSimulator->ApplyCZ(
static_cast<unsigned int>(tgt_qubit),
658 static_cast<unsigned int>(ctrl_qubit));
660 tensorNetwork->AddGate(czgate,
static_cast<unsigned int>(ctrl_qubit),
661 static_cast<unsigned int>(tgt_qubit));
663 extendedStabilizer->ApplyCZ(ctrl_qubit, tgt_qubit);
665 pp->ApplyCZ(
static_cast<unsigned int>(ctrl_qubit),
666 static_cast<unsigned int>(tgt_qubit));
668 QC::Gates::AppliedGate<> agate(czgate.getRawOperatorMatrix(),
669 tgt_qubit, ctrl_qubit);
670 pathIntegralSimulator->ApplyGate(agate);
673 ApplyStatevectorOrDensityMatrix(
674 czgate,
static_cast<unsigned int>(tgt_qubit),
675 static_cast<unsigned int>(ctrl_qubit));
676 NotifyObservers({tgt_qubit, ctrl_qubit});
688 double lambda)
override {
689 cpgate.SetPhaseShift(lambda);
691 mpsSimulator->ApplyGate(cpgate,
static_cast<unsigned int>(tgt_qubit),
692 static_cast<unsigned int>(ctrl_qubit));
694 throw std::runtime_error(
695 "QCSimSimulator::ApplyCP: The stabilizer "
696 "simulator does not support the CP gate.");
698 tensorNetwork->AddGate(cpgate,
static_cast<unsigned int>(ctrl_qubit),
699 static_cast<unsigned int>(tgt_qubit));
701 extendedStabilizer->ApplyCP(ctrl_qubit, tgt_qubit, lambda);
703 pp->ApplyCP(
static_cast<unsigned int>(ctrl_qubit),
704 static_cast<unsigned int>(tgt_qubit), lambda);
706 QC::Gates::AppliedGate<> agate(cpgate.getRawOperatorMatrix(),
707 tgt_qubit, ctrl_qubit);
708 pathIntegralSimulator->ApplyGate(agate);
711 ApplyStatevectorOrDensityMatrix(
712 cpgate,
static_cast<unsigned int>(tgt_qubit),
713 static_cast<unsigned int>(ctrl_qubit));
714 NotifyObservers({tgt_qubit, ctrl_qubit});
726 double theta)
override {
727 crxgate.SetTheta(theta);
729 mpsSimulator->ApplyGate(crxgate,
static_cast<unsigned int>(tgt_qubit),
730 static_cast<unsigned int>(ctrl_qubit));
732 throw std::runtime_error(
733 "QCSimSimulator::ApplyCRx: The stabilizer "
734 "simulator does not support the CRx gate.");
736 tensorNetwork->AddGate(crxgate,
static_cast<unsigned int>(ctrl_qubit),
737 static_cast<unsigned int>(tgt_qubit));
739 extendedStabilizer->ApplyCRX(ctrl_qubit, tgt_qubit, theta);
741 pp->ApplyCRX(
static_cast<unsigned int>(ctrl_qubit),
742 static_cast<unsigned int>(tgt_qubit), theta);
744 QC::Gates::AppliedGate<> agate(crxgate.getRawOperatorMatrix(),
745 tgt_qubit, ctrl_qubit);
746 pathIntegralSimulator->ApplyGate(agate);
749 ApplyStatevectorOrDensityMatrix(
750 crxgate,
static_cast<unsigned int>(tgt_qubit),
751 static_cast<unsigned int>(ctrl_qubit));
752 NotifyObservers({tgt_qubit, ctrl_qubit});
764 double theta)
override {
765 crygate.SetTheta(theta);
767 mpsSimulator->ApplyGate(crygate,
static_cast<unsigned int>(tgt_qubit),
768 static_cast<unsigned int>(ctrl_qubit));
770 throw std::runtime_error(
771 "QCSimSimulator::ApplyCRy: The stabilizer "
772 "simulator does not support the CRy gate.");
774 tensorNetwork->AddGate(crygate,
static_cast<unsigned int>(ctrl_qubit),
775 static_cast<unsigned int>(tgt_qubit));
777 extendedStabilizer->ApplyCRY(ctrl_qubit, tgt_qubit, theta);
779 pp->ApplyCRY(
static_cast<unsigned int>(ctrl_qubit),
780 static_cast<unsigned int>(tgt_qubit), theta);
782 QC::Gates::AppliedGate<> agate(crygate.getRawOperatorMatrix(),
783 tgt_qubit, ctrl_qubit);
784 pathIntegralSimulator->ApplyGate(agate);
787 ApplyStatevectorOrDensityMatrix(
788 crygate,
static_cast<unsigned int>(tgt_qubit),
789 static_cast<unsigned int>(ctrl_qubit));
790 NotifyObservers({tgt_qubit, ctrl_qubit});
802 double theta)
override {
803 crzgate.SetTheta(theta);
805 mpsSimulator->ApplyGate(crzgate,
static_cast<unsigned int>(tgt_qubit),
806 static_cast<unsigned int>(ctrl_qubit));
808 throw std::runtime_error(
809 "QCSimSimulator::ApplyCRz: The stabilizer "
810 "simulator does not support the CRz gate.");
812 tensorNetwork->AddGate(crzgate,
static_cast<unsigned int>(ctrl_qubit),
813 static_cast<unsigned int>(tgt_qubit));
815 extendedStabilizer->ApplyCRZ(ctrl_qubit, tgt_qubit, theta);
817 pp->ApplyCRZ(
static_cast<unsigned int>(ctrl_qubit),
818 static_cast<unsigned int>(tgt_qubit), theta);
820 QC::Gates::AppliedGate<> agate(crzgate.getRawOperatorMatrix(), tgt_qubit,
822 pathIntegralSimulator->ApplyGate(agate);
825 ApplyStatevectorOrDensityMatrix(
826 crzgate,
static_cast<unsigned int>(tgt_qubit),
827 static_cast<unsigned int>(ctrl_qubit));
828 NotifyObservers({tgt_qubit, ctrl_qubit});
840 mpsSimulator->ApplyGate(ch,
static_cast<unsigned int>(tgt_qubit),
841 static_cast<unsigned int>(ctrl_qubit));
843 throw std::runtime_error(
844 "QCSimSimulator::ApplyCH: The stabilizer "
845 "simulator does not support the CH gate.");
847 tensorNetwork->AddGate(ch,
static_cast<unsigned int>(ctrl_qubit),
848 static_cast<unsigned int>(tgt_qubit));
850 extendedStabilizer->ApplyCH(ctrl_qubit, tgt_qubit);
852 pp->ApplyCH(
static_cast<unsigned int>(ctrl_qubit),
853 static_cast<unsigned int>(tgt_qubit));
855 QC::Gates::AppliedGate<> agate(ch.getRawOperatorMatrix(), tgt_qubit,
857 pathIntegralSimulator->ApplyGate(agate);
860 ApplyStatevectorOrDensityMatrix(
861 ch,
static_cast<unsigned int>(tgt_qubit),
862 static_cast<unsigned int>(ctrl_qubit));
863 NotifyObservers({tgt_qubit, ctrl_qubit});
875 mpsSimulator->ApplyGate(csx,
static_cast<unsigned int>(tgt_qubit),
876 static_cast<unsigned int>(ctrl_qubit));
878 throw std::runtime_error(
879 "QCSimSimulator::ApplyCSx: The stabilizer "
880 "simulator does not support the CSx gate.");
882 tensorNetwork->AddGate(csx,
static_cast<unsigned int>(ctrl_qubit),
883 static_cast<unsigned int>(tgt_qubit));
885 extendedStabilizer->ApplyCSX(ctrl_qubit, tgt_qubit);
887 pp->ApplyCSX(
static_cast<unsigned int>(ctrl_qubit),
888 static_cast<unsigned int>(tgt_qubit));
890 QC::Gates::AppliedGate<> agate(csx.getRawOperatorMatrix(), tgt_qubit,
892 pathIntegralSimulator->ApplyGate(agate);
895 ApplyStatevectorOrDensityMatrix(
896 csx,
static_cast<unsigned int>(tgt_qubit),
897 static_cast<unsigned int>(ctrl_qubit));
898 NotifyObservers({tgt_qubit, ctrl_qubit});
911 mpsSimulator->ApplyGate(csxdag,
static_cast<unsigned int>(tgt_qubit),
912 static_cast<unsigned int>(ctrl_qubit));
914 throw std::runtime_error(
915 "QCSimSimulator::ApplyCSxDAG: The stabilizer "
916 "simulator does not support the CSxDag gate.");
918 tensorNetwork->AddGate(csxdag,
static_cast<unsigned int>(ctrl_qubit),
919 static_cast<unsigned int>(tgt_qubit));
921 extendedStabilizer->ApplyCSXDAG(ctrl_qubit, tgt_qubit);
923 pp->ApplyCSXDAG(
static_cast<unsigned int>(ctrl_qubit),
924 static_cast<unsigned int>(tgt_qubit));
926 QC::Gates::AppliedGate<> agate(csxdag.getRawOperatorMatrix(), tgt_qubit,
928 pathIntegralSimulator->ApplyGate(agate);
931 ApplyStatevectorOrDensityMatrix(
932 csxdag,
static_cast<unsigned int>(tgt_qubit),
933 static_cast<unsigned int>(ctrl_qubit));
934 NotifyObservers({tgt_qubit, ctrl_qubit});
946 mpsSimulator->ApplyGate(swapgate,
static_cast<unsigned int>(qubit1),
947 static_cast<unsigned int>(qubit0));
949 cliffordSimulator->ApplySwap(
static_cast<unsigned int>(qubit1),
950 static_cast<unsigned int>(qubit0));
952 tensorNetwork->AddGate(swapgate,
static_cast<unsigned int>(qubit0),
953 static_cast<unsigned int>(qubit1));
955 extendedStabilizer->ApplySWAP(qubit0, qubit1);
957 pp->ApplySWAP(
static_cast<unsigned int>(qubit0),
958 static_cast<unsigned int>(qubit1));
960 QC::Gates::AppliedGate<> agate(swapgate.getRawOperatorMatrix(), qubit1,
962 pathIntegralSimulator->ApplyGate(agate);
965 ApplyStatevectorOrDensityMatrix(
966 swapgate,
static_cast<unsigned int>(qubit1),
967 static_cast<unsigned int>(qubit0));
968 NotifyObservers({qubit1, qubit0});
982 const size_t q1 = qubit0;
983 const size_t q2 = qubit1;
984 const size_t q3 = qubit2;
987 mpsSimulator->ApplyGate(csx,
static_cast<unsigned int>(q3),
988 static_cast<unsigned int>(q2));
989 NotifyObservers({qubit1, qubit2});
991 mpsSimulator->ApplyGate(cxgate,
static_cast<unsigned int>(q2),
992 static_cast<unsigned int>(q1));
993 NotifyObservers({qubit0, qubit1});
995 mpsSimulator->ApplyGate(csxdag,
static_cast<unsigned int>(q3),
996 static_cast<unsigned int>(q2));
997 NotifyObservers({qubit1, qubit2});
999 mpsSimulator->ApplyGate(cxgate,
static_cast<unsigned int>(q2),
1000 static_cast<unsigned int>(q1));
1001 NotifyObservers({qubit0, qubit1});
1003 mpsSimulator->ApplyGate(csx,
static_cast<unsigned int>(q3),
1004 static_cast<unsigned int>(q1));
1005 NotifyObservers({qubit0, qubit2});
1007 SimulationType::kMatrixProductOperator) {
1008 ApplyDecomposedGate(
1010 ApplyCSx(qubit1, qubit2);
1012 ApplyCSxDAG(qubit1, qubit2);
1014 ApplyCSx(qubit0, qubit2);
1016 {qubit2, qubit1, qubit0});
1018 throw std::runtime_error(
1019 "QCSimSimulator::ApplyCCX: The stabilizer "
1020 "simulator does not support the CCX gate.");
1022 const size_t q1 = qubit0;
1023 const size_t q2 = qubit1;
1024 const size_t q3 = qubit2;
1027 tensorNetwork->AddGate(csx,
static_cast<unsigned int>(q2),
1028 static_cast<unsigned int>(q3));
1029 NotifyObservers({qubit1, qubit2});
1031 tensorNetwork->AddGate(cxgate,
static_cast<unsigned int>(q1),
1032 static_cast<unsigned int>(q2));
1033 NotifyObservers({qubit0, qubit1});
1035 tensorNetwork->AddGate(csxdag,
static_cast<unsigned int>(q2),
1036 static_cast<unsigned int>(q3));
1037 NotifyObservers({qubit1, qubit2});
1039 tensorNetwork->AddGate(cxgate,
static_cast<unsigned int>(q1),
1040 static_cast<unsigned int>(q2));
1041 NotifyObservers({qubit0, qubit1});
1043 tensorNetwork->AddGate(csx,
static_cast<unsigned int>(q1),
1044 static_cast<unsigned int>(q3));
1045 NotifyObservers({qubit0, qubit2});
1047 extendedStabilizer->ApplyCCX(qubit0, qubit1, qubit2);
1048 NotifyObservers({qubit2, qubit1, qubit0});
1050 pp->ApplyCCX(
static_cast<unsigned int>(qubit0),
1051 static_cast<unsigned int>(qubit1),
1052 static_cast<unsigned int>(qubit2));
1053 NotifyObservers({qubit2, qubit1, qubit0});
1055 QC::Gates::AppliedGate<> agate(ccxgate.getRawOperatorMatrix(), qubit2,
1057 pathIntegralSimulator->ApplyGate(agate);
1058 NotifyObservers({qubit2, qubit1, qubit0});
1060 ApplyStatevectorOrDensityMatrix(
1061 ccxgate,
static_cast<unsigned int>(qubit2),
1062 static_cast<unsigned int>(qubit1),
1063 static_cast<unsigned int>(qubit0));
1064 NotifyObservers({qubit2, qubit1, qubit0});
1079 const size_t q1 = ctrl_qubit;
1080 const size_t q2 = qubit0;
1081 const size_t q3 = qubit1;
1085 mpsSimulator->ApplyGate(cxgate,
static_cast<unsigned int>(q2),
1086 static_cast<unsigned int>(q3));
1087 NotifyObservers({qubit1, qubit0});
1089 mpsSimulator->ApplyGate(csx,
static_cast<unsigned int>(q3),
1090 static_cast<unsigned int>(q2));
1091 NotifyObservers({qubit0, qubit1});
1093 mpsSimulator->ApplyGate(cxgate,
static_cast<unsigned int>(q2),
1094 static_cast<unsigned int>(q1));
1095 NotifyObservers({ctrl_qubit, qubit0});
1097 pgate.SetPhaseShift(M_PI);
1098 mpsSimulator->ApplyGate(pgate,
static_cast<unsigned int>(q3));
1099 NotifyObservers({qubit1});
1100 pgate.SetPhaseShift(-M_PI_2);
1101 mpsSimulator->ApplyGate(pgate,
static_cast<unsigned int>(q2));
1102 NotifyObservers({qubit0});
1104 mpsSimulator->ApplyGate(csx,
static_cast<unsigned int>(q3),
1105 static_cast<unsigned int>(q2));
1106 NotifyObservers({qubit0, qubit1});
1108 mpsSimulator->ApplyGate(cxgate,
static_cast<unsigned int>(q2),
1109 static_cast<unsigned int>(q1));
1110 NotifyObservers({ctrl_qubit, qubit0});
1112 pgate.SetPhaseShift(M_PI);
1113 mpsSimulator->ApplyGate(pgate,
static_cast<unsigned int>(q3));
1114 NotifyObservers({qubit1});
1116 mpsSimulator->ApplyGate(csx,
static_cast<unsigned int>(q3),
1117 static_cast<unsigned int>(q1));
1118 NotifyObservers({ctrl_qubit, qubit1});
1120 mpsSimulator->ApplyGate(cxgate,
static_cast<unsigned int>(q2),
1121 static_cast<unsigned int>(q3));
1122 NotifyObservers({qubit1, qubit0});
1124 SimulationType::kMatrixProductOperator) {
1125 ApplyDecomposedGate(
1128 ApplyCSx(qubit0, qubit1);
1132 ApplyCSx(qubit0, qubit1);
1135 ApplyCSx(ctrl_qubit, qubit1);
1138 {qubit1, qubit0, ctrl_qubit});
1140 throw std::runtime_error(
1141 "QCSimSimulator::ApplyCSwap: The stabilizer "
1142 "simulator does not support the CSwap gate.");
1144 const size_t q1 = ctrl_qubit;
1145 const size_t q2 = qubit0;
1146 const size_t q3 = qubit1;
1150 tensorNetwork->AddGate(cxgate,
static_cast<unsigned int>(q3),
1151 static_cast<unsigned int>(q2));
1152 NotifyObservers({qubit1, qubit0});
1154 tensorNetwork->AddGate(csx,
static_cast<unsigned int>(q2),
1155 static_cast<unsigned int>(q3));
1156 NotifyObservers({qubit0, qubit1});
1158 tensorNetwork->AddGate(cxgate,
static_cast<unsigned int>(q1),
1159 static_cast<unsigned int>(q2));
1160 NotifyObservers({ctrl_qubit, qubit0});
1162 pgate.SetPhaseShift(M_PI);
1163 tensorNetwork->AddGate(pgate,
static_cast<unsigned int>(q3));
1164 NotifyObservers({qubit1});
1165 pgate.SetPhaseShift(-M_PI_2);
1166 tensorNetwork->AddGate(pgate,
static_cast<unsigned int>(q2));
1167 NotifyObservers({qubit0});
1169 tensorNetwork->AddGate(csx,
static_cast<unsigned int>(q2),
1170 static_cast<unsigned int>(q3));
1171 NotifyObservers({qubit0, qubit1});
1173 tensorNetwork->AddGate(cxgate,
static_cast<unsigned int>(q1),
1174 static_cast<unsigned int>(q2));
1175 NotifyObservers({ctrl_qubit, qubit0});
1177 pgate.SetPhaseShift(M_PI);
1178 tensorNetwork->AddGate(pgate,
static_cast<unsigned int>(q3));
1179 NotifyObservers({qubit1});
1181 tensorNetwork->AddGate(csx,
static_cast<unsigned int>(q1),
1182 static_cast<unsigned int>(q3));
1183 NotifyObservers({ctrl_qubit, qubit1});
1185 tensorNetwork->AddGate(cxgate,
static_cast<unsigned int>(q3),
1186 static_cast<unsigned int>(q2));
1187 NotifyObservers({qubit1, qubit0});
1189 extendedStabilizer->ApplyCSwap(ctrl_qubit, qubit0, qubit1);
1190 NotifyObservers({qubit1, qubit0, ctrl_qubit});
1192 pp->ApplyCSwap(
static_cast<unsigned int>(ctrl_qubit),
1193 static_cast<unsigned int>(qubit0),
1194 static_cast<unsigned int>(qubit1));
1195 NotifyObservers({qubit1, qubit0, ctrl_qubit});
1197 QC::Gates::AppliedGate<> agate(cswapgate.getRawOperatorMatrix(),
1198 qubit1, qubit0, ctrl_qubit);
1199 pathIntegralSimulator->ApplyGate(agate);
1200 NotifyObservers({qubit1, qubit0, ctrl_qubit});
1202 ApplyStatevectorOrDensityMatrix(
1203 cswapgate,
static_cast<unsigned int>(qubit1),
1204 static_cast<unsigned int>(qubit0),
1205 static_cast<unsigned int>(ctrl_qubit));
1206 NotifyObservers({qubit1, qubit0, ctrl_qubit});
1222 double theta,
double phi,
double lambda,
double gamma)
override {
1223 cugate.SetParams(theta, phi, lambda, gamma);
1225 mpsSimulator->ApplyGate(cugate,
static_cast<unsigned int>(tgt_qubit),
1226 static_cast<unsigned int>(ctrl_qubit));
1228 throw std::runtime_error(
1229 "QCSimSimulator::ApplyCU: The stabilizer "
1230 "simulator does not support the CU gate.");
1232 tensorNetwork->AddGate(cugate,
static_cast<unsigned int>(ctrl_qubit),
1233 static_cast<unsigned int>(tgt_qubit));
1235 extendedStabilizer->ApplyCU(ctrl_qubit, tgt_qubit, theta, phi, lambda,
1238 pp->ApplyCU(
static_cast<unsigned int>(ctrl_qubit),
1239 static_cast<unsigned int>(tgt_qubit), theta, phi, lambda,
1242 QC::Gates::AppliedGate<> agate(cugate.getRawOperatorMatrix(), tgt_qubit,
1244 pathIntegralSimulator->ApplyGate(agate);
1247 ApplyStatevectorOrDensityMatrix(
1248 cugate,
static_cast<unsigned int>(tgt_qubit),
1249 static_cast<unsigned int>(ctrl_qubit));
1250 NotifyObservers({tgt_qubit, ctrl_qubit});
1260 void ApplyNop()
override {
1274 std::unique_ptr<ISimulator> Clone()
override {
1275 auto cloned = std::make_unique<QCSimSimulator>();
1277 cloned->simulationType = simulationType;
1278 cloned->nrQubits = nrQubits;
1280 cloned->enableMultithreading = enableMultithreading;
1282 cloned->lookaheadDepth = lookaheadDepth;
1283 cloned->lookaheadDepthWithHeuristic = lookaheadDepthWithHeuristic;
1284 cloned->useOptimalMeetingPosition = useOptimalMeetingPosition;
1285 cloned->upcomingGates = upcomingGates;
1286 cloned->upcomingGateIndex = upcomingGateIndex;
1287 cloned->growthFactorGate = growthFactorGate;
1288 cloned->growthFactorSwap = growthFactorSwap;
1290 if (state) cloned->state = state->Clone();
1293 cloned->mpsSimulator = mpsSimulator->Clone();
1295 cloned->dummySim = dummySim ? dummySim->Clone() :
nullptr;
1297 cloned->gateCounterObserver =
1298 std::make_shared<GateCounterObserver>(cloned->upcomingGateIndex);
1299 cloned->RegisterObserver(cloned->gateCounterObserver);
1301 cloned->curMaxBondDim = curMaxBondDim;
1303 cloned->mpsSimulator->SetMeetingPositionCallback(
1304 cloned->meetingPositionCallback);
1305 cloned->mpsSimulator->SetBondDimensionCallback(
1306 cloned->bondDimensionCallback);
1310 cloned->mpoSimulator = mpoSimulator->Clone();
1311 cloned->dummySim = dummySim ? dummySim->Clone() :
nullptr;
1312 cloned->curMaxBondDim = curMaxBondDim;
1313 cloned->gateCounterObserver =
1314 std::make_shared<GateCounterObserver>(cloned->upcomingGateIndex);
1315 cloned->RegisterObserver(cloned->gateCounterObserver);
1316 cloned->mpoSimulator->SetMeetingPositionCallback(
1317 cloned->meetingPositionCallback);
1318 cloned->mpoSimulator->SetBondDimensionCallback(
1319 cloned->bondDimensionCallback);
1322 if (cliffordSimulator)
1323 cloned->cliffordSimulator = cliffordSimulator->Clone();
1325 if (tensorNetwork) cloned->tensorNetwork = tensorNetwork->Clone();
1327 if (pp) cloned->pp = pp->Clone();
1329 if (pathIntegralSimulator)
1330 cloned->pathIntegralSimulator = pathIntegralSimulator->Clone();
1332 if (densityMatrix) cloned->densityMatrix = densityMatrix->Clone();
1334 if (extendedStabilizer)
1335 cloned->extendedStabilizer = extendedStabilizer->Clone();
1337 for (
const auto& [key, value] : configuration.GetConfigMap())
1338 cloned->Configure(key.c_str(), value.c_str());
1340 if (configuration.IsSet(
"seed"))
1341 cloned->SetSeed(DeriveSeed(
1342 std::stoull(configuration.GetConfiguration(
"seed")),
1349 template <
class Function>
1350 void ApplyDecomposedGate(Function&& apply,
1354 std::forward<Function>(apply)();
1360 NotifyObservers(affectedQubits);
1363 template <
class Gate,
class... Qubits>
1364 void ApplyStatevectorOrDensityMatrix(
const Gate& gate, Qubits... qubits) {
1366 if constexpr (
sizeof...(Qubits) <= 2) {
1367 mpoSimulator->ApplyGate(gate,
static_cast<Eigen::Index
>(qubits)...);
1369 throw std::runtime_error(
1370 "QCSimSimulator: The matrix product operator simulator supports "
1371 "only one- and two-qubit gate operators.");
1374 densityMatrix->ApplyGate(gate,
static_cast<size_t>(qubits)...);
1376 state->ApplyGate(gate, qubits...);
1379 QC::Gates::PhaseShiftGate<> pgate;
1380 QC::Gates::PauliXGate<> xgate;
1381 QC::Gates::PauliYGate<> ygate;
1382 QC::Gates::PauliZGate<> zgate;
1383 QC::Gates::HadamardGate<> h;
1385 QC::Gates::SGate<> sgate;
1386 QC::Gates::SDGGate<> sdggate;
1387 QC::Gates::TGate<> tgate;
1388 QC::Gates::TDGGate<> tdggate;
1389 QC::Gates::SquareRootNOTGate<> sxgate;
1390 QC::Gates::SquareRootNOTDagGate<> sxdaggate;
1391 QC::Gates::HyGate<> k;
1392 QC::Gates::RxGate<> rxgate;
1393 QC::Gates::RyGate<> rygate;
1394 QC::Gates::RzGate<> rzgate;
1395 QC::Gates::UGate<> ugate;
1396 QC::Gates::CNOTGate<> cxgate;
1397 QC::Gates::ControlledYGate<> cygate;
1398 QC::Gates::ControlledZGate<> czgate;
1399 QC::Gates::ControlledPhaseShiftGate<> cpgate;
1400 QC::Gates::ControlledRxGate<> crxgate;
1401 QC::Gates::ControlledRyGate<> crygate;
1402 QC::Gates::ControlledRzGate<> crzgate;
1403 QC::Gates::ControlledHadamardGate<> ch;
1404 QC::Gates::ControlledSquareRootNOTGate<> csx;
1405 QC::Gates::ControlledSquareRootNOTDagGate<> csxdag;
1406 QC::Gates::SwapGate<> swapgate;
1407 QC::Gates::ToffoliGate<> ccxgate;
1408 QC::Gates::FredkinGate<> cswapgate;
1409 QC::Gates::ControlledUGate<> cugate;
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)
std::vector< qubit_t > qubits_vector
The type of a vector of qubits.
uint_fast64_t qubit_t
The type of a qubit.