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 {
68 throw std::runtime_error(
"QCSimSimulator::ApplyGenericOneQubitGate: Unsupported simulation type.");
70 const QC::Gates::AppliedGate<> agate(gate, qubit);
73 mpsSimulator->ApplyGate(agate);
75 tensorNetwork->AddGate(agate, qubit);
77 state->ApplyGate(agate);
79 NotifyObservers({qubit});
89 const Eigen::Matrix4cd& gate)
override {
93 throw std::runtime_error(
94 "QCSimSimulator::ApplyGenericTwoQubitGate: Unsupported simulation "
97 const QC::Gates::AppliedGate<> agate(gate, qubit0, qubit1);
100 mpsSimulator->ApplyGate(agate);
102 tensorNetwork->AddGate(agate, qubit0, qubit1);
104 state->ApplyGate(agate);
106 NotifyObservers({qubit0, qubit1});
117 pgate.SetPhaseShift(lambda);
119 mpsSimulator->ApplyGate(pgate,
static_cast<unsigned int>(qubit));
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));
127 tensorNetwork->AddGate(pgate,
static_cast<unsigned int>(qubit));
129 pp->ApplyP(
static_cast<unsigned int>(qubit), lambda);
131 QC::Gates::AppliedGate<> agate(pgate.getRawOperatorMatrix(), qubit);
132 pathIntegralSimulator->ApplyGate(agate);
135 state->ApplyGate(pgate,
static_cast<unsigned int>(qubit));
136 NotifyObservers({qubit});
147 mpsSimulator->ApplyGate(xgate,
static_cast<unsigned int>(qubit));
149 cliffordSimulator->ApplyX(
static_cast<unsigned int>(qubit));
151 tensorNetwork->AddGate(xgate,
static_cast<unsigned int>(qubit));
153 pp->ApplyX(
static_cast<unsigned int>(qubit));
155 QC::Gates::AppliedGate<> agate(xgate.getRawOperatorMatrix(), qubit);
156 pathIntegralSimulator->ApplyGate(agate);
159 state->ApplyGate(xgate,
static_cast<unsigned int>(qubit));
160 NotifyObservers({qubit});
171 mpsSimulator->ApplyGate(ygate,
static_cast<unsigned int>(qubit));
173 cliffordSimulator->ApplyY(
static_cast<unsigned int>(qubit));
175 tensorNetwork->AddGate(ygate,
static_cast<unsigned int>(qubit));
177 pp->ApplyY(
static_cast<unsigned int>(qubit));
179 QC::Gates::AppliedGate<> agate(ygate.getRawOperatorMatrix(), qubit);
180 pathIntegralSimulator->ApplyGate(agate);
183 state->ApplyGate(ygate,
static_cast<unsigned int>(qubit));
184 NotifyObservers({qubit});
195 mpsSimulator->ApplyGate(zgate,
static_cast<unsigned int>(qubit));
197 cliffordSimulator->ApplyZ(
static_cast<unsigned int>(qubit));
199 tensorNetwork->AddGate(zgate,
static_cast<unsigned int>(qubit));
201 pp->ApplyZ(
static_cast<unsigned int>(qubit));
203 QC::Gates::AppliedGate<> agate(zgate.getRawOperatorMatrix(), qubit);
204 pathIntegralSimulator->ApplyGate(agate);
207 state->ApplyGate(zgate,
static_cast<unsigned int>(qubit));
208 NotifyObservers({qubit});
219 mpsSimulator->ApplyGate(h,
static_cast<unsigned int>(qubit));
221 cliffordSimulator->ApplyH(
static_cast<unsigned int>(qubit));
223 tensorNetwork->AddGate(h,
static_cast<unsigned int>(qubit));
225 pp->ApplyH(
static_cast<unsigned int>(qubit));
227 QC::Gates::AppliedGate<> agate(h.getRawOperatorMatrix(), qubit);
228 pathIntegralSimulator->ApplyGate(agate);
231 state->ApplyGate(h,
static_cast<unsigned int>(qubit));
232 NotifyObservers({qubit});
243 mpsSimulator->ApplyGate(sgate,
static_cast<unsigned int>(qubit));
245 cliffordSimulator->ApplyS(
static_cast<unsigned int>(qubit));
247 tensorNetwork->AddGate(sgate,
static_cast<unsigned int>(qubit));
249 pp->ApplyS(
static_cast<unsigned int>(qubit));
251 QC::Gates::AppliedGate<> agate(sgate.getRawOperatorMatrix(), qubit);
252 pathIntegralSimulator->ApplyGate(agate);
255 state->ApplyGate(sgate,
static_cast<unsigned int>(qubit));
256 NotifyObservers({qubit});
267 mpsSimulator->ApplyGate(sdggate,
static_cast<unsigned int>(qubit));
269 cliffordSimulator->ApplySdg(
static_cast<unsigned int>(qubit));
271 tensorNetwork->AddGate(sdggate,
static_cast<unsigned int>(qubit));
273 pp->ApplySDG(
static_cast<unsigned int>(qubit));
275 QC::Gates::AppliedGate<> agate(sdggate.getRawOperatorMatrix(), qubit);
276 pathIntegralSimulator->ApplyGate(agate);
279 state->ApplyGate(sdggate,
static_cast<unsigned int>(qubit));
280 NotifyObservers({qubit});
291 mpsSimulator->ApplyGate(tgate,
static_cast<unsigned int>(qubit));
293 throw std::runtime_error(
294 "QCSimSimulator::ApplyT: The stabilizer simulator does not support "
295 "non-clifford gates.");
297 tensorNetwork->AddGate(tgate,
static_cast<unsigned int>(qubit));
299 pp->ApplyT(
static_cast<unsigned int>(qubit));
301 QC::Gates::AppliedGate<> agate(tgate.getRawOperatorMatrix(), qubit);
302 pathIntegralSimulator->ApplyGate(agate);
305 state->ApplyGate(tgate,
static_cast<unsigned int>(qubit));
306 NotifyObservers({qubit});
317 mpsSimulator->ApplyGate(tdggate,
static_cast<unsigned int>(qubit));
319 throw std::runtime_error(
320 "QCSimSimulator::ApplyTDG: The stabilizer simulator does not support "
321 "non-clifford gates.");
323 tensorNetwork->AddGate(tdggate,
static_cast<unsigned int>(qubit));
325 pp->ApplyTDG(
static_cast<unsigned int>(qubit));
327 QC::Gates::AppliedGate<> agate(tdggate.getRawOperatorMatrix(), qubit);
328 pathIntegralSimulator->ApplyGate(agate);
331 state->ApplyGate(tdggate,
static_cast<unsigned int>(qubit));
332 NotifyObservers({qubit});
343 mpsSimulator->ApplyGate(sxgate,
static_cast<unsigned int>(qubit));
345 cliffordSimulator->ApplySx(
static_cast<unsigned int>(qubit));
347 tensorNetwork->AddGate(sxgate,
static_cast<unsigned int>(qubit));
349 pp->ApplySX(
static_cast<unsigned int>(qubit));
351 QC::Gates::AppliedGate<> agate(sxgate.getRawOperatorMatrix(), qubit);
352 pathIntegralSimulator->ApplyGate(agate);
355 state->ApplyGate(sxgate,
static_cast<unsigned int>(qubit));
356 NotifyObservers({qubit});
367 mpsSimulator->ApplyGate(sxdaggate,
static_cast<unsigned int>(qubit));
369 cliffordSimulator->ApplySxDag(
static_cast<unsigned int>(qubit));
371 tensorNetwork->AddGate(sxdaggate,
static_cast<unsigned int>(qubit));
373 pp->ApplySXDG(
static_cast<unsigned int>(qubit));
375 QC::Gates::AppliedGate<> agate(sxdaggate.getRawOperatorMatrix(), qubit);
376 pathIntegralSimulator->ApplyGate(agate);
379 state->ApplyGate(sxdaggate,
static_cast<unsigned int>(qubit));
380 NotifyObservers({qubit});
391 mpsSimulator->ApplyGate(k,
static_cast<unsigned int>(qubit));
393 cliffordSimulator->ApplyK(
static_cast<unsigned int>(qubit));
395 tensorNetwork->AddGate(k,
static_cast<unsigned int>(qubit));
397 pp->ApplyK(
static_cast<unsigned int>(qubit));
399 QC::Gates::AppliedGate<> agate(k.getRawOperatorMatrix(), qubit);
400 pathIntegralSimulator->ApplyGate(agate);
403 state->ApplyGate(k,
static_cast<unsigned int>(qubit));
404 NotifyObservers({qubit});
415 rxgate.SetTheta(theta);
417 mpsSimulator->ApplyGate(rxgate,
static_cast<unsigned int>(qubit));
419 throw std::runtime_error(
420 "QCSimSimulator::ApplyRx: The stabilizer "
421 "simulator does not support the Rx gate.");
423 tensorNetwork->AddGate(rxgate,
static_cast<unsigned int>(qubit));
425 pp->ApplyRX(
static_cast<unsigned int>(qubit), theta);
427 QC::Gates::AppliedGate<> agate(rxgate.getRawOperatorMatrix(), qubit);
428 pathIntegralSimulator->ApplyGate(agate);
431 state->ApplyGate(rxgate,
static_cast<unsigned int>(qubit));
432 NotifyObservers({qubit});
443 rygate.SetTheta(theta);
445 mpsSimulator->ApplyGate(rygate,
static_cast<unsigned int>(qubit));
447 throw std::runtime_error(
448 "QCSimSimulator::ApplyRy: The stabilizer "
449 "simulator does not support the Ry gate.");
451 tensorNetwork->AddGate(rygate,
static_cast<unsigned int>(qubit));
453 pp->ApplyRY(
static_cast<unsigned int>(qubit), theta);
455 QC::Gates::AppliedGate<> agate(rygate.getRawOperatorMatrix(), qubit);
456 pathIntegralSimulator->ApplyGate(agate);
459 state->ApplyGate(rygate,
static_cast<unsigned int>(qubit));
460 NotifyObservers({qubit});
471 rzgate.SetTheta(theta);
473 mpsSimulator->ApplyGate(rzgate,
static_cast<unsigned int>(qubit));
475 throw std::runtime_error(
476 "QCSimSimulator::ApplyRz: The stabilizer "
477 "simulator does not support the Rz gate.");
479 tensorNetwork->AddGate(rzgate,
static_cast<unsigned int>(qubit));
481 pp->ApplyRZ(
static_cast<unsigned int>(qubit), theta);
483 QC::Gates::AppliedGate<> agate(rzgate.getRawOperatorMatrix(), qubit);
484 pathIntegralSimulator->ApplyGate(agate);
487 state->ApplyGate(rzgate,
static_cast<unsigned int>(qubit));
488 NotifyObservers({qubit});
502 double gamma)
override {
503 ugate.SetParams(theta, phi, lambda, gamma);
505 mpsSimulator->ApplyGate(ugate,
static_cast<unsigned int>(qubit));
507 throw std::runtime_error(
508 "QCSimSimulator::ApplyU: The stabilizer "
509 "simulator does not support the U gate.");
511 tensorNetwork->AddGate(ugate,
static_cast<unsigned int>(qubit));
513 pp->ApplyU(
static_cast<unsigned int>(qubit), theta, phi, lambda, gamma);
515 QC::Gates::AppliedGate<> agate(ugate.getRawOperatorMatrix(), qubit);
516 pathIntegralSimulator->ApplyGate(agate);
519 state->ApplyGate(ugate,
static_cast<unsigned int>(qubit));
520 NotifyObservers({qubit});
532 mpsSimulator->ApplyGate(cxgate,
static_cast<unsigned int>(tgt_qubit),
533 static_cast<unsigned int>(ctrl_qubit));
535 cliffordSimulator->ApplyCX(
static_cast<unsigned int>(tgt_qubit),
536 static_cast<unsigned int>(ctrl_qubit));
538 tensorNetwork->AddGate(cxgate,
static_cast<unsigned int>(ctrl_qubit),
539 static_cast<unsigned int>(tgt_qubit));
541 pp->ApplyCX(
static_cast<unsigned int>(ctrl_qubit),
542 static_cast<unsigned int>(tgt_qubit));
544 QC::Gates::AppliedGate<> agate(cxgate.getRawOperatorMatrix(),
545 tgt_qubit, ctrl_qubit);
546 pathIntegralSimulator->ApplyGate(agate);
549 state->ApplyGate(cxgate,
static_cast<unsigned int>(tgt_qubit),
550 static_cast<unsigned int>(ctrl_qubit));
551 NotifyObservers({tgt_qubit, ctrl_qubit});
563 mpsSimulator->ApplyGate(cygate,
static_cast<unsigned int>(tgt_qubit),
564 static_cast<unsigned int>(ctrl_qubit));
566 cliffordSimulator->ApplyCY(
static_cast<unsigned int>(tgt_qubit),
567 static_cast<unsigned int>(ctrl_qubit));
569 tensorNetwork->AddGate(cygate,
static_cast<unsigned int>(ctrl_qubit),
570 static_cast<unsigned int>(tgt_qubit));
572 pp->ApplyCY(
static_cast<unsigned int>(ctrl_qubit),
573 static_cast<unsigned int>(tgt_qubit));
575 QC::Gates::AppliedGate<> agate(cygate.getRawOperatorMatrix(),
576 tgt_qubit, ctrl_qubit);
577 pathIntegralSimulator->ApplyGate(agate);
580 state->ApplyGate(cygate,
static_cast<unsigned int>(tgt_qubit),
581 static_cast<unsigned int>(ctrl_qubit));
582 NotifyObservers({tgt_qubit, ctrl_qubit});
594 mpsSimulator->ApplyGate(czgate,
static_cast<unsigned int>(tgt_qubit),
595 static_cast<unsigned int>(ctrl_qubit));
597 cliffordSimulator->ApplyCZ(
static_cast<unsigned int>(tgt_qubit),
598 static_cast<unsigned int>(ctrl_qubit));
600 tensorNetwork->AddGate(czgate,
static_cast<unsigned int>(ctrl_qubit),
601 static_cast<unsigned int>(tgt_qubit));
603 pp->ApplyCZ(
static_cast<unsigned int>(ctrl_qubit),
604 static_cast<unsigned int>(tgt_qubit));
606 QC::Gates::AppliedGate<> agate(czgate.getRawOperatorMatrix(),
607 tgt_qubit, ctrl_qubit);
608 pathIntegralSimulator->ApplyGate(agate);
611 state->ApplyGate(czgate,
static_cast<unsigned int>(tgt_qubit),
612 static_cast<unsigned int>(ctrl_qubit));
613 NotifyObservers({tgt_qubit, ctrl_qubit});
625 double lambda)
override {
626 cpgate.SetPhaseShift(lambda);
628 mpsSimulator->ApplyGate(cpgate,
static_cast<unsigned int>(tgt_qubit),
629 static_cast<unsigned int>(ctrl_qubit));
631 throw std::runtime_error(
632 "QCSimSimulator::ApplyCP: The stabilizer "
633 "simulator does not support the CP gate.");
635 tensorNetwork->AddGate(cpgate,
static_cast<unsigned int>(ctrl_qubit),
636 static_cast<unsigned int>(tgt_qubit));
638 pp->ApplyCP(
static_cast<unsigned int>(ctrl_qubit),
639 static_cast<unsigned int>(tgt_qubit), lambda);
641 QC::Gates::AppliedGate<> agate(cpgate.getRawOperatorMatrix(),
642 tgt_qubit, ctrl_qubit);
643 pathIntegralSimulator->ApplyGate(agate);
646 state->ApplyGate(cpgate,
static_cast<unsigned int>(tgt_qubit),
647 static_cast<unsigned int>(ctrl_qubit));
648 NotifyObservers({tgt_qubit, ctrl_qubit});
660 double theta)
override {
661 crxgate.SetTheta(theta);
663 mpsSimulator->ApplyGate(crxgate,
static_cast<unsigned int>(tgt_qubit),
664 static_cast<unsigned int>(ctrl_qubit));
666 throw std::runtime_error(
667 "QCSimSimulator::ApplyCRx: The stabilizer "
668 "simulator does not support the CRx gate.");
670 tensorNetwork->AddGate(crxgate,
static_cast<unsigned int>(ctrl_qubit),
671 static_cast<unsigned int>(tgt_qubit));
673 pp->ApplyCRX(
static_cast<unsigned int>(ctrl_qubit),
674 static_cast<unsigned int>(tgt_qubit), theta);
676 QC::Gates::AppliedGate<> agate(crxgate.getRawOperatorMatrix(),
677 tgt_qubit, ctrl_qubit);
678 pathIntegralSimulator->ApplyGate(agate);
681 state->ApplyGate(crxgate,
static_cast<unsigned int>(tgt_qubit),
682 static_cast<unsigned int>(ctrl_qubit));
683 NotifyObservers({tgt_qubit, ctrl_qubit});
695 double theta)
override {
696 crygate.SetTheta(theta);
698 mpsSimulator->ApplyGate(crygate,
static_cast<unsigned int>(tgt_qubit),
699 static_cast<unsigned int>(ctrl_qubit));
701 throw std::runtime_error(
702 "QCSimSimulator::ApplyCRy: The stabilizer "
703 "simulator does not support the CRy gate.");
705 tensorNetwork->AddGate(crygate,
static_cast<unsigned int>(ctrl_qubit),
706 static_cast<unsigned int>(tgt_qubit));
708 pp->ApplyCRY(
static_cast<unsigned int>(ctrl_qubit),
709 static_cast<unsigned int>(tgt_qubit), theta);
711 QC::Gates::AppliedGate<> agate(crygate.getRawOperatorMatrix(),
712 tgt_qubit, ctrl_qubit);
713 pathIntegralSimulator->ApplyGate(agate);
716 state->ApplyGate(crygate,
static_cast<unsigned int>(tgt_qubit),
717 static_cast<unsigned int>(ctrl_qubit));
718 NotifyObservers({tgt_qubit, ctrl_qubit});
730 double theta)
override {
731 crzgate.SetTheta(theta);
733 mpsSimulator->ApplyGate(crzgate,
static_cast<unsigned int>(tgt_qubit),
734 static_cast<unsigned int>(ctrl_qubit));
736 throw std::runtime_error(
737 "QCSimSimulator::ApplyCRz: The stabilizer "
738 "simulator does not support the CRz gate.");
740 tensorNetwork->AddGate(crzgate,
static_cast<unsigned int>(ctrl_qubit),
741 static_cast<unsigned int>(tgt_qubit));
743 pp->ApplyCRZ(
static_cast<unsigned int>(ctrl_qubit),
744 static_cast<unsigned int>(tgt_qubit), theta);
746 QC::Gates::AppliedGate<> agate(crzgate.getRawOperatorMatrix(), tgt_qubit,
748 pathIntegralSimulator->ApplyGate(agate);
751 state->ApplyGate(crzgate,
static_cast<unsigned int>(tgt_qubit),
752 static_cast<unsigned int>(ctrl_qubit));
753 NotifyObservers({tgt_qubit, ctrl_qubit});
765 mpsSimulator->ApplyGate(ch,
static_cast<unsigned int>(tgt_qubit),
766 static_cast<unsigned int>(ctrl_qubit));
768 throw std::runtime_error(
769 "QCSimSimulator::ApplyCH: The stabilizer "
770 "simulator does not support the CH gate.");
772 tensorNetwork->AddGate(ch,
static_cast<unsigned int>(ctrl_qubit),
773 static_cast<unsigned int>(tgt_qubit));
775 pp->ApplyCH(
static_cast<unsigned int>(ctrl_qubit),
776 static_cast<unsigned int>(tgt_qubit));
778 QC::Gates::AppliedGate<> agate(ch.getRawOperatorMatrix(), tgt_qubit,
780 pathIntegralSimulator->ApplyGate(agate);
783 state->ApplyGate(ch,
static_cast<unsigned int>(tgt_qubit),
784 static_cast<unsigned int>(ctrl_qubit));
785 NotifyObservers({tgt_qubit, ctrl_qubit});
797 mpsSimulator->ApplyGate(csx,
static_cast<unsigned int>(tgt_qubit),
798 static_cast<unsigned int>(ctrl_qubit));
800 throw std::runtime_error(
801 "QCSimSimulator::ApplyCSx: The stabilizer "
802 "simulator does not support the CSx gate.");
804 tensorNetwork->AddGate(csx,
static_cast<unsigned int>(ctrl_qubit),
805 static_cast<unsigned int>(tgt_qubit));
807 pp->ApplyCSX(
static_cast<unsigned int>(ctrl_qubit),
808 static_cast<unsigned int>(tgt_qubit));
810 QC::Gates::AppliedGate<> agate(csx.getRawOperatorMatrix(), tgt_qubit,
812 pathIntegralSimulator->ApplyGate(agate);
815 state->ApplyGate(csx,
static_cast<unsigned int>(tgt_qubit),
816 static_cast<unsigned int>(ctrl_qubit));
817 NotifyObservers({tgt_qubit, ctrl_qubit});
830 mpsSimulator->ApplyGate(csxdag,
static_cast<unsigned int>(tgt_qubit),
831 static_cast<unsigned int>(ctrl_qubit));
833 throw std::runtime_error(
834 "QCSimSimulator::ApplyCSxDAG: The stabilizer "
835 "simulator does not support the CSxDag gate.");
837 tensorNetwork->AddGate(csxdag,
static_cast<unsigned int>(ctrl_qubit),
838 static_cast<unsigned int>(tgt_qubit));
840 pp->ApplyCSXDAG(
static_cast<unsigned int>(ctrl_qubit),
841 static_cast<unsigned int>(tgt_qubit));
843 QC::Gates::AppliedGate<> agate(csxdag.getRawOperatorMatrix(), tgt_qubit,
845 pathIntegralSimulator->ApplyGate(agate);
848 state->ApplyGate(csxdag,
static_cast<unsigned int>(tgt_qubit),
849 static_cast<unsigned int>(ctrl_qubit));
850 NotifyObservers({tgt_qubit, ctrl_qubit});
862 mpsSimulator->ApplyGate(swapgate,
static_cast<unsigned int>(qubit1),
863 static_cast<unsigned int>(qubit0));
865 cliffordSimulator->ApplySwap(
static_cast<unsigned int>(qubit1),
866 static_cast<unsigned int>(qubit0));
868 tensorNetwork->AddGate(swapgate,
static_cast<unsigned int>(qubit0),
869 static_cast<unsigned int>(qubit1));
871 pp->ApplySWAP(
static_cast<unsigned int>(qubit0),
872 static_cast<unsigned int>(qubit1));
874 QC::Gates::AppliedGate<> agate(swapgate.getRawOperatorMatrix(), qubit1,
876 pathIntegralSimulator->ApplyGate(agate);
879 state->ApplyGate(swapgate,
static_cast<unsigned int>(qubit1),
880 static_cast<unsigned int>(qubit0));
881 NotifyObservers({qubit1, qubit0});
895 const size_t q1 = qubit0;
896 const size_t q2 = qubit1;
897 const size_t q3 = qubit2;
900 mpsSimulator->ApplyGate(csx,
static_cast<unsigned int>(q3),
901 static_cast<unsigned int>(q2));
902 NotifyObservers({qubit1, qubit2});
904 mpsSimulator->ApplyGate(cxgate,
static_cast<unsigned int>(q2),
905 static_cast<unsigned int>(q1));
906 NotifyObservers({qubit0, qubit1});
908 mpsSimulator->ApplyGate(csxdag,
static_cast<unsigned int>(q3),
909 static_cast<unsigned int>(q2));
910 NotifyObservers({qubit1, qubit2});
912 mpsSimulator->ApplyGate(cxgate,
static_cast<unsigned int>(q2),
913 static_cast<unsigned int>(q1));
914 NotifyObservers({qubit0, qubit1});
916 mpsSimulator->ApplyGate(csx,
static_cast<unsigned int>(q3),
917 static_cast<unsigned int>(q1));
918 NotifyObservers({qubit0, qubit2});
920 throw std::runtime_error(
921 "QCSimSimulator::ApplyCCX: The stabilizer "
922 "simulator does not support the CCX gate.");
924 const size_t q1 = qubit0;
925 const size_t q2 = qubit1;
926 const size_t q3 = qubit2;
929 tensorNetwork->AddGate(csx,
static_cast<unsigned int>(q2),
930 static_cast<unsigned int>(q3));
931 NotifyObservers({qubit1, qubit2});
933 tensorNetwork->AddGate(cxgate,
static_cast<unsigned int>(q1),
934 static_cast<unsigned int>(q2));
935 NotifyObservers({qubit0, qubit1});
937 tensorNetwork->AddGate(csxdag,
static_cast<unsigned int>(q2),
938 static_cast<unsigned int>(q3));
939 NotifyObservers({qubit1, qubit2});
941 tensorNetwork->AddGate(cxgate,
static_cast<unsigned int>(q1),
942 static_cast<unsigned int>(q2));
943 NotifyObservers({qubit0, qubit1});
945 tensorNetwork->AddGate(csx,
static_cast<unsigned int>(q1),
946 static_cast<unsigned int>(q3));
947 NotifyObservers({qubit0, qubit2});
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});
954 QC::Gates::AppliedGate<> agate(ccxgate.getRawOperatorMatrix(), qubit2,
956 pathIntegralSimulator->ApplyGate(agate);
957 NotifyObservers({qubit2, qubit1, qubit0});
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});
977 const size_t q1 = ctrl_qubit;
978 const size_t q2 = qubit0;
979 const size_t q3 = qubit1;
983 mpsSimulator->ApplyGate(cxgate,
static_cast<unsigned int>(q2),
984 static_cast<unsigned int>(q3));
985 NotifyObservers({qubit1, qubit0});
987 mpsSimulator->ApplyGate(csx,
static_cast<unsigned int>(q3),
988 static_cast<unsigned int>(q2));
989 NotifyObservers({qubit0, qubit1});
991 mpsSimulator->ApplyGate(cxgate,
static_cast<unsigned int>(q2),
992 static_cast<unsigned int>(q1));
993 NotifyObservers({ctrl_qubit, qubit0});
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});
1002 mpsSimulator->ApplyGate(csx,
static_cast<unsigned int>(q3),
1003 static_cast<unsigned int>(q2));
1004 NotifyObservers({qubit0, qubit1});
1006 mpsSimulator->ApplyGate(cxgate,
static_cast<unsigned int>(q2),
1007 static_cast<unsigned int>(q1));
1008 NotifyObservers({ctrl_qubit, qubit0});
1010 pgate.SetPhaseShift(M_PI);
1011 mpsSimulator->ApplyGate(pgate,
static_cast<unsigned int>(q3));
1012 NotifyObservers({qubit1});
1014 mpsSimulator->ApplyGate(csx,
static_cast<unsigned int>(q3),
1015 static_cast<unsigned int>(q1));
1016 NotifyObservers({ctrl_qubit, qubit1});
1018 mpsSimulator->ApplyGate(cxgate,
static_cast<unsigned int>(q2),
1019 static_cast<unsigned int>(q3));
1020 NotifyObservers({qubit1, qubit0});
1022 throw std::runtime_error(
1023 "QCSimSimulator::ApplyCSwap: The stabilizer "
1024 "simulator does not support the CSwap gate.");
1026 const size_t q1 = ctrl_qubit;
1027 const size_t q2 = qubit0;
1028 const size_t q3 = qubit1;
1032 tensorNetwork->AddGate(cxgate,
static_cast<unsigned int>(q3),
1033 static_cast<unsigned int>(q2));
1034 NotifyObservers({qubit1, qubit0});
1036 tensorNetwork->AddGate(csx,
static_cast<unsigned int>(q2),
1037 static_cast<unsigned int>(q3));
1038 NotifyObservers({qubit0, qubit1});
1040 tensorNetwork->AddGate(cxgate,
static_cast<unsigned int>(q1),
1041 static_cast<unsigned int>(q2));
1042 NotifyObservers({ctrl_qubit, qubit0});
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});
1051 tensorNetwork->AddGate(csx,
static_cast<unsigned int>(q2),
1052 static_cast<unsigned int>(q3));
1053 NotifyObservers({qubit0, qubit1});
1055 tensorNetwork->AddGate(cxgate,
static_cast<unsigned int>(q1),
1056 static_cast<unsigned int>(q2));
1057 NotifyObservers({ctrl_qubit, qubit0});
1059 pgate.SetPhaseShift(M_PI);
1060 tensorNetwork->AddGate(pgate,
static_cast<unsigned int>(q3));
1061 NotifyObservers({qubit1});
1063 tensorNetwork->AddGate(csx,
static_cast<unsigned int>(q1),
1064 static_cast<unsigned int>(q3));
1065 NotifyObservers({ctrl_qubit, qubit1});
1067 tensorNetwork->AddGate(cxgate,
static_cast<unsigned int>(q3),
1068 static_cast<unsigned int>(q2));
1069 NotifyObservers({qubit1, qubit0});
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});
1076 QC::Gates::AppliedGate<> agate(cswapgate.getRawOperatorMatrix(),
1077 qubit1, qubit0, ctrl_qubit);
1078 pathIntegralSimulator->ApplyGate(agate);
1079 NotifyObservers({qubit1, qubit0, ctrl_qubit});
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});
1100 double theta,
double phi,
double lambda,
double gamma)
override {
1101 cugate.SetParams(theta, phi, lambda, gamma);
1103 mpsSimulator->ApplyGate(cugate,
static_cast<unsigned int>(tgt_qubit),
1104 static_cast<unsigned int>(ctrl_qubit));
1106 throw std::runtime_error(
1107 "QCSimSimulator::ApplyCU: The stabilizer "
1108 "simulator does not support the CU gate.");
1110 tensorNetwork->AddGate(cugate,
static_cast<unsigned int>(ctrl_qubit),
1111 static_cast<unsigned int>(tgt_qubit));
1113 pp->ApplyCU(
static_cast<unsigned int>(ctrl_qubit),
1114 static_cast<unsigned int>(tgt_qubit), theta, phi, lambda,
1117 QC::Gates::AppliedGate<> agate(cugate.getRawOperatorMatrix(), tgt_qubit,
1119 pathIntegralSimulator->ApplyGate(agate);
1122 state->ApplyGate(cugate,
static_cast<unsigned int>(tgt_qubit),
1123 static_cast<unsigned int>(ctrl_qubit));
1124 NotifyObservers({tgt_qubit, ctrl_qubit});
1134 void ApplyNop()
override {
1148 std::unique_ptr<ISimulator> Clone()
override {
1149 auto cloned = std::make_unique<QCSimSimulator>();
1151 cloned->simulationType = simulationType;
1152 cloned->nrQubits = nrQubits;
1154 cloned->limitSize = limitSize;
1155 cloned->limitEntanglement = limitEntanglement;
1157 cloned->singularValueThreshold = singularValueThreshold;
1159 cloned->enableMultithreading = enableMultithreading;
1160 cloned->useMPSMeasureNoCollapse = useMPSMeasureNoCollapse;
1162 cloned->lookaheadDepth = lookaheadDepth;
1163 cloned->useOptimalMeetingPosition = useOptimalMeetingPosition;
1164 cloned->upcomingGates = upcomingGates;
1165 cloned->upcomingGateIndex = upcomingGateIndex;
1166 cloned->growthFactorGate = growthFactorGate;
1167 cloned->growthFactorSwap = growthFactorSwap;
1169 if (state) cloned->state = state->Clone();
1172 cloned->mpsSimulator = mpsSimulator->Clone();
1174 if (limitEntanglement && singularValueThreshold > 0.)
1175 cloned->mpsSimulator->setLimitEntanglement(singularValueThreshold);
1176 if (limitSize && chi > 0)
1177 cloned->mpsSimulator->setLimitBondDimension(chi);
1179 cloned->dummySim = dummySim ? dummySim->Clone() :
nullptr;
1181 cloned->gateCounterObserver =
1182 std::make_shared<GateCounterObserver>(upcomingGateIndex);
1183 cloned->RegisterObserver(cloned->gateCounterObserver);
1186 if (cliffordSimulator)
1187 cloned->cliffordSimulator = cliffordSimulator->Clone();
1189 if (tensorNetwork) cloned->tensorNetwork = tensorNetwork->Clone();
1191 if (pp) cloned->pp = pp->Clone();
1193 if (pathIntegralSimulator)
1194 cloned->pathIntegralSimulator = pathIntegralSimulator->Clone();
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;
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;
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.