18#ifdef INCLUDED_BY_FACTORY
23#include <unordered_map>
40class QuestState :
public ISimulator {
42 QuestState() : rng(std::random_device{}()), uniformZeroOne(0, 1) {}
51 void Initialize()
override {
52 if (!questLib) questLib = SimulatorsFactory::GetQuestLibrary();
53 if (nrQubits && questLib && questLib->IsValid()) {
54 simHandle = questLib->CreateSimulator(
static_cast<int>(nrQubits));
55 sim = questLib->GetSimulator(simHandle);
57 throw std::runtime_error(
58 "QuestState::Initialize: Failed to create "
59 "and initialize the statevector state.");
74 void InitializeState(
size_t num_qubits,
75 std::vector<std::complex<double>> &litudes)
override {
76 throw std::runtime_error(
77 "QuestState::InitializeState: Not supported for Quest simulator.");
92 void InitializeState(
size_t num_qubits,
93 AER::Vector<std::complex<double>> &litudes)
override {
94 throw std::runtime_error(
95 "QuestState::InitializeState: Not supported for Quest simulator.");
110 void InitializeState(
size_t num_qubits,
111 Eigen::VectorXcd &litudes)
override {
112 throw std::runtime_error(
113 "QuestState::InitializeState: Not supported for Quest simulator.");
122 void Reset()
override {
123 if (sim && questLib) {
124 questLib->DestroySimulator(simHandle);
125 simHandle = questLib->CreateSimulator(
static_cast<int>(nrQubits));
126 sim = questLib->GetSimulator(simHandle);
139 void Configure(
const char *key,
const char *value)
override {
151 if (std::string(
"method") == key)
return "statevector";
165 const size_t oldNrQubits = nrQubits;
166 nrQubits += num_qubits;
186 void Clear()
override {
187 if (sim && questLib) {
188 questLib->DestroySimulator(simHandle);
192 if (savedSim && questLib) {
193 questLib->DestroySimulator(savedSimHandle);
211 if (qubits.size() >
sizeof(
size_t) * 8)
213 <<
"Warning: The number of qubits to measure is larger than the "
214 "number of bits in the size_t type, the outcome will be undefined"
219 std::vector<int> qb(qubits.begin(), qubits.end());
220 const size_t res =
static_cast<size_t>(questLib->MeasureQubits(
221 sim, qb.data(),
static_cast<int>(qubits.size())));
224 NotifyObservers(qubits);
236 std::vector<bool> res(qubits.size(),
false);
240 std::vector<int> qb(qubits.begin(), qubits.end());
241 const size_t resm =
static_cast<size_t>(questLib->MeasureQubits(
242 sim, qb.data(),
static_cast<int>(qubits.size())));
245 for (
size_t i = 0; i < qubits.size(); ++i) {
246 res[i] = (resm & mask) != 0;
251 NotifyObservers(qubits);
264 std::vector<int> qb(qubits.begin(), qubits.end());
265 const size_t res =
static_cast<size_t>(questLib->MeasureQubits(
266 sim, qb.data(),
static_cast<int>(qubits.size())));
268 for (
size_t i = 0; i < qubits.size(); ++i) {
269 if (res & mask) questLib->ApplyX(sim,
static_cast<int>(qubits[i]));
274 NotifyObservers(qubits);
289 return questLib->GetOutcomeProbability(sim,
290 static_cast<long long int>(outcome));
304 std::complex<double> amplitude;
305 if (questLib->GetAmplitude(sim,
static_cast<long long int>(outcome),
309 return std::complex<double>(0.0, 0.0);
325 std::complex<double> ProjectOnZero()
override {
340 if (nrQubits == 0)
return {};
341 const size_t numStates = 1ULL << nrQubits;
342 std::vector<std::complex<double>> amplitudes(numStates);
343 questLib->GetAmplitudes(sim, amplitudes);
345 std::vector<double> result(numStates);
346 for (
size_t i = 0; i < numStates; ++i) result[i] = std::norm(amplitudes[i]);
363 std::vector<double> result(qubits.size());
364 for (
size_t i = 0; i < qubits.size(); ++i)
365 result[i] = questLib->GetOutcomeProbability(
366 sim,
static_cast<long long int>(qubits[i]));
386 std::unordered_map<Types::qubit_t, Types::qubit_t>
SampleCounts(
388 if (qubits.empty() || shots == 0)
return {};
392 <<
"Warning: The number of qubits to measure is larger than the "
393 "number of bits in the Types::qubit_t type, the outcome will be "
397 std::unordered_map<Types::qubit_t, Types::qubit_t> result;
400 const size_t numStates = 1ULL << nrQubits;
401 std::vector<std::complex<double>> amplitudes(numStates);
402 questLib->GetAmplitudes(sim, amplitudes);
406 for (
size_t shot = 0; shot < shots; ++shot) {
407 const double prob = 1. - uniformZeroOne(rng);
408 const size_t measRaw = alias.
Sample(prob);
412 for (
auto q : qubits) {
413 const size_t qubitMask = 1ULL << q;
414 if ((measRaw & qubitMask) != 0) meas |= mask;
421 for (
size_t shot = 0; shot < shots; ++shot) {
426 for (
auto q : qubits) {
427 const size_t qubitMask = 1ULL << q;
428 if ((measRaw & qubitMask) != 0) meas |= mask;
437 NotifyObservers(qubits);
455 std::unordered_map<std::vector<bool>,
Types::qubit_t> SampleCountsMany(
457 if (qubits.empty() || shots == 0)
return {};
462 const size_t numStates = 1ULL << nrQubits;
463 std::vector<std::complex<double>> amplitudes(numStates);
464 questLib->GetAmplitudes(sim, amplitudes);
468 for (
size_t shot = 0; shot < shots; ++shot) {
469 const double prob = 1. - uniformZeroOne(rng);
470 const size_t measRaw = alias.
Sample(prob);
472 std::vector<bool> meas(qubits.size(),
false);
474 for (
size_t i = 0; i < qubits.size(); ++i)
475 if (((measRaw >> qubits[i]) & 1) == 1) meas[i] =
true;
480 for (
size_t shot = 0; shot < shots; ++shot) {
481 const auto measRaw = MeasureNoCollapseMany();
482 std::vector<bool> meas(qubits.size(),
false);
484 for (
size_t i = 0; i < qubits.size(); ++i)
485 if (measRaw[qubits[i]]) meas[i] =
true;
492 NotifyObservers(qubits);
508 double ExpectationValue(
const std::string &pauliString)
override {
509 return questLib->GetExpectationValue(sim, pauliString.c_str());
519 SimulatorType GetType()
const override {
return SimulatorType::kQuestSim; }
530 return SimulationType::kStatevector;
539 void Flush()
override {}
550 if (savedSim && questLib) {
551 questLib->DestroySimulator(savedSimHandle);
555 savedSimHandle = simHandle;
568 if (sim && questLib) questLib->DestroySimulator(simHandle);
569 simHandle = savedSimHandle;
584 if (savedSim && questLib) {
585 questLib->DestroySimulator(savedSimHandle);
589 savedSimHandle = questLib->CloneSimulator(sim);
590 savedSim = questLib->GetSimulator(savedSimHandle);
601 if (sim && questLib) questLib->DestroySimulator(simHandle);
602 simHandle = questLib->CloneSimulator(savedSim);
603 sim = questLib->GetSimulator(simHandle);
611 std::complex<double> AmplitudeRaw(
Types::qubit_t outcome)
override {
643 bool IsQcsim()
const override {
return false; }
661 <<
"Warning: The number of qubits to measure is larger than the "
662 "number of bits in the Types::qubit_t type, the outcome will be "
666 const size_t numStates = 1ULL << nrQubits;
667 std::vector<std::complex<double>> amplitudes(numStates);
668 questLib->GetAmplitudes(sim, amplitudes);
670 std::vector<double> probs(numStates);
671 for (
size_t i = 0; i < numStates; ++i) probs[i] = std::norm(amplitudes[i]);
673 std::discrete_distribution<Types::qubit_t> dist(probs.begin(), probs.end());
689 std::vector<bool> MeasureNoCollapseMany()
override {
691 std::vector<bool> result(nrQubits,
false);
692 for (
size_t i = 0; i < nrQubits; ++i) result[i] = ((meas >> i) & 1) == 1;
698 const std::unordered_map<std::string, std::string>& GetConfigMap()
700 return configuration.GetConfigMap();
704 std::shared_ptr<QuestLibSim> questLib;
705 unsigned long int simHandle = 0;
708 unsigned long int savedSimHandle = 0;
709 void *savedSim =
nullptr;
711 std::uniform_real_distribution<double> uniformZeroOne;
713 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
std::vector< qubit_t > qubits_vector
The type of a vector of qubits.
uint_fast64_t qubit_t
The type of a qubit.