20#ifdef INCLUDED_BY_FACTORY
24#include "QubitRegister.h"
35class IndividualSimulator;
47class AerState :
public ISimulator {
48 friend class IndividualSimulator;
58 std::random_device rd;
61 Configure(
"method",
"statevector");
71 void Initialize()
override {
73 if (simulationType == SimulationType::kMatrixProductState)
74 Configure(
"mps_sample_measure_algorithm", useMPSMeasureNoCollapse
76 :
"mps_apply_measure");
91 void InitializeState(
size_t num_qubits,
92 std::vector<std::complex<double>> &litudes)
override {
94 state->initialize_statevector(num_qubits, amplitudes.data(),
true);
128 void InitializeState(
size_t num_qubits,
129 AER::Vector<std::complex<double>> &litudes)
override {
131 state->initialize_statevector(num_qubits, amplitudes.move_to_buffer(),
146 void InitializeState(
size_t num_qubits,
147 Eigen::VectorXcd &litudes)
override {
149 state->initialize_statevector(num_qubits, amplitudes.data(),
true);
158 void Reset()
override {
173 void Configure(
const char *key,
const char *value)
override {
174 if (std::string(
"method") == key) {
175 if (std::string(
"statevector") == value)
176 simulationType = SimulationType::kStatevector;
177 else if (std::string(
"matrix_product_state") == value)
178 simulationType = SimulationType::kMatrixProductState;
179 else if (std::string(
"stabilizer") == value)
180 simulationType = SimulationType::kStabilizer;
181 else if (std::string(
"tensor_network") == value)
182 simulationType = SimulationType::kTensorNetwork;
184 simulationType = SimulationType::kOther;
185 }
else if (std::string(
"matrix_product_state_truncation_threshold") ==
187 singularValueThreshold = std::stod(value);
188 if (singularValueThreshold > 0.)
189 limitEntanglement =
true;
191 limitEntanglement =
false;
192 }
else if (std::string(
"matrix_product_state_max_bond_dimension") == key) {
193 chi = std::stoi(value);
198 }
else if (std::string(
"mps_sample_measure_algorithm") == key)
199 useMPSMeasureNoCollapse = std::string(
"mps_probabilities") == value;
201 state->configure(key, value);
212 if (std::string(
"method") == key) {
213 switch (simulationType) {
214 case SimulationType::kStatevector:
215 return "statevector";
216 case SimulationType::kMatrixProductState:
217 return "matrix_product_state";
218 case SimulationType::kStabilizer:
220 case SimulationType::kTensorNetwork:
221 return "tensor_network";
225 }
else if (std::string(
"matrix_product_state_truncation_threshold") ==
227 if (limitEntanglement && singularValueThreshold > 0.)
228 return std::to_string(singularValueThreshold);
229 }
else if (std::string(
"matrix_product_state_max_bond_dimension") == key) {
230 if (limitSize && limitSize > 0)
231 return std::to_string(chi);
232 }
else if (std::string(
"mps_sample_measure_algorithm") == key) {
233 return useMPSMeasureNoCollapse ?
"mps_probabilities"
234 :
"mps_apply_measure";
248 const auto ids = state->allocate_qubits(num_qubits);
259 if (state->is_initialized())
260 return state->num_of_qubits();
272 void Clear()
override {
276 if (simulationType == SimulationType::kMatrixProductState)
277 Configure(
"mps_sample_measure_algorithm", useMPSMeasureNoCollapse
278 ?
"mps_probabilities"
279 :
"mps_apply_measure");
290 const size_t res = state->apply_measure(qubits);
292 NotifyObservers(qubits);
304 state->apply_reset(qubits);
306 NotifyObservers(qubits);
321 return state->probability(outcome);
335 return state->amplitude(outcome);
349 return state->probabilities();
365 return state->probabilities(qubits);
384 std::unordered_map<Types::qubit_t, Types::qubit_t>
386 size_t shots = 1000)
override {
387 if (qubits.empty() || shots == 0)
390 const std::unordered_map<Types::qubit_t, Types::qubit_t> res =
391 state->sample_counts(qubits, shots);
393 NotifyObservers(qubits);
409 double ExpectationValue(
const std::string &pauliStringOrig)
override {
410 if (pauliStringOrig.empty())
413 std::string pauliString = pauliStringOrig;
416 const auto pauliOp = toupper(pauliString[i]);
417 if (pauliOp !=
'I' && pauliOp !=
'Z')
427 pauli.reserve(pauliString.size());
428 qubits.reserve(pauliString.size());
430 for (
size_t q = 0; q < pauliString.size(); ++q) {
431 const char p = toupper(pauliString[q]);
443 std::reverse(pauli.begin(), pauli.end());
445 return state->expval_pauli(qubits, pauli);
455 SimulatorType GetType()
const override {
return SimulatorType::kQiskitAer; }
475 void Flush()
override {
490 savedAmplitudes = state->move_to_vector();
500 const size_t numQubits =
static_cast<size_t>(log2(savedAmplitudes.size()));
501 state->initialize_statevector(numQubits, savedAmplitudes.move_to_buffer(),
519 if (simulationType == SimulationType::kStatevector) {
521 state->initialize_statevector(numQubits, savedAmplitudes.data(),
true);
527 if (state->is_initialized()) {
528 AER::Operations::Op op;
530 op.type = AER::Operations::OpType::save_state;
531 op.name =
"save_state";
532 op.save_type = AER::Operations::DataSubType::single;
533 op.string_params.push_back(
"s");
535 for (
size_t q = 0; q < numQubits; ++q)
536 op.qubits.push_back(q);
538 state->buffer_op(std::move(op));
542 AER::ExperimentResult &last_result = state->last_result();
544 if (last_result.status == AER::ExperimentResult::Status::completed) {
545 savedState = std::move(last_result.data);
550 AER::ExperimentResult &last_result_prev = state->last_result();
552 if (last_result_prev.status == AER::ExperimentResult::Status::completed) {
553 savedState = std::move(last_result_prev.data);
563 if (saved && simulationType == SimulationType::kMatrixProductState)
578 AER::Operations::Op op;
580 switch (simulationType) {
581 case SimulationType::kStatevector: {
590 numQubits =
static_cast<size_t>(log2(savedAmplitudes.size()));
591 state->initialize_statevector(numQubits, savedAmplitudes.data(),
true);
595 case SimulationType::kMatrixProductState:
596 op.type = AER::Operations::OpType::set_mps;
598 op.mps =
static_cast<AER::DataMap<AER::SingleData, AER::mps_container_t>
>(
616 numQubits = op.mps.first.size();
618 case SimulationType::kStabilizer:
619 op.type = AER::Operations::OpType::set_stabilizer;
620 op.name =
"set_stabilizer";
622 static_cast<AER::DataMap<AER::SingleData, json_t>
>(savedState)
639 numQubits = op.clifford.num_qubits();
641 case SimulationType::kTensorNetwork:
643 throw std::runtime_error(
"AerState::RestoreState: not implemented yet "
644 "for this type of simulator.");
647 op.save_type = AER::Operations::DataSubType::single;
648 op.string_params.push_back(
"s");
650 for (
size_t q = 0; q < numQubits; ++q)
651 op.qubits.push_back(q);
654 if (!state->is_initialized()) {
660 state->buffer_op(std::move(op));
671 std::complex<double> AmplitudeRaw(
Types::qubit_t outcome)
override {
672 return savedAmplitudes[outcome];
684 enableMultithreading = multithreading;
685 if (state && !state->is_initialized()) {
686 const std::string nrThreads =
687 std::to_string(enableMultithreading ? 0 : 1);
688 state->configure(
"max_parallel_threads", nrThreads);
689 state->configure(
"parallel_state_update", nrThreads);
690 const std::string threadsLimit = std::to_string(12);
691 state->configure(
"statevector_parallel_threshold", threadsLimit);
714 bool IsQcsim()
const override {
return false; }
730 if (simulationType == SimulationType::kStatevector) {
732 1. - uniformZeroOne(rng);
736 accum += std::norm(savedAmplitudes[i]);
746 throw std::runtime_error(
747 "AerState::MeasureNoCollapse: Invalid simulation type for measuring "
748 "all the qubits without collapsing the state.");
754 SimulationType simulationType =
755 SimulationType::kStatevector;
756 std::unique_ptr<QiskitAerState> state =
757 std::make_unique<QiskitAerState>();
758 AER::Vector<complex_t> savedAmplitudes;
759 bool limitSize =
false;
760 bool limitEntanglement =
false;
761 Eigen::Index chi = 10;
762 double singularValueThreshold = 0.;
763 bool enableMultithreading =
true;
764 AER::Data savedState;
767 std::uniform_real_distribution<double> uniformZeroOne{0., 1.};
768 bool useMPSMeasureNoCollapse =
double Probability(void *sim, unsigned long long int outcome)
char * GetConfiguration(void *sim, const char *key)
int RestoreState(void *sim)
int ApplyReset(void *sim, const unsigned long int *qubits, unsigned long int nrQubits)
unsigned long int AllocateQubits(void *sim, unsigned long int nrQubits)
unsigned long int GetNumberOfQubits(void *sim)
double * AllProbabilities(void *sim)
unsigned long long int MeasureNoCollapse(void *sim)
int GetMultithreading(void *sim)
unsigned long long int Measure(void *sim, const unsigned long int *qubits, unsigned long int nrQubits)
double * Amplitude(void *sim, unsigned long long int outcome)
double * Probabilities(void *sim, const unsigned long long int *qubits, unsigned long int nrQubits)
int SetMultithreading(void *sim, int multithreading)
int SaveStateToInternalDestructive(void *sim)
int GetSimulationType(void *sim)
unsigned long long int * SampleCounts(void *sim, const unsigned long long int *qubits, unsigned long int nrQubits, unsigned long int shots)
int RestoreInternalDestructiveSavedState(void *sim)
std::vector< qubit_t > qubits_vector
The type of a vector of qubits.
uint_fast64_t qubit_t
The type of a qubit.