20#ifdef INCLUDED_BY_FACTORY
27#include "QubitRegister.h"
38class IndividualSimulator;
50class AerState :
public ISimulator {
51 friend class IndividualSimulator;
61 std::random_device rd;
64 Configure(
"method",
"statevector");
74 void Initialize()
override {
76 if (simulationType == SimulationType::kMatrixProductState)
77 Configure(
"mps_sample_measure_algorithm", useMPSMeasureNoCollapse
79 :
"mps_apply_measure");
94 void InitializeState(
size_t num_qubits,
95 std::vector<std::complex<double>> &litudes)
override {
97 state->initialize_statevector(num_qubits, amplitudes.data(),
true);
131 void InitializeState(
size_t num_qubits,
132 AER::Vector<std::complex<double>> &litudes)
override {
134 state->initialize_statevector(num_qubits, amplitudes.move_to_buffer(),
149 void InitializeState(
size_t num_qubits,
150 Eigen::VectorXcd &litudes)
override {
152 state->initialize_statevector(num_qubits, amplitudes.data(),
true);
161 void Reset()
override {
176 void Configure(
const char *key,
const char *value)
override {
177 if (std::string(
"method") == key) {
178 if (std::string(
"statevector") == value)
179 simulationType = SimulationType::kStatevector;
180 else if (std::string(
"matrix_product_state") == value)
181 simulationType = SimulationType::kMatrixProductState;
182 else if (std::string(
"stabilizer") == value)
183 simulationType = SimulationType::kStabilizer;
184 else if (std::string(
"tensor_network") == value)
185 simulationType = SimulationType::kTensorNetwork;
186 else if (std::string(
"extended_stabilizer") == value)
187 simulationType = SimulationType::kExtendedStabilizer;
189 simulationType = SimulationType::kOther;
190 }
else if (std::string(
"matrix_product_state_truncation_threshold") ==
192 singularValueThreshold = std::stod(value);
193 if (singularValueThreshold > 0.)
194 limitEntanglement =
true;
196 limitEntanglement =
false;
197 }
else if (std::string(
"matrix_product_state_max_bond_dimension") == key) {
198 chi = std::stoi(value);
203 }
else if (std::string(
"mps_sample_measure_algorithm") == key)
204 useMPSMeasureNoCollapse = std::string(
"mps_probabilities") == value;
206 state->configure(key, value);
217 if (std::string(
"method") == key) {
218 switch (simulationType) {
219 case SimulationType::kStatevector:
220 return "statevector";
221 case SimulationType::kMatrixProductState:
222 return "matrix_product_state";
223 case SimulationType::kStabilizer:
225 case SimulationType::kTensorNetwork:
226 return "tensor_network";
227 case SimulationType::kExtendedStabilizer:
228 return "extended_stabilizer";
232 }
else if (std::string(
"matrix_product_state_truncation_threshold") ==
234 if (limitEntanglement && singularValueThreshold > 0.) {
235 std::ostringstream oss;
236 oss << std::setprecision(std::numeric_limits<double>::max_digits10)
237 << singularValueThreshold;
240 }
else if (std::string(
"matrix_product_state_max_bond_dimension") == key) {
241 if (limitSize && limitSize > 0)
return std::to_string(chi);
242 }
else if (std::string(
"mps_sample_measure_algorithm") == key) {
243 return useMPSMeasureNoCollapse ?
"mps_probabilities"
244 :
"mps_apply_measure";
258 const auto ids = state->allocate_qubits(num_qubits);
269 if (state->is_initialized())
return state->num_of_qubits();
281 void Clear()
override {
285 if (simulationType == SimulationType::kMatrixProductState)
286 Configure(
"mps_sample_measure_algorithm", useMPSMeasureNoCollapse
287 ?
"mps_probabilities"
288 :
"mps_apply_measure");
302 if (qubits.size() >
sizeof(
size_t) * 8)
304 <<
"Warning: The number of qubits to measure is larger than the "
305 "number of bits in the size_t type, the outcome will be undefined"
308 const size_t res = state->apply_measure(qubits);
310 NotifyObservers(qubits);
322 auto res = state->apply_measure_many(qubits);
324 NotifyObservers(qubits);
336 state->apply_reset(qubits);
338 NotifyObservers(qubits);
353 return state->probability(outcome);
367 return state->amplitude(outcome);
383 std::complex<double> ProjectOnZero()
override {
399 return state->probabilities();
415 return state->probabilities(qubits);
434 std::unordered_map<Types::qubit_t, Types::qubit_t>
SampleCounts(
436 if (qubits.empty() || shots == 0)
return {};
440 <<
"Warning: The number of qubits to measure is larger than the "
441 "number of bits in the Types::qubit_t type, the outcome will be "
445 std::unordered_map<Types::qubit_t, Types::qubit_t> res =
446 state->sample_counts(qubits, shots);
448 NotifyObservers(qubits);
466 std::unordered_map<std::vector<bool>,
Types::qubit_t> SampleCountsMany(
468 if (qubits.empty() || shots == 0)
return {};
470 state->sample_counts_many(qubits, shots);
471 NotifyObservers(qubits);
486 double ExpectationValue(
const std::string &pauliStringOrig)
override {
487 if (pauliStringOrig.empty())
return 1.0;
489 std::string pauliString = pauliStringOrig;
492 const auto pauliOp = toupper(pauliString[i]);
493 if (pauliOp !=
'I' && pauliOp !=
'Z')
return 0.0;
502 pauli.reserve(pauliString.size());
503 qubits.reserve(pauliString.size());
505 for (
size_t q = 0; q < pauliString.size(); ++q) {
506 const char p = toupper(pauliString[q]);
507 if (p ==
'I')
continue;
513 if (qubits.empty())
return 1.0;
516 std::reverse(pauli.begin(), pauli.end());
518 return state->expval_pauli(qubits, pauli);
528 SimulatorType GetType()
const override {
return SimulatorType::kQiskitAer; }
548 void Flush()
override {
563 savedAmplitudes = state->move_to_vector();
573 const size_t numQubits =
static_cast<size_t>(log2(savedAmplitudes.size()));
574 state->initialize_statevector(numQubits, savedAmplitudes.move_to_buffer(),
591 if (simulationType == SimulationType::kStatevector) {
593 state->initialize_statevector(numQubits, savedAmplitudes.data(),
true);
599 if (state->is_initialized()) {
600 AER::Operations::Op op;
602 op.type = AER::Operations::OpType::save_state;
603 op.name =
"save_state";
604 op.save_type = AER::Operations::DataSubType::single;
605 op.string_params.push_back(
"s");
607 for (
size_t q = 0; q < numQubits; ++q) op.qubits.push_back(q);
609 state->buffer_op(std::move(op));
613 AER::ExperimentResult &last_result = state->last_result();
615 if (last_result.status == AER::ExperimentResult::Status::completed) {
616 savedState = std::move(last_result.data);
621 AER::ExperimentResult &last_result_prev = state->last_result();
623 if (last_result_prev.status == AER::ExperimentResult::Status::completed) {
624 savedState = std::move(last_result_prev.data);
634 if (saved && simulationType == SimulationType::kMatrixProductState)
649 AER::Operations::Op op;
651 switch (simulationType) {
652 case SimulationType::kStatevector: {
661 numQubits =
static_cast<size_t>(log2(savedAmplitudes.size()));
662 state->initialize_statevector(numQubits, savedAmplitudes.data(),
true);
666 case SimulationType::kMatrixProductState:
667 op.type = AER::Operations::OpType::set_mps;
670 static_cast<AER::DataMap<AER::SingleData, AER::mps_container_t>
>(
688 numQubits = op.mps.first.size();
690 case SimulationType::kStabilizer:
691 op.type = AER::Operations::OpType::set_stabilizer;
692 op.name =
"set_stabilizer";
694 static_cast<AER::DataMap<AER::SingleData, json_t>
>(savedState)
711 numQubits = op.clifford.num_qubits();
713 case SimulationType::kTensorNetwork:
715 throw std::runtime_error(
716 "AerState::RestoreState: not implemented yet "
717 "for this type of simulator.");
720 op.save_type = AER::Operations::DataSubType::single;
721 op.string_params.push_back(
"s");
723 for (
size_t q = 0; q < numQubits; ++q) op.qubits.push_back(q);
726 if (!state->is_initialized()) {
732 state->buffer_op(std::move(op));
743 std::complex<double> AmplitudeRaw(
Types::qubit_t outcome)
override {
744 return savedAmplitudes[outcome];
756 enableMultithreading = multithreading;
757 if (state && !state->is_initialized()) {
758 const std::string nrThreads =
759 std::to_string(enableMultithreading
762 state->configure(
"max_parallel_threads", nrThreads);
763 state->configure(
"parallel_state_update", nrThreads);
764 const std::string threadsLimit =
767 state->configure(
"statevector_parallel_threshold", threadsLimit);
790 bool IsQcsim()
const override {
return false; }
809 if (simulationType == SimulationType::kStatevector) {
811 1. - uniformZeroOne(rng);
815 accum += std::norm(savedAmplitudes[i]);
825 throw std::runtime_error(
826 "AerState::MeasureNoCollapse: Invalid simulation type for measuring "
827 "all the qubits without collapsing the state.");
846 std::vector<bool> MeasureNoCollapseMany()
override {
847 if (simulationType == SimulationType::kStatevector) {
848 const size_t numQubits =
849 static_cast<size_t>(log2(savedAmplitudes.size()));
850 std::vector<bool> res(numQubits,
false);
854 for (
size_t i = 0; i < numQubits; ++i) {
855 if ((state & 1) == 1) res[i] =
true;
861 throw std::runtime_error(
862 "AerState::MeasureNoCollapseMany: Invalid simulation type for "
864 "all the qubits without collapsing the state.");
870 SimulationType simulationType =
871 SimulationType::kStatevector;
872 std::unique_ptr<QiskitAerState> state =
873 std::make_unique<QiskitAerState>();
874 AER::Vector<complex_t> savedAmplitudes;
875 bool limitSize =
false;
876 bool limitEntanglement =
false;
877 Eigen::Index chi = 10;
878 double singularValueThreshold = 0.;
879 bool enableMultithreading =
true;
880 AER::Data savedState;
883 std::uniform_real_distribution<double> uniformZeroOne{0., 1.};
884 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.