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 void ApplyP(Types::qubit_t qubit,
double lambda)
override {
65 pgate.SetPhaseShift(lambda);
67 mpsSimulator->ApplyGate(pgate,
static_cast<unsigned int>(qubit));
69 if (std::abs(lambda - M_PI_2) > 1e-10)
70 throw std::runtime_error(
71 "QCSimSimulator::ApplyP: Invalid phase shift "
72 "angle for a Clifford gate.");
73 cliffordSimulator->ApplyS(
static_cast<unsigned int>(qubit));
75 tensorNetwork->AddGate(pgate,
static_cast<unsigned int>(qubit));
77 pp->ApplyP(
static_cast<unsigned int>(qubit), lambda);
79 state->ApplyGate(pgate,
static_cast<unsigned int>(qubit));
80 NotifyObservers({qubit});
89 void ApplyX(Types::qubit_t qubit)
override {
91 mpsSimulator->ApplyGate(xgate,
static_cast<unsigned int>(qubit));
93 cliffordSimulator->ApplyX(
static_cast<unsigned int>(qubit));
95 tensorNetwork->AddGate(xgate,
static_cast<unsigned int>(qubit));
97 pp->ApplyX(
static_cast<unsigned int>(qubit));
99 state->ApplyGate(xgate,
static_cast<unsigned int>(qubit));
100 NotifyObservers({qubit});
109 void ApplyY(Types::qubit_t qubit)
override {
111 mpsSimulator->ApplyGate(ygate,
static_cast<unsigned int>(qubit));
113 cliffordSimulator->ApplyY(
static_cast<unsigned int>(qubit));
115 tensorNetwork->AddGate(ygate,
static_cast<unsigned int>(qubit));
117 pp->ApplyY(
static_cast<unsigned int>(qubit));
119 state->ApplyGate(ygate,
static_cast<unsigned int>(qubit));
120 NotifyObservers({qubit});
129 void ApplyZ(Types::qubit_t qubit)
override {
131 mpsSimulator->ApplyGate(zgate,
static_cast<unsigned int>(qubit));
133 cliffordSimulator->ApplyZ(
static_cast<unsigned int>(qubit));
135 tensorNetwork->AddGate(zgate,
static_cast<unsigned int>(qubit));
137 pp->ApplyZ(
static_cast<unsigned int>(qubit));
139 state->ApplyGate(zgate,
static_cast<unsigned int>(qubit));
140 NotifyObservers({qubit});
149 void ApplyH(Types::qubit_t qubit)
override {
151 mpsSimulator->ApplyGate(h,
static_cast<unsigned int>(qubit));
153 cliffordSimulator->ApplyH(
static_cast<unsigned int>(qubit));
155 tensorNetwork->AddGate(h,
static_cast<unsigned int>(qubit));
157 pp->ApplyH(
static_cast<unsigned int>(qubit));
159 state->ApplyGate(h,
static_cast<unsigned int>(qubit));
160 NotifyObservers({qubit});
169 void ApplyS(Types::qubit_t qubit)
override {
171 mpsSimulator->ApplyGate(sgate,
static_cast<unsigned int>(qubit));
173 cliffordSimulator->ApplyS(
static_cast<unsigned int>(qubit));
175 tensorNetwork->AddGate(sgate,
static_cast<unsigned int>(qubit));
177 pp->ApplyS(
static_cast<unsigned int>(qubit));
179 state->ApplyGate(sgate,
static_cast<unsigned int>(qubit));
180 NotifyObservers({qubit});
189 void ApplySDG(Types::qubit_t qubit)
override {
191 mpsSimulator->ApplyGate(sdggate,
static_cast<unsigned int>(qubit));
193 cliffordSimulator->ApplySdg(
static_cast<unsigned int>(qubit));
195 tensorNetwork->AddGate(sdggate,
static_cast<unsigned int>(qubit));
197 pp->ApplySDG(
static_cast<unsigned int>(qubit));
199 state->ApplyGate(sdggate,
static_cast<unsigned int>(qubit));
200 NotifyObservers({qubit});
209 void ApplyT(Types::qubit_t qubit)
override {
211 mpsSimulator->ApplyGate(tgate,
static_cast<unsigned int>(qubit));
213 throw std::runtime_error(
214 "QCSimSimulator::ApplyT: The stabilizer simulator does not support "
215 "non-clifford gates.");
217 tensorNetwork->AddGate(tgate,
static_cast<unsigned int>(qubit));
219 pp->ApplyT(
static_cast<unsigned int>(qubit));
221 state->ApplyGate(tgate,
static_cast<unsigned int>(qubit));
222 NotifyObservers({qubit});
231 void ApplyTDG(Types::qubit_t qubit)
override {
233 mpsSimulator->ApplyGate(tdggate,
static_cast<unsigned int>(qubit));
235 throw std::runtime_error(
236 "QCSimSimulator::ApplyTDG: The stabilizer simulator does not support "
237 "non-clifford gates.");
239 tensorNetwork->AddGate(tdggate,
static_cast<unsigned int>(qubit));
241 pp->ApplyTDG(
static_cast<unsigned int>(qubit));
243 state->ApplyGate(tdggate,
static_cast<unsigned int>(qubit));
244 NotifyObservers({qubit});
253 void ApplySx(Types::qubit_t qubit)
override {
255 mpsSimulator->ApplyGate(sxgate,
static_cast<unsigned int>(qubit));
257 cliffordSimulator->ApplySx(
static_cast<unsigned int>(qubit));
259 tensorNetwork->AddGate(sxgate,
static_cast<unsigned int>(qubit));
261 pp->ApplySX(
static_cast<unsigned int>(qubit));
263 state->ApplyGate(sxgate,
static_cast<unsigned int>(qubit));
264 NotifyObservers({qubit});
273 void ApplySxDAG(Types::qubit_t qubit)
override {
275 mpsSimulator->ApplyGate(sxdaggate,
static_cast<unsigned int>(qubit));
277 cliffordSimulator->ApplySxDag(
static_cast<unsigned int>(qubit));
279 tensorNetwork->AddGate(sxdaggate,
static_cast<unsigned int>(qubit));
281 pp->ApplySXDG(
static_cast<unsigned int>(qubit));
283 state->ApplyGate(sxdaggate,
static_cast<unsigned int>(qubit));
284 NotifyObservers({qubit});
293 void ApplyK(Types::qubit_t qubit)
override {
295 mpsSimulator->ApplyGate(k,
static_cast<unsigned int>(qubit));
297 cliffordSimulator->ApplyK(
static_cast<unsigned int>(qubit));
299 tensorNetwork->AddGate(k,
static_cast<unsigned int>(qubit));
301 pp->ApplyK(
static_cast<unsigned int>(qubit));
303 state->ApplyGate(k,
static_cast<unsigned int>(qubit));
304 NotifyObservers({qubit});
314 void ApplyRx(Types::qubit_t qubit,
double theta)
override {
315 rxgate.SetTheta(theta);
317 mpsSimulator->ApplyGate(rxgate,
static_cast<unsigned int>(qubit));
319 throw std::runtime_error(
320 "QCSimSimulator::ApplyRx: The stabilizer "
321 "simulator does not support the Rx gate.");
323 tensorNetwork->AddGate(rxgate,
static_cast<unsigned int>(qubit));
325 pp->ApplyRX(
static_cast<unsigned int>(qubit), theta);
327 state->ApplyGate(rxgate,
static_cast<unsigned int>(qubit));
328 NotifyObservers({qubit});
338 void ApplyRy(Types::qubit_t qubit,
double theta)
override {
339 rygate.SetTheta(theta);
341 mpsSimulator->ApplyGate(rygate,
static_cast<unsigned int>(qubit));
343 throw std::runtime_error(
344 "QCSimSimulator::ApplyRy: The stabilizer "
345 "simulator does not support the Ry gate.");
347 tensorNetwork->AddGate(rygate,
static_cast<unsigned int>(qubit));
349 pp->ApplyRY(
static_cast<unsigned int>(qubit), theta);
351 state->ApplyGate(rygate,
static_cast<unsigned int>(qubit));
352 NotifyObservers({qubit});
362 void ApplyRz(Types::qubit_t qubit,
double theta)
override {
363 rzgate.SetTheta(theta);
365 mpsSimulator->ApplyGate(rzgate,
static_cast<unsigned int>(qubit));
367 throw std::runtime_error(
368 "QCSimSimulator::ApplyRz: The stabilizer "
369 "simulator does not support the Rz gate.");
371 tensorNetwork->AddGate(rzgate,
static_cast<unsigned int>(qubit));
373 pp->ApplyRZ(
static_cast<unsigned int>(qubit), theta);
375 state->ApplyGate(rzgate,
static_cast<unsigned int>(qubit));
376 NotifyObservers({qubit});
389 void ApplyU(Types::qubit_t qubit,
double theta,
double phi,
double lambda,
390 double gamma)
override {
391 ugate.SetParams(theta, phi, lambda, gamma);
393 mpsSimulator->ApplyGate(ugate,
static_cast<unsigned int>(qubit));
395 throw std::runtime_error(
396 "QCSimSimulator::ApplyU: The stabilizer "
397 "simulator does not support the U gate.");
399 tensorNetwork->AddGate(ugate,
static_cast<unsigned int>(qubit));
401 pp->ApplyU(
static_cast<unsigned int>(qubit), theta, phi, lambda, gamma);
403 state->ApplyGate(ugate,
static_cast<unsigned int>(qubit));
404 NotifyObservers({qubit});
414 void ApplyCX(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit)
override {
416 mpsSimulator->ApplyGate(cxgate,
static_cast<unsigned int>(tgt_qubit),
417 static_cast<unsigned int>(ctrl_qubit));
419 cliffordSimulator->ApplyCX(
static_cast<unsigned int>(tgt_qubit),
420 static_cast<unsigned int>(ctrl_qubit));
422 tensorNetwork->AddGate(cxgate,
static_cast<unsigned int>(ctrl_qubit),
423 static_cast<unsigned int>(tgt_qubit));
425 pp->ApplyCX(
static_cast<unsigned int>(ctrl_qubit),
426 static_cast<unsigned int>(tgt_qubit));
428 state->ApplyGate(cxgate,
static_cast<unsigned int>(tgt_qubit),
429 static_cast<unsigned int>(ctrl_qubit));
430 NotifyObservers({tgt_qubit, ctrl_qubit});
440 void ApplyCY(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit)
override {
442 mpsSimulator->ApplyGate(cygate,
static_cast<unsigned int>(tgt_qubit),
443 static_cast<unsigned int>(ctrl_qubit));
445 cliffordSimulator->ApplyCY(
static_cast<unsigned int>(tgt_qubit),
446 static_cast<unsigned int>(ctrl_qubit));
448 tensorNetwork->AddGate(cygate,
static_cast<unsigned int>(ctrl_qubit),
449 static_cast<unsigned int>(tgt_qubit));
451 pp->ApplyCY(
static_cast<unsigned int>(ctrl_qubit),
452 static_cast<unsigned int>(tgt_qubit));
454 state->ApplyGate(cygate,
static_cast<unsigned int>(tgt_qubit),
455 static_cast<unsigned int>(ctrl_qubit));
456 NotifyObservers({tgt_qubit, ctrl_qubit});
466 void ApplyCZ(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit)
override {
468 mpsSimulator->ApplyGate(czgate,
static_cast<unsigned int>(tgt_qubit),
469 static_cast<unsigned int>(ctrl_qubit));
471 cliffordSimulator->ApplyCZ(
static_cast<unsigned int>(tgt_qubit),
472 static_cast<unsigned int>(ctrl_qubit));
474 tensorNetwork->AddGate(czgate,
static_cast<unsigned int>(ctrl_qubit),
475 static_cast<unsigned int>(tgt_qubit));
477 pp->ApplyCZ(
static_cast<unsigned int>(ctrl_qubit),
478 static_cast<unsigned int>(tgt_qubit));
480 state->ApplyGate(czgate,
static_cast<unsigned int>(tgt_qubit),
481 static_cast<unsigned int>(ctrl_qubit));
482 NotifyObservers({tgt_qubit, ctrl_qubit});
493 void ApplyCP(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit,
494 double lambda)
override {
495 cpgate.SetPhaseShift(lambda);
497 mpsSimulator->ApplyGate(cpgate,
static_cast<unsigned int>(tgt_qubit),
498 static_cast<unsigned int>(ctrl_qubit));
500 throw std::runtime_error(
501 "QCSimSimulator::ApplyCP: The stabilizer "
502 "simulator does not support the CP gate.");
504 tensorNetwork->AddGate(cpgate,
static_cast<unsigned int>(ctrl_qubit),
505 static_cast<unsigned int>(tgt_qubit));
507 pp->ApplyCP(
static_cast<unsigned int>(ctrl_qubit),
508 static_cast<unsigned int>(tgt_qubit), lambda);
510 state->ApplyGate(cpgate,
static_cast<unsigned int>(tgt_qubit),
511 static_cast<unsigned int>(ctrl_qubit));
512 NotifyObservers({tgt_qubit, ctrl_qubit});
523 void ApplyCRx(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit,
524 double theta)
override {
525 crxgate.SetTheta(theta);
527 mpsSimulator->ApplyGate(crxgate,
static_cast<unsigned int>(tgt_qubit),
528 static_cast<unsigned int>(ctrl_qubit));
530 throw std::runtime_error(
531 "QCSimSimulator::ApplyCRx: The stabilizer "
532 "simulator does not support the CRx gate.");
534 tensorNetwork->AddGate(crxgate,
static_cast<unsigned int>(ctrl_qubit),
535 static_cast<unsigned int>(tgt_qubit));
537 pp->ApplyCRX(
static_cast<unsigned int>(ctrl_qubit),
538 static_cast<unsigned int>(tgt_qubit), theta);
540 state->ApplyGate(crxgate,
static_cast<unsigned int>(tgt_qubit),
541 static_cast<unsigned int>(ctrl_qubit));
542 NotifyObservers({tgt_qubit, ctrl_qubit});
553 void ApplyCRy(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit,
554 double theta)
override {
555 crygate.SetTheta(theta);
557 mpsSimulator->ApplyGate(crygate,
static_cast<unsigned int>(tgt_qubit),
558 static_cast<unsigned int>(ctrl_qubit));
560 throw std::runtime_error(
561 "QCSimSimulator::ApplyCRy: The stabilizer "
562 "simulator does not support the CRy gate.");
564 tensorNetwork->AddGate(crygate,
static_cast<unsigned int>(ctrl_qubit),
565 static_cast<unsigned int>(tgt_qubit));
567 pp->ApplyCRY(
static_cast<unsigned int>(ctrl_qubit),
568 static_cast<unsigned int>(tgt_qubit), theta);
570 state->ApplyGate(crygate,
static_cast<unsigned int>(tgt_qubit),
571 static_cast<unsigned int>(ctrl_qubit));
572 NotifyObservers({tgt_qubit, ctrl_qubit});
583 void ApplyCRz(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit,
584 double theta)
override {
585 crzgate.SetTheta(theta);
587 mpsSimulator->ApplyGate(crzgate,
static_cast<unsigned int>(tgt_qubit),
588 static_cast<unsigned int>(ctrl_qubit));
590 throw std::runtime_error(
591 "QCSimSimulator::ApplyCRz: The stabilizer "
592 "simulator does not support the CRz gate.");
594 tensorNetwork->AddGate(crzgate,
static_cast<unsigned int>(ctrl_qubit),
595 static_cast<unsigned int>(tgt_qubit));
597 pp->ApplyCRZ(
static_cast<unsigned int>(ctrl_qubit),
598 static_cast<unsigned int>(tgt_qubit), theta);
600 state->ApplyGate(crzgate,
static_cast<unsigned int>(tgt_qubit),
601 static_cast<unsigned int>(ctrl_qubit));
602 NotifyObservers({tgt_qubit, ctrl_qubit});
612 void ApplyCH(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit)
override {
614 mpsSimulator->ApplyGate(ch,
static_cast<unsigned int>(tgt_qubit),
615 static_cast<unsigned int>(ctrl_qubit));
617 throw std::runtime_error(
618 "QCSimSimulator::ApplyCH: The stabilizer "
619 "simulator does not support the CH gate.");
621 tensorNetwork->AddGate(ch,
static_cast<unsigned int>(ctrl_qubit),
622 static_cast<unsigned int>(tgt_qubit));
624 pp->ApplyCH(
static_cast<unsigned int>(ctrl_qubit),
625 static_cast<unsigned int>(tgt_qubit));
627 state->ApplyGate(ch,
static_cast<unsigned int>(tgt_qubit),
628 static_cast<unsigned int>(ctrl_qubit));
629 NotifyObservers({tgt_qubit, ctrl_qubit});
639 void ApplyCSx(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit)
override {
641 mpsSimulator->ApplyGate(csx,
static_cast<unsigned int>(tgt_qubit),
642 static_cast<unsigned int>(ctrl_qubit));
644 throw std::runtime_error(
645 "QCSimSimulator::ApplyCSx: The stabilizer "
646 "simulator does not support the CSx gate.");
648 tensorNetwork->AddGate(csx,
static_cast<unsigned int>(ctrl_qubit),
649 static_cast<unsigned int>(tgt_qubit));
651 pp->ApplyCSX(
static_cast<unsigned int>(ctrl_qubit),
652 static_cast<unsigned int>(tgt_qubit));
654 state->ApplyGate(csx,
static_cast<unsigned int>(tgt_qubit),
655 static_cast<unsigned int>(ctrl_qubit));
656 NotifyObservers({tgt_qubit, ctrl_qubit});
666 void ApplyCSxDAG(Types::qubit_t ctrl_qubit,
667 Types::qubit_t tgt_qubit)
override {
669 mpsSimulator->ApplyGate(csxdag,
static_cast<unsigned int>(tgt_qubit),
670 static_cast<unsigned int>(ctrl_qubit));
672 throw std::runtime_error(
673 "QCSimSimulator::ApplyCSxDAG: The stabilizer "
674 "simulator does not support the CSxDag gate.");
676 tensorNetwork->AddGate(csxdag,
static_cast<unsigned int>(ctrl_qubit),
677 static_cast<unsigned int>(tgt_qubit));
679 pp->ApplyCSXDAG(
static_cast<unsigned int>(ctrl_qubit),
680 static_cast<unsigned int>(tgt_qubit));
682 state->ApplyGate(csxdag,
static_cast<unsigned int>(tgt_qubit),
683 static_cast<unsigned int>(ctrl_qubit));
684 NotifyObservers({tgt_qubit, ctrl_qubit});
694 void ApplySwap(Types::qubit_t qubit0, Types::qubit_t qubit1)
override {
696 mpsSimulator->ApplyGate(swapgate,
static_cast<unsigned int>(qubit1),
697 static_cast<unsigned int>(qubit0));
699 cliffordSimulator->ApplySwap(
static_cast<unsigned int>(qubit1),
700 static_cast<unsigned int>(qubit0));
702 tensorNetwork->AddGate(swapgate,
static_cast<unsigned int>(qubit0),
703 static_cast<unsigned int>(qubit1));
705 pp->ApplySWAP(
static_cast<unsigned int>(qubit0),
706 static_cast<unsigned int>(qubit1));
708 state->ApplyGate(swapgate,
static_cast<unsigned int>(qubit1),
709 static_cast<unsigned int>(qubit0));
710 NotifyObservers({qubit1, qubit0});
721 void ApplyCCX(Types::qubit_t qubit0, Types::qubit_t qubit1,
722 Types::qubit_t qubit2)
override {
724 const size_t q1 = qubit0;
725 const size_t q2 = qubit1;
726 const size_t q3 = qubit2;
729 mpsSimulator->ApplyGate(csx,
static_cast<unsigned int>(q3),
730 static_cast<unsigned int>(q2));
731 mpsSimulator->ApplyGate(cxgate,
static_cast<unsigned int>(q2),
732 static_cast<unsigned int>(q1));
733 mpsSimulator->ApplyGate(csxdag,
static_cast<unsigned int>(q3),
734 static_cast<unsigned int>(q2));
735 mpsSimulator->ApplyGate(cxgate,
static_cast<unsigned int>(q2),
736 static_cast<unsigned int>(q1));
737 mpsSimulator->ApplyGate(csx,
static_cast<unsigned int>(q3),
738 static_cast<unsigned int>(q1));
740 throw std::runtime_error(
741 "QCSimSimulator::ApplyCCX: The stabilizer "
742 "simulator does not support the CCX gate.");
744 const size_t q1 = qubit0;
745 const size_t q2 = qubit1;
746 const size_t q3 = qubit2;
749 tensorNetwork->AddGate(csx,
static_cast<unsigned int>(q2),
750 static_cast<unsigned int>(q3));
751 tensorNetwork->AddGate(cxgate,
static_cast<unsigned int>(q1),
752 static_cast<unsigned int>(q2));
753 tensorNetwork->AddGate(csxdag,
static_cast<unsigned int>(q2),
754 static_cast<unsigned int>(q3));
755 tensorNetwork->AddGate(cxgate,
static_cast<unsigned int>(q1),
756 static_cast<unsigned int>(q2));
757 tensorNetwork->AddGate(csx,
static_cast<unsigned int>(q1),
758 static_cast<unsigned int>(q3));
760 pp->ApplyCCX(
static_cast<unsigned int>(qubit0),
761 static_cast<unsigned int>(qubit1),
762 static_cast<unsigned int>(qubit2));
764 state->ApplyGate(ccxgate,
static_cast<unsigned int>(qubit2),
765 static_cast<unsigned int>(qubit1),
766 static_cast<unsigned int>(qubit0));
767 NotifyObservers({qubit2, qubit1, qubit0});
778 void ApplyCSwap(Types::qubit_t ctrl_qubit, Types::qubit_t qubit0,
779 Types::qubit_t qubit1)
override {
781 const size_t q1 = ctrl_qubit;
782 const size_t q2 = qubit0;
783 const size_t q3 = qubit1;
787 mpsSimulator->ApplyGate(cxgate,
static_cast<unsigned int>(q2),
788 static_cast<unsigned int>(q3));
789 mpsSimulator->ApplyGate(csx,
static_cast<unsigned int>(q3),
790 static_cast<unsigned int>(q2));
791 mpsSimulator->ApplyGate(cxgate,
static_cast<unsigned int>(q2),
792 static_cast<unsigned int>(q1));
794 pgate.SetPhaseShift(M_PI);
795 mpsSimulator->ApplyGate(pgate,
static_cast<unsigned int>(q3));
796 pgate.SetPhaseShift(-M_PI_2);
797 mpsSimulator->ApplyGate(pgate,
static_cast<unsigned int>(q2));
799 mpsSimulator->ApplyGate(csx,
static_cast<unsigned int>(q3),
800 static_cast<unsigned int>(q2));
801 mpsSimulator->ApplyGate(cxgate,
static_cast<unsigned int>(q2),
802 static_cast<unsigned int>(q1));
804 pgate.SetPhaseShift(M_PI);
805 mpsSimulator->ApplyGate(pgate,
static_cast<unsigned int>(q3));
807 mpsSimulator->ApplyGate(csx,
static_cast<unsigned int>(q3),
808 static_cast<unsigned int>(q1));
809 mpsSimulator->ApplyGate(cxgate,
static_cast<unsigned int>(q2),
810 static_cast<unsigned int>(q3));
812 throw std::runtime_error(
813 "QCSimSimulator::ApplyCSwap: The stabilizer "
814 "simulator does not support the CSwap gate.");
816 const size_t q1 = ctrl_qubit;
817 const size_t q2 = qubit0;
818 const size_t q3 = qubit1;
822 tensorNetwork->AddGate(cxgate,
static_cast<unsigned int>(q3),
823 static_cast<unsigned int>(q2));
824 tensorNetwork->AddGate(csx,
static_cast<unsigned int>(q2),
825 static_cast<unsigned int>(q3));
826 tensorNetwork->AddGate(cxgate,
static_cast<unsigned int>(q1),
827 static_cast<unsigned int>(q2));
829 pgate.SetPhaseShift(M_PI);
830 tensorNetwork->AddGate(pgate,
static_cast<unsigned int>(q3));
831 pgate.SetPhaseShift(-M_PI_2);
832 tensorNetwork->AddGate(pgate,
static_cast<unsigned int>(q2));
834 tensorNetwork->AddGate(csx,
static_cast<unsigned int>(q2),
835 static_cast<unsigned int>(q3));
836 tensorNetwork->AddGate(cxgate,
static_cast<unsigned int>(q1),
837 static_cast<unsigned int>(q2));
839 pgate.SetPhaseShift(M_PI);
840 tensorNetwork->AddGate(pgate,
static_cast<unsigned int>(q3));
842 tensorNetwork->AddGate(csx,
static_cast<unsigned int>(q1),
843 static_cast<unsigned int>(q3));
844 tensorNetwork->AddGate(cxgate,
static_cast<unsigned int>(q3),
845 static_cast<unsigned int>(q2));
847 pp->ApplyCSwap(
static_cast<unsigned int>(ctrl_qubit),
848 static_cast<unsigned int>(qubit0),
849 static_cast<unsigned int>(qubit1));
851 state->ApplyGate(cswapgate,
static_cast<unsigned int>(qubit1),
852 static_cast<unsigned int>(qubit0),
853 static_cast<unsigned int>(ctrl_qubit));
854 NotifyObservers({qubit1, qubit0, ctrl_qubit});
868 void ApplyCU(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit,
869 double theta,
double phi,
double lambda,
double gamma)
override {
870 cugate.SetParams(theta, phi, lambda, gamma);
872 mpsSimulator->ApplyGate(cugate,
static_cast<unsigned int>(tgt_qubit),
873 static_cast<unsigned int>(ctrl_qubit));
875 throw std::runtime_error(
876 "QCSimSimulator::ApplyCU: The stabilizer "
877 "simulator does not support the CU gate.");
879 tensorNetwork->AddGate(cugate,
static_cast<unsigned int>(ctrl_qubit),
880 static_cast<unsigned int>(tgt_qubit));
882 pp->ApplyCU(
static_cast<unsigned int>(ctrl_qubit),
883 static_cast<unsigned int>(tgt_qubit), theta, phi, lambda,
886 state->ApplyGate(cugate,
static_cast<unsigned int>(tgt_qubit),
887 static_cast<unsigned int>(ctrl_qubit));
888 NotifyObservers({tgt_qubit, ctrl_qubit});
898 void ApplyNop()
override {
912 std::unique_ptr<ISimulator> Clone()
override {
913 auto cloned = std::make_unique<QCSimSimulator>();
915 cloned->simulationType = simulationType;
916 cloned->nrQubits = nrQubits;
918 cloned->limitSize = limitSize;
919 cloned->limitEntanglement = limitEntanglement;
921 cloned->singularValueThreshold = singularValueThreshold;
923 cloned->enableMultithreading = enableMultithreading;
924 cloned->useMPSMeasureNoCollapse = useMPSMeasureNoCollapse;
926 if (state) cloned->state = state->Clone();
929 cloned->mpsSimulator = mpsSimulator->Clone();
931 if (limitEntanglement && singularValueThreshold > 0.)
932 cloned->mpsSimulator->setLimitEntanglement(singularValueThreshold);
933 if (limitSize && chi > 0)
934 cloned->mpsSimulator->setLimitBondDimension(chi);
937 if (cliffordSimulator)
938 cloned->cliffordSimulator = cliffordSimulator->Clone();
940 if (tensorNetwork) cloned->tensorNetwork = tensorNetwork->Clone();
942 if (pp) cloned->pp = std::move(pp->Clone());
948 QC::Gates::PhaseShiftGate<> pgate;
949 QC::Gates::PauliXGate<> xgate;
950 QC::Gates::PauliYGate<> ygate;
951 QC::Gates::PauliZGate<> zgate;
952 QC::Gates::HadamardGate<> h;
954 QC::Gates::SGate<> sgate;
955 QC::Gates::SDGGate<> sdggate;
956 QC::Gates::TGate<> tgate;
957 QC::Gates::TDGGate<> tdggate;
958 QC::Gates::SquareRootNOTGate<> sxgate;
959 QC::Gates::SquareRootNOTDagGate<> sxdaggate;
960 QC::Gates::HyGate<> k;
961 QC::Gates::RxGate<> rxgate;
962 QC::Gates::RyGate<> rygate;
963 QC::Gates::RzGate<> rzgate;
964 QC::Gates::UGate<> ugate;
965 QC::Gates::CNOTGate<> cxgate;
966 QC::Gates::ControlledYGate<> cygate;
967 QC::Gates::ControlledZGate<> czgate;
968 QC::Gates::ControlledPhaseShiftGate<> cpgate;
969 QC::Gates::ControlledRxGate<> crxgate;
970 QC::Gates::ControlledRyGate<> crygate;
971 QC::Gates::ControlledRzGate<> crzgate;
972 QC::Gates::ControlledHadamardGate<> ch;
973 QC::Gates::ControlledSquareRootNOTGate<> csx;
974 QC::Gates::ControlledSquareRootNOTDagGate<> csxdag;
975 QC::Gates::SwapGate<> swapgate;
976 QC::Gates::ToffoliGate<> ccxgate;
977 QC::Gates::FredkinGate<> cswapgate;
978 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)