18#ifdef INCLUDED_BY_FACTORY
23#include <unordered_map>
38class QuestState :
public ISimulator {
40 QuestState() : rng(std::random_device{}()), uniformZeroOne(0, 1) {}
49 void Initialize()
override {
50 if (!questLib) questLib = SimulatorsFactory::GetQuestLibrary();
51 if (nrQubits && questLib && questLib->IsValid()) {
52 simHandle = questLib->CreateSimulator(
static_cast<int>(nrQubits));
53 sim = questLib->GetSimulator(simHandle);
55 throw std::runtime_error(
56 "QuestState::Initialize: Failed to create "
57 "and initialize the statevector state.");
72 void InitializeState(
size_t num_qubits,
73 std::vector<std::complex<double>> &litudes)
override {
74 throw std::runtime_error(
75 "QuestState::InitializeState: Not supported for Quest simulator.");
90 void InitializeState(
size_t num_qubits,
91 AER::Vector<std::complex<double>> &litudes)
override {
92 throw std::runtime_error(
93 "QuestState::InitializeState: Not supported for Quest simulator.");
108 void InitializeState(
size_t num_qubits,
109 Eigen::VectorXcd &litudes)
override {
110 throw std::runtime_error(
111 "QuestState::InitializeState: Not supported for Quest simulator.");
120 void Reset()
override {
121 if (sim && questLib) {
122 questLib->DestroySimulator(simHandle);
123 simHandle = questLib->CreateSimulator(
static_cast<int>(nrQubits));
124 sim = questLib->GetSimulator(simHandle);
137 void Configure(
const char *key,
const char *value)
override {
149 if (std::string(
"method") == key)
return "statevector";
163 const size_t oldNrQubits = nrQubits;
164 nrQubits += num_qubits;
184 void Clear()
override {
185 if (sim && questLib) {
186 questLib->DestroySimulator(simHandle);
190 if (savedSim && questLib) {
191 questLib->DestroySimulator(savedSimHandle);
209 if (qubits.size() >
sizeof(
size_t) * 8)
211 <<
"Warning: The number of qubits to measure is larger than the "
212 "number of bits in the size_t type, the outcome will be undefined"
217 std::vector<int> qb(qubits.begin(), qubits.end());
218 const size_t res =
static_cast<size_t>(questLib->MeasureQubits(
219 sim, qb.data(),
static_cast<int>(qubits.size())));
222 NotifyObservers(qubits);
234 std::vector<bool> res(qubits.size(),
false);
238 std::vector<int> qb(qubits.begin(), qubits.end());
239 const size_t resm =
static_cast<size_t>(questLib->MeasureQubits(
240 sim, qb.data(),
static_cast<int>(qubits.size())));
243 for (
size_t i = 0; i < qubits.size(); ++i) {
244 res[i] = (resm & mask) != 0;
249 NotifyObservers(qubits);
262 std::vector<int> qb(qubits.begin(), qubits.end());
263 const size_t res =
static_cast<size_t>(questLib->MeasureQubits(
264 sim, qb.data(),
static_cast<int>(qubits.size())));
266 for (
size_t i = 0; i < qubits.size(); ++i) {
267 if (res & mask) questLib->ApplyX(sim,
static_cast<int>(qubits[i]));
272 NotifyObservers(qubits);
287 return questLib->GetOutcomeProbability(sim,
288 static_cast<long long int>(outcome));
302 std::complex<double> amplitude;
303 if (questLib->GetAmplitude(sim,
static_cast<long long int>(outcome),
307 return std::complex<double>(0.0, 0.0);
323 std::complex<double> ProjectOnZero()
override {
338 if (nrQubits == 0)
return {};
339 const size_t numStates = 1ULL << nrQubits;
340 std::vector<std::complex<double>> amplitudes(numStates);
341 questLib->GetAmplitudes(sim, amplitudes);
343 std::vector<double> result(numStates);
344 for (
size_t i = 0; i < numStates; ++i) result[i] = std::norm(amplitudes[i]);
361 std::vector<double> result(qubits.size());
362 for (
size_t i = 0; i < qubits.size(); ++i)
363 result[i] = questLib->GetOutcomeProbability(
364 sim,
static_cast<long long int>(qubits[i]));
384 std::unordered_map<Types::qubit_t, Types::qubit_t>
SampleCounts(
386 if (qubits.empty() || shots == 0)
return {};
390 <<
"Warning: The number of qubits to measure is larger than the "
391 "number of bits in the Types::qubit_t type, the outcome will be "
395 std::unordered_map<Types::qubit_t, Types::qubit_t> result;
398 const size_t numStates = 1ULL << nrQubits;
399 std::vector<std::complex<double>> amplitudes(numStates);
400 questLib->GetAmplitudes(sim, amplitudes);
404 for (
size_t shot = 0; shot < shots; ++shot) {
405 const double prob = 1. - uniformZeroOne(rng);
406 const size_t measRaw = alias.
Sample(prob);
410 for (
auto q : qubits) {
411 const size_t qubitMask = 1ULL << q;
412 if ((measRaw & qubitMask) != 0) meas |= mask;
419 for (
size_t shot = 0; shot < shots; ++shot) {
424 for (
auto q : qubits) {
425 const size_t qubitMask = 1ULL << q;
426 if ((measRaw & qubitMask) != 0) meas |= mask;
435 NotifyObservers(qubits);
453 std::unordered_map<std::vector<bool>,
Types::qubit_t> SampleCountsMany(
455 if (qubits.empty() || shots == 0)
return {};
460 const size_t numStates = 1ULL << nrQubits;
461 std::vector<std::complex<double>> amplitudes(numStates);
462 questLib->GetAmplitudes(sim, amplitudes);
466 for (
size_t shot = 0; shot < shots; ++shot) {
467 const double prob = 1. - uniformZeroOne(rng);
468 const size_t measRaw = alias.
Sample(prob);
470 std::vector<bool> meas(qubits.size(),
false);
472 for (
size_t i = 0; i < qubits.size(); ++i)
473 if (((measRaw >> qubits[i]) & 1) == 1) meas[i] =
true;
478 for (
size_t shot = 0; shot < shots; ++shot) {
479 const auto measRaw = MeasureNoCollapseMany();
480 std::vector<bool> meas(qubits.size(),
false);
482 for (
size_t i = 0; i < qubits.size(); ++i)
483 if (measRaw[qubits[i]]) meas[i] =
true;
490 NotifyObservers(qubits);
506 double ExpectationValue(
const std::string &pauliString)
override {
507 return questLib->GetExpectationValue(sim, pauliString.c_str());
517 SimulatorType GetType()
const override {
return SimulatorType::kQuestSim; }
528 return SimulationType::kStatevector;
537 void Flush()
override {}
548 if (savedSim && questLib) {
549 questLib->DestroySimulator(savedSimHandle);
553 savedSimHandle = simHandle;
566 if (sim && questLib) questLib->DestroySimulator(simHandle);
567 simHandle = savedSimHandle;
582 if (savedSim && questLib) {
583 questLib->DestroySimulator(savedSimHandle);
587 savedSimHandle = questLib->CloneSimulator(sim);
588 savedSim = questLib->GetSimulator(savedSimHandle);
599 if (sim && questLib) questLib->DestroySimulator(simHandle);
600 simHandle = questLib->CloneSimulator(savedSim);
601 sim = questLib->GetSimulator(simHandle);
609 std::complex<double> AmplitudeRaw(
Types::qubit_t outcome)
override {
641 bool IsQcsim()
const override {
return false; }
659 <<
"Warning: The number of qubits to measure is larger than the "
660 "number of bits in the Types::qubit_t type, the outcome will be "
664 const size_t numStates = 1ULL << nrQubits;
665 std::vector<std::complex<double>> amplitudes(numStates);
666 questLib->GetAmplitudes(sim, amplitudes);
668 std::vector<double> probs(numStates);
669 for (
size_t i = 0; i < numStates; ++i) probs[i] = std::norm(amplitudes[i]);
671 std::discrete_distribution<Types::qubit_t> dist(probs.begin(), probs.end());
687 std::vector<bool> MeasureNoCollapseMany()
override {
689 std::vector<bool> result(nrQubits,
false);
690 for (
size_t i = 0; i < nrQubits; ++i) result[i] = ((meas >> i) & 1) == 1;
695 std::shared_ptr<QuestLibSim> questLib;
696 unsigned long int simHandle = 0;
699 unsigned long int savedSimHandle = 0;
700 void *savedSim =
nullptr;
702 std::uniform_real_distribution<double> uniformZeroOne;
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
uint_fast64_t qubit_t
The type of a qubit.
std::vector< qubit_t > qubits_vector
The type of a vector of qubits.