18#ifdef INCLUDED_BY_FACTORY
24#include <unordered_map>
43class QuestState :
public ISimulator
46 QuestState() : rng(std::random_device{}()), uniformZeroOne(0, 1)
57 void Initialize()
override
60 questLib = SimulatorsFactory::GetQuestLibrary();
61 if (nrQubits && questLib && questLib->IsValid())
63 simHandle = questLib->CreateSimulator(
static_cast<int>(nrQubits));
64 sim = questLib->GetSimulator(simHandle);
66 throw std::runtime_error(
"QuestState::Initialize: Failed to create "
67 "and initialize the statevector state.");
82 void InitializeState(
size_t num_qubits, std::vector<std::complex<double>> &litudes)
override
84 throw std::runtime_error(
"QuestState::InitializeState: Not supported for Quest simulator.");
99 void InitializeState(
size_t num_qubits, AER::Vector<std::complex<double>> &litudes)
override
101 throw std::runtime_error(
"QuestState::InitializeState: Not supported for Quest simulator.");
116 void InitializeState(
size_t num_qubits, Eigen::VectorXcd &litudes)
override
118 throw std::runtime_error(
"QuestState::InitializeState: Not supported for Quest simulator.");
127 void Reset()
override
131 questLib->DestroySimulator(simHandle);
132 simHandle = questLib->CreateSimulator(
static_cast<int>(nrQubits));
133 sim = questLib->GetSimulator(simHandle);
146 void Configure(
const char *key,
const char *value)
override
148 if (std::string(
"seed") == key)
150 const uint64_t seed = std::stoull(value);
151 SeedAuxiliaryRng(seed);
153 configuration.SetConfiguration(key, value);
166 if (std::string(
"method") == key)
167 return "statevector";
168 return configuration.GetConfiguration(key);
183 const size_t oldNrQubits = nrQubits;
184 nrQubits += num_qubits;
207 void Clear()
override
211 questLib->DestroySimulator(simHandle);
215 if (savedSim && questLib)
217 questLib->DestroySimulator(savedSimHandle);
236 if (qubits.size() >
sizeof(
size_t) * 8)
237 std::cerr <<
"Warning: The number of qubits to measure is larger than the "
238 "number of bits in the size_t type, the outcome will be undefined"
243 std::vector<int> qb(qubits.begin(), qubits.end());
244 const size_t res =
static_cast<size_t>(questLib->MeasureQubits(sim, qb.data(),
static_cast<int>(qubits.size())));
247 NotifyObservers(qubits);
260 std::vector<bool> res(qubits.size(),
false);
264 std::vector<int> qb(qubits.begin(), qubits.end());
265 const size_t resm =
static_cast<size_t>(questLib->MeasureQubits(sim, qb.data(),
static_cast<int>(qubits.size())));
268 for (
size_t i = 0; i < qubits.size(); ++i)
270 res[i] = (resm & mask) != 0;
275 NotifyObservers(qubits);
289 std::vector<int> qb(qubits.begin(), qubits.end());
290 const size_t res =
static_cast<size_t>(questLib->MeasureQubits(sim, qb.data(),
static_cast<int>(qubits.size())));
292 for (
size_t i = 0; i < qubits.size(); ++i)
295 questLib->ApplyX(sim,
static_cast<int>(qubits[i]));
300 NotifyObservers(qubits);
316 return questLib->GetOutcomeProbability(sim,
static_cast<long long int>(outcome));
331 std::complex<double> amplitude;
332 if (questLib->GetAmplitude(sim,
static_cast<long long int>(outcome), amplitude))
336 return std::complex<double>(0.0, 0.0);
352 std::complex<double> ProjectOnZero()
override
371 const size_t numStates = 1ULL << nrQubits;
372 std::vector<std::complex<double>> amplitudes(numStates);
373 questLib->GetAmplitudes(sim, amplitudes);
375 std::vector<double> result(numStates);
376 for (
size_t i = 0; i < numStates; ++i)
377 result[i] = std::norm(amplitudes[i]);
394 std::vector<double> result(qubits.size());
395 for (
size_t i = 0; i < qubits.size(); ++i)
396 result[i] = questLib->GetOutcomeProbability(sim,
static_cast<long long int>(qubits[i]));
418 if (qubits.empty() || shots == 0)
422 std::cerr <<
"Warning: The number of qubits to measure is larger than the "
423 "number of bits in the Types::qubit_t type, the outcome will be "
427 std::unordered_map<Types::qubit_t, Types::qubit_t> result;
431 const size_t numStates = 1ULL << nrQubits;
432 std::vector<std::complex<double>> amplitudes(numStates);
433 questLib->GetAmplitudes(sim, amplitudes);
437 for (
size_t shot = 0; shot < shots; ++shot)
439 const double prob = 1. - uniformZeroOne(rng);
440 const size_t measRaw = alias.
Sample(prob);
444 for (
auto q : qubits)
446 const size_t qubitMask = 1ULL << q;
447 if ((measRaw & qubitMask) != 0)
457 for (
size_t shot = 0; shot < shots; ++shot)
463 for (
auto q : qubits)
465 const size_t qubitMask = 1ULL << q;
466 if ((measRaw & qubitMask) != 0)
476 NotifyObservers(qubits);
496 if (qubits.empty() || shots == 0)
503 const size_t numStates = 1ULL << nrQubits;
504 std::vector<std::complex<double>> amplitudes(numStates);
505 questLib->GetAmplitudes(sim, amplitudes);
509 for (
size_t shot = 0; shot < shots; ++shot)
511 const double prob = 1. - uniformZeroOne(rng);
512 const size_t measRaw = alias.
Sample(prob);
514 std::vector<bool> meas(qubits.size(),
false);
516 for (
size_t i = 0; i < qubits.size(); ++i)
517 if (((measRaw >> qubits[i]) & 1) == 1)
525 for (
size_t shot = 0; shot < shots; ++shot)
527 const auto measRaw = MeasureNoCollapseMany();
528 std::vector<bool> meas(qubits.size(),
false);
530 for (
size_t i = 0; i < qubits.size(); ++i)
531 if (measRaw[qubits[i]])
539 NotifyObservers(qubits);
555 double ExpectationValue(
const std::string &pauliString)
override
557 return questLib->GetExpectationValue(sim, pauliString.c_str());
567 SimulatorType GetType()
const override
569 return SimulatorType::kQuestSim;
582 return SimulationType::kStatevector;
591 void Flush()
override
605 if (savedSim && questLib)
607 questLib->DestroySimulator(savedSimHandle);
611 savedSimHandle = simHandle;
626 questLib->DestroySimulator(simHandle);
627 simHandle = savedSimHandle;
643 if (savedSim && questLib)
645 questLib->DestroySimulator(savedSimHandle);
649 savedSimHandle = questLib->CloneSimulator(sim);
650 savedSim = questLib->GetSimulator(savedSimHandle);
663 questLib->DestroySimulator(simHandle);
664 simHandle = questLib->CloneSimulator(savedSim);
665 sim = questLib->GetSimulator(simHandle);
673 std::complex<double> AmplitudeRaw(
Types::qubit_t outcome)
override
731 std::cerr <<
"Warning: The number of qubits to measure is larger than the "
732 "number of bits in the Types::qubit_t type, the outcome will be "
736 const size_t numStates = 1ULL << nrQubits;
737 std::vector<std::complex<double>> amplitudes(numStates);
738 questLib->GetAmplitudes(sim, amplitudes);
740 std::vector<double> probs(numStates);
741 for (
size_t i = 0; i < numStates; ++i)
742 probs[i] = std::norm(amplitudes[i]);
744 std::discrete_distribution<Types::qubit_t> dist(probs.begin(), probs.end());
760 std::vector<bool> MeasureNoCollapseMany()
override
763 std::vector<bool> result(nrQubits,
false);
764 for (
size_t i = 0; i < nrQubits; ++i)
765 result[i] = ((meas >> i) & 1) == 1;
771 return configuration;
774 const std::unordered_map<std::string, std::string> &GetConfigMap()
const override
776 return configuration.GetConfigMap();
780 std::shared_ptr<QuestLibSim> questLib;
781 unsigned long int simHandle = 0;
784 unsigned long int savedSimHandle = 0;
785 void *savedSim =
nullptr;
787 std::uniform_real_distribution<double> uniformZeroOne;
789 Configuration configuration;
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)
size_t Sample(double v) const
Bounded online routing based on current physical bond dimensions.
std::vector< qubit_t > qubits_vector
The type of a vector of qubits.
uint_fast64_t qubit_t
The type of a qubit.