15#ifndef _AER_SIMULATOR_H_
16#define _AER_SIMULATOR_H_
20#ifdef INCLUDED_BY_FACTORY
41class AerSimulator :
public AerState {
43 AerSimulator() =
default;
45 AerSimulator(
const AerSimulator &) =
delete;
46 AerSimulator &operator=(
const AerSimulator &) =
delete;
49 AerSimulator(AerSimulator &&other) =
default;
50 AerSimulator &operator=(AerSimulator &&other) =
default;
62 const AER::cvector_t P = {{1, 0}, std::polar(1., lambda)};
63 state->apply_diagonal_matrix(qubits, P);
65 NotifyObservers(qubits);
76 state->apply_x(qubit);
77 NotifyObservers(qubits);
88 state->apply_y(qubit);
89 NotifyObservers(qubits);
100 state->apply_z(qubit);
101 NotifyObservers(qubits);
112 state->apply_h(qubit);
113 NotifyObservers(qubits);
126 AER::Operations::Op op;
127 op.type = AER::Operations::OpType::gate;
129 op.qubits = AER::reg_t{qubit};
131 state->buffer_op(std::move(op));
133 const AER::cvector_t S = {{1, 0}, complex_t(0.0, 1)};
134 state->apply_diagonal_matrix(qubits, S);
137 NotifyObservers(qubits);
150 AER::Operations::Op op;
151 op.type = AER::Operations::OpType::gate;
153 op.qubits = AER::reg_t{qubit};
155 state->buffer_op(std::move(op));
157 const AER::cvector_t Sdg = {{1, 0}, complex_t(0.0, -1)};
158 state->apply_diagonal_matrix(qubits, Sdg);
161 NotifyObservers(qubits);
172 throw std::runtime_error(
"T gate not supported in stabilizer simulation");
177 const AER::cvector_t T = {{1, 0}, std::polar<double>(1, M_PI / 4.)};
178 state->apply_diagonal_matrix(qubits, T);
180 NotifyObservers(qubits);
191 throw std::runtime_error(
192 "TDG gate not supported in stabilizer simulation");
197 const AER::cvector_t Tdg = {{1, 0}, std::polar<double>(1, -M_PI / 4.)};
198 state->apply_diagonal_matrix(qubits, Tdg);
200 NotifyObservers(qubits);
213 AER::Operations::Op op;
214 op.type = AER::Operations::OpType::gate;
216 op.qubits = AER::reg_t{qubit};
218 state->buffer_op(std::move(op));
224 state->apply_unitary(qubits, AER::Linalg::Matrix::SX);
227 NotifyObservers(qubits);
240 AER::Operations::Op op;
241 op.type = AER::Operations::OpType::gate;
243 op.qubits = AER::reg_t{qubit};
245 state->buffer_op(std::move(op));
247 state->apply_unitary(qubits, AER::Linalg::Matrix::SXDG);
249 NotifyObservers(qubits);
267 static const cmatrix_t K = AER::Utils::make_matrix<complex_t>(
268 {{{1. / std::sqrt(2.), 0}, {0, -1. / std::sqrt(2.)}},
269 {{0, 1. / std::sqrt(2.)}, {-1. / std::sqrt(2.), 0}}});
271 state->apply_unitary(qubits, K);
274 NotifyObservers(qubits);
286 throw std::runtime_error(
287 "Rx gate not supported in stabilizer simulation");
290 const cmatrix_t rx = AER::Linalg::Matrix::rx(theta);
292 state->apply_unitary(qubits, rx);
294 NotifyObservers(qubits);
306 throw std::runtime_error(
307 "Ry gate not supported in stabilizer simulation");
310 const cmatrix_t ry = AER::Linalg::Matrix::ry(theta);
312 state->apply_unitary(qubits, ry);
314 NotifyObservers(qubits);
326 throw std::runtime_error(
327 "Rz gate not supported in stabilizer simulation");
330 const cmatrix_t rz = AER::Linalg::Matrix::rz(theta);
332 state->apply_unitary(qubits, rz);
334 NotifyObservers(qubits);
348 double gamma)
override {
350 throw std::runtime_error(
"U gate not supported in stabilizer simulation");
353 const cmatrix_t u = AER::Linalg::Matrix::u4(theta, phi, lambda, gamma);
355 state->apply_unitary(qubits, u);
357 NotifyObservers(qubits);
369 state->apply_cx(qubits);
370 NotifyObservers(qubits);
382 state->apply_cy(qubits);
383 NotifyObservers(qubits);
395 state->apply_cz(qubits);
396 NotifyObservers(qubits);
408 double lambda)
override {
410 throw std::runtime_error(
411 "CP gate not supported in stabilizer simulation");
414 const cmatrix_t CP = AER::Linalg::Matrix::cphase(lambda);
416 state->apply_unitary(qubits, CP);
418 NotifyObservers(qubits);
430 double theta)
override {
432 throw std::runtime_error(
433 "CRx gate not supported in stabilizer simulation");
441 const double t2 = theta * 0.5;
443 const complex_t i(0., 1.);
444 mat(1, 1) = std::cos(t2);
445 mat(1, 3) = -i * std::sin(t2);
446 mat(3, 1) = mat(1, 3);
447 mat(3, 3) = mat(1, 1);
450 state->apply_unitary(qubits, mat);
452 NotifyObservers(qubits);
464 double theta)
override {
466 throw std::runtime_error(
467 "CRy gate not supported in stabilizer simulation");
475 const double t2 = theta * 0.5;
477 mat(1, 1) = std::complex<double>(cos(t2), 0);
478 mat(1, 3) = std::complex<double>(-sin(t2), 0);
479 mat(3, 1) = std::complex<double>(sin(t2), 0);
480 mat(3, 3) = mat(1, 1);
483 state->apply_unitary(qubits, mat);
485 NotifyObservers(qubits);
497 double theta)
override {
499 throw std::runtime_error(
500 "CRz gate not supported in stabilizer simulation");
504 const double t2 = theta * 0.5;
506 {1, 0}, std::polar(1., -t2), {1, 0}, std::polar(1., t2)};
509 state->apply_diagonal_matrix(qubits, v);
511 NotifyObservers(qubits);
523 throw std::runtime_error(
524 "CH gate not supported in stabilizer simulation");
527 const cmatrix_t CU = AER::Linalg::Matrix::cu(M_PI_2, 0, M_PI, 0);
528 state->apply_unitary(qubits, CU);
531 NotifyObservers(qubits);
543 throw std::runtime_error(
544 "CSx gate not supported in stabilizer simulation");
546 static const cmatrix_t CSX = AER::Utils::make_matrix<complex_t>(
547 {{{1, 0}, {0, 0}, {0, 0}, {0, 0}},
548 {{0, 0}, {0.5, 0.5}, {0, 0}, {0.5, -0.5}},
549 {{0, 0}, {0, 0}, {1, 0}, {0, 0}},
550 {{0, 0}, {0.5, -0.5}, {0, 0}, {0.5, 0.5}}});
553 state->apply_unitary(qubits, CSX);
554 NotifyObservers(qubits);
567 throw std::runtime_error(
568 "CSxDAG gate not supported in stabilizer simulation");
570 static const cmatrix_t CSXDG = AER::Utils::make_matrix<complex_t>(
571 {{{1, 0}, {0, 0}, {0, 0}, {0, 0}},
572 {{0, 0}, {0.5, -0.5}, {0, 0}, {0.5, 0.5}},
573 {{0, 0}, {0, 0}, {1, 0}, {0, 0}},
574 {{0, 0}, {0.5, 0.5}, {0, 0}, {0.5, -0.5}}});
577 state->apply_unitary(qubits, CSXDG);
578 NotifyObservers(qubits);
592 AER::Operations::Op op;
593 op.type = AER::Operations::OpType::gate;
595 op.qubits = AER::reg_t{qubit0, qubit1};
597 state->buffer_op(std::move(op));
600 state->apply_unitary(qubits, AER::Linalg::Matrix::SWAP);
602 NotifyObservers(qubits);
616 throw std::runtime_error(
617 "CCX gate not supported in stabilizer simulation");
621 static const cmatrix_t mat = AER::Utils::make_matrix<complex_t>(
622 {{{1, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}},
623 {{0, 0}, {1, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}},
624 {{0, 0}, {0, 0}, {1, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}},
625 {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 0}},
626 {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 0}, {0, 0}, {0, 0}, {0, 0}},
627 {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 0}, {0, 0}, {0, 0}},
628 {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 0}, {0, 0}},
629 {{0, 0}, {0, 0}, {0, 0}, {1, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}});
632 state->apply_unitary(qubits, mat);
634 NotifyObservers(qubits);
648 throw std::runtime_error(
649 "CSwap gate not supported in stabilizer simulation");
653 static const cmatrix_t mat = AER::Utils::make_matrix<complex_t>(
654 {{{1, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}},
655 {{0, 0}, {1, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}},
656 {{0, 0}, {0, 0}, {1, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}},
657 {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 0}, {0, 0}, {0, 0}},
658 {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 0}, {0, 0}, {0, 0}, {0, 0}},
659 {{0, 0}, {0, 0}, {0, 0}, {1, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}},
660 {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 0}, {0, 0}},
661 {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 0}}});
664 state->apply_unitary(qubits, mat);
666 NotifyObservers(qubits);
681 double theta,
double phi,
double lambda,
double gamma)
override {
683 throw std::runtime_error(
684 "CU gate not supported in stabilizer simulation");
688 const cmatrix_t CU = AER::Linalg::Matrix::cu(theta, phi, lambda, gamma);
690 state->apply_unitary(qubits, CU);
692 NotifyObservers(qubits);
702 void ApplyNop()
override {
703 AER::Operations::Op op;
705 AER::Operations::OpType::barrier;
707 state->buffer_op(std::move(op));
720 std::unique_ptr<ISimulator> Clone()
override {
721 auto sim = std::make_unique<AerSimulator>();
724 if (simulationType == SimulationType::kMatrixProductState)
725 sim->Configure(
"method",
"matrix_product_state");
726 else if (simulationType == SimulationType::kStabilizer)
727 sim->Configure(
"method",
"stabilizer");
728 else if (simulationType == SimulationType::kTensorNetwork)
729 sim->Configure(
"method",
"tensor_network");
731 sim->Configure(
"method",
"statevector");
733 if (simulationType == SimulationType::kMatrixProductState) {
735 sim->Configure(
"matrix_product_state_max_bond_dimension",
736 std::to_string(chi).c_str());
737 if (limitEntanglement)
738 sim->Configure(
"matrix_product_state_truncation_threshold",
739 std::to_string(singularValueThreshold).c_str());
740 sim->Configure(
"mps_sample_measure_algorithm", useMPSMeasureNoCollapse
741 ?
"mps_probabilities"
742 :
"mps_apply_measure");
745 sim->SetMultithreading(
746 enableMultithreading);
748 AER::Vector<complex_t> localSavedAmplitudes =
750 AER::Data localSavedState =
755 if (state && state->is_initialized()) {
760 sim->savedAmplitudes = std::move(savedAmplitudes);
761 sim->savedState = std::move(savedState);
767 sim->savedAmplitudes = localSavedAmplitudes;
768 sim->savedState = localSavedState;
771 savedAmplitudes = std::move(localSavedAmplitudes);
772 savedState = std::move(localSavedState);
775 sim->savedAmplitudes = std::move(localSavedAmplitudes);
776 sim->savedState = std::move(localSavedState);
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.