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;
183 else if (std::string(
"extended_stabilizer") == value)
184 simulationType = SimulationType::kExtendedStabilizer;
186 simulationType = SimulationType::kOther;
187 }
else if (std::string(
"matrix_product_state_truncation_threshold") ==
189 singularValueThreshold = std::stod(value);
190 if (singularValueThreshold > 0.)
191 limitEntanglement =
true;
193 limitEntanglement =
false;
194 }
else if (std::string(
"matrix_product_state_max_bond_dimension") == key) {
195 chi = std::stoi(value);
200 }
else if (std::string(
"mps_sample_measure_algorithm") == key)
201 useMPSMeasureNoCollapse = std::string(
"mps_probabilities") == value;
203 state->configure(key, value);
214 if (std::string(
"method") == key) {
215 switch (simulationType) {
216 case SimulationType::kStatevector:
217 return "statevector";
218 case SimulationType::kMatrixProductState:
219 return "matrix_product_state";
220 case SimulationType::kStabilizer:
222 case SimulationType::kTensorNetwork:
223 return "tensor_network";
224 case SimulationType::kExtendedStabilizer:
225 return "extended_stabilizer";
229 }
else if (std::string(
"matrix_product_state_truncation_threshold") ==
231 if (limitEntanglement && singularValueThreshold > 0.)
232 return std::to_string(singularValueThreshold);
233 }
else if (std::string(
"matrix_product_state_max_bond_dimension") == key) {
234 if (limitSize && limitSize > 0)
return std::to_string(chi);
235 }
else if (std::string(
"mps_sample_measure_algorithm") == key) {
236 return useMPSMeasureNoCollapse ?
"mps_probabilities"
237 :
"mps_apply_measure";
251 const auto ids = state->allocate_qubits(num_qubits);
262 if (state->is_initialized())
return state->num_of_qubits();
274 void Clear()
override {
278 if (simulationType == SimulationType::kMatrixProductState)
279 Configure(
"mps_sample_measure_algorithm", useMPSMeasureNoCollapse
280 ?
"mps_probabilities"
281 :
"mps_apply_measure");
295 if (qubits.size() >
sizeof(
size_t) * 8)
297 <<
"Warning: The number of qubits to measure is larger than the "
298 "number of bits in the size_t type, the outcome will be undefined"
301 const size_t res = state->apply_measure(qubits);
303 NotifyObservers(qubits);
315 auto res = state->apply_measure_many(qubits);
317 NotifyObservers(qubits);
329 state->apply_reset(qubits);
331 NotifyObservers(qubits);
346 return state->probability(outcome);
360 return state->amplitude(outcome);
376 std::complex<double> ProjectOnZero()
override {
392 return state->probabilities();
408 return state->probabilities(qubits);
427 std::unordered_map<Types::qubit_t, Types::qubit_t>
SampleCounts(
429 if (qubits.empty() || shots == 0)
return {};
433 <<
"Warning: The number of qubits to measure is larger than the "
434 "number of bits in the Types::qubit_t type, the outcome will be "
438 std::unordered_map<Types::qubit_t, Types::qubit_t> res =
439 state->sample_counts(qubits, shots);
441 NotifyObservers(qubits);
459 std::unordered_map<std::vector<bool>,
Types::qubit_t> SampleCountsMany(
461 if (qubits.empty() || shots == 0)
return {};
463 state->sample_counts_many(qubits, shots);
464 NotifyObservers(qubits);
479 double ExpectationValue(
const std::string &pauliStringOrig)
override {
480 if (pauliStringOrig.empty())
return 1.0;
482 std::string pauliString = pauliStringOrig;
485 const auto pauliOp = toupper(pauliString[i]);
486 if (pauliOp !=
'I' && pauliOp !=
'Z')
return 0.0;
495 pauli.reserve(pauliString.size());
496 qubits.reserve(pauliString.size());
498 for (
size_t q = 0; q < pauliString.size(); ++q) {
499 const char p = toupper(pauliString[q]);
500 if (p ==
'I')
continue;
506 if (qubits.empty())
return 1.0;
509 std::reverse(pauli.begin(), pauli.end());
511 return state->expval_pauli(qubits, pauli);
521 SimulatorType GetType()
const override {
return SimulatorType::kQiskitAer; }
541 void Flush()
override {
556 savedAmplitudes = state->move_to_vector();
566 const size_t numQubits =
static_cast<size_t>(log2(savedAmplitudes.size()));
567 state->initialize_statevector(numQubits, savedAmplitudes.move_to_buffer(),
584 if (simulationType == SimulationType::kStatevector) {
586 state->initialize_statevector(numQubits, savedAmplitudes.data(),
true);
592 if (state->is_initialized()) {
593 AER::Operations::Op op;
595 op.type = AER::Operations::OpType::save_state;
596 op.name =
"save_state";
597 op.save_type = AER::Operations::DataSubType::single;
598 op.string_params.push_back(
"s");
600 for (
size_t q = 0; q < numQubits; ++q) op.qubits.push_back(q);
602 state->buffer_op(std::move(op));
606 AER::ExperimentResult &last_result = state->last_result();
608 if (last_result.status == AER::ExperimentResult::Status::completed) {
609 savedState = std::move(last_result.data);
614 AER::ExperimentResult &last_result_prev = state->last_result();
616 if (last_result_prev.status == AER::ExperimentResult::Status::completed) {
617 savedState = std::move(last_result_prev.data);
627 if (saved && simulationType == SimulationType::kMatrixProductState)
642 AER::Operations::Op op;
644 switch (simulationType) {
645 case SimulationType::kStatevector: {
654 numQubits =
static_cast<size_t>(log2(savedAmplitudes.size()));
655 state->initialize_statevector(numQubits, savedAmplitudes.data(),
true);
659 case SimulationType::kMatrixProductState:
660 op.type = AER::Operations::OpType::set_mps;
663 static_cast<AER::DataMap<AER::SingleData, AER::mps_container_t>
>(
681 numQubits = op.mps.first.size();
683 case SimulationType::kStabilizer:
684 op.type = AER::Operations::OpType::set_stabilizer;
685 op.name =
"set_stabilizer";
687 static_cast<AER::DataMap<AER::SingleData, json_t>
>(savedState)
704 numQubits = op.clifford.num_qubits();
706 case SimulationType::kTensorNetwork:
708 throw std::runtime_error(
709 "AerState::RestoreState: not implemented yet "
710 "for this type of simulator.");
713 op.save_type = AER::Operations::DataSubType::single;
714 op.string_params.push_back(
"s");
716 for (
size_t q = 0; q < numQubits; ++q) op.qubits.push_back(q);
719 if (!state->is_initialized()) {
725 state->buffer_op(std::move(op));
736 std::complex<double> AmplitudeRaw(
Types::qubit_t outcome)
override {
737 return savedAmplitudes[outcome];
749 enableMultithreading = multithreading;
750 if (state && !state->is_initialized()) {
751 const std::string nrThreads =
752 std::to_string(enableMultithreading
755 state->configure(
"max_parallel_threads", nrThreads);
756 state->configure(
"parallel_state_update", nrThreads);
757 const std::string threadsLimit =
760 state->configure(
"statevector_parallel_threshold", threadsLimit);
783 bool IsQcsim()
const override {
return false; }
802 if (simulationType == SimulationType::kStatevector) {
804 1. - uniformZeroOne(rng);
808 accum += std::norm(savedAmplitudes[i]);
818 throw std::runtime_error(
819 "AerState::MeasureNoCollapse: Invalid simulation type for measuring "
820 "all the qubits without collapsing the state.");
839 std::vector<bool> MeasureNoCollapseMany()
override {
840 if (simulationType == SimulationType::kStatevector) {
841 const size_t numQubits =
842 static_cast<size_t>(log2(savedAmplitudes.size()));
843 std::vector<bool> res(numQubits,
false);
847 for (
size_t i = 0; i < numQubits; ++i) {
848 if ((state & 1) == 1) res[i] =
true;
854 throw std::runtime_error(
855 "AerState::MeasureNoCollapseMany: Invalid simulation type for "
857 "all the qubits without collapsing the state.");
863 SimulationType simulationType =
864 SimulationType::kStatevector;
865 std::unique_ptr<QiskitAerState> state =
866 std::make_unique<QiskitAerState>();
867 AER::Vector<complex_t> savedAmplitudes;
868 bool limitSize =
false;
869 bool limitEntanglement =
false;
870 Eigen::Index chi = 10;
871 double singularValueThreshold = 0.;
872 bool enableMultithreading =
true;
873 AER::Data savedState;
876 std::uniform_real_distribution<double> uniformZeroOne{0., 1.};
877 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)
uint_fast64_t qubit_t
The type of a qubit.
std::vector< qubit_t > qubits_vector
The type of a vector of qubits.