14#ifndef _QUEST_LIB_SIM_H_
15#define _QUEST_LIB_SIM_H_
17#include "../Utils/Library.h"
35 if (initialized && fFinalize) {
41 bool Init(
const char *libName)
noexcept override {
43 fInitialize = (void (*)())
GetFunction(
"Initialize");
49 (
unsigned long int (*)(int))
GetFunction(
"CreateSimulator");
52 (void (*)(
unsigned long int))
GetFunction(
"DestroySimulator");
55 (
unsigned long int (*)(
void *))
GetFunction(
"CloneSimulator");
57 fGetSimulator = (
void *(*)(
unsigned long int))
GetFunction(
"GetSimulator");
60 fGetNumQubits = (int (*)(
void *))
GetFunction(
"GetNumQubits");
62 fGetQubitProbability0 =
63 (double (*)(
void *, int))
GetFunction(
"GetQubitProbability0");
65 fGetQubitProbability1 =
66 (double (*)(
void *, int))
GetFunction(
"GetQubitProbability1");
68 fGetOutcomeProbability = (double (*)(
void *,
long long int))
GetFunction(
69 "GetOutcomeProbability");
71 fGetExpectationValue =
72 (double (*)(
void *,
const char *))
GetFunction(
"GetExpectationValue");
75 fMeasure = (int (*)(
void *, int))
GetFunction(
"Measure");
78 (
long long int (*)(
void *,
int *, int))
GetFunction(
"MeasureQubits");
81 fApplyP = (void (*)(
void *, int, double))
GetFunction(
"ApplyP");
83 fApplyX = (void (*)(
void *, int))
GetFunction(
"ApplyX");
85 fApplyY = (void (*)(
void *, int))
GetFunction(
"ApplyY");
87 fApplyZ = (void (*)(
void *, int))
GetFunction(
"ApplyZ");
89 fApplyH = (void (*)(
void *, int))
GetFunction(
"ApplyH");
91 fApplyS = (void (*)(
void *, int))
GetFunction(
"ApplyS");
93 fApplyT = (void (*)(
void *, int))
GetFunction(
"ApplyT");
96 fApplyRx = (void (*)(
void *, int, double))
GetFunction(
"ApplyRx");
98 fApplyRy = (void (*)(
void *, int, double))
GetFunction(
"ApplyRy");
100 fApplyRz = (void (*)(
void *, int, double))
GetFunction(
"ApplyRz");
103 fApplyCS = (void (*)(
void *, int, int))
GetFunction(
"ApplyCS");
105 fApplyCT = (void (*)(
void *, int, int))
GetFunction(
"ApplyCT");
107 fApplyCH = (void (*)(
void *, int, int))
GetFunction(
"ApplyCH");
109 fApplySwap = (void (*)(
void *, int, int))
GetFunction(
"ApplySwap");
111 fApplyCX = (void (*)(
void *, int, int))
GetFunction(
"ApplyCX");
113 fApplyCY = (void (*)(
void *, int, int))
GetFunction(
"ApplyCY");
115 fApplyCZ = (void (*)(
void *, int, int))
GetFunction(
"ApplyCZ");
118 fApplyCRx = (void (*)(
void *, int, int, double))
GetFunction(
"ApplyCRx");
120 fApplyCRy = (void (*)(
void *, int, int, double))
GetFunction(
"ApplyCRy");
122 fApplyCRz = (void (*)(
void *, int, int, double))
GetFunction(
"ApplyCRz");
125 fApplyCSwap = (void (*)(
void *, int, int, int))
GetFunction(
"ApplyCSwap");
127 fApplyCCX = (void (*)(
void *, int, int, int))
GetFunction(
"ApplyCCX");
130 fApplySdg = (void (*)(
void *, int))
GetFunction(
"ApplySdg");
132 fApplyTdg = (void (*)(
void *, int))
GetFunction(
"ApplyTdg");
134 fApplySx = (void (*)(
void *, int))
GetFunction(
"ApplySx");
136 fApplySxDg = (void (*)(
void *, int))
GetFunction(
"ApplySxDg");
138 fApplyK = (void (*)(
void *, int))
GetFunction(
"ApplyK");
141 fApplyU = (void (*)(
void *, int, double, double, double,
144 fApplyCU = (void (*)(
void *, int, int, double, double, double,
147 fApplyCP = (void (*)(
void *, int, int, double))
GetFunction(
"ApplyCP");
149 fApplyCSx = (void (*)(
void *, int, int))
GetFunction(
"ApplyCSx");
151 fApplyCSxDg = (void (*)(
void *, int, int))
GetFunction(
"ApplyCSxDg");
154 fGetAmplitudes = (int (*)(
155 void *,
void *,
unsigned long long int))
GetFunction(
"GetAmplitudes");
158 (int (*)(
void *,
long long int,
void *,
159 unsigned long long int))
GetFunction(
"GetAmplitude");
161 fIsDoublePrecision = (int (*)())
GetFunction(
"IsDoublePrecision");
176 std::cerr <<
"QuestLibSim: Unable to load function, line #: " << line;
179 const char *dlsym_error = dlerror();
180 if (dlsym_error) std::cerr <<
", error: " << dlsym_error;
182 const DWORD error = GetLastError();
183 std::cerr <<
", error code: " << error;
186 std::cerr << std::endl;
196 return fCreateSimulator(nrQubits);
198 throw std::runtime_error(
"QuestLibSim: Unable to create simulator");
205 fDestroySimulator(simHandle);
207 throw std::runtime_error(
"QuestLibSim: Unable to destroy simulator");
212 return fCloneSimulator(sim);
214 throw std::runtime_error(
"QuestLibSim: Unable to clone simulator");
221 return fGetSimulator(simHandle);
223 throw std::runtime_error(
"QuestLibSim: Unable to get simulator");
232 return fGetNumQubits(sim);
234 throw std::runtime_error(
"QuestLibSim: Unable to get number of qubits");
241 return fGetQubitProbability0(sim, qubit);
243 throw std::runtime_error(
244 "QuestLibSim: Unable to get qubit probability 0");
251 return fGetQubitProbability1(sim, qubit);
253 throw std::runtime_error(
254 "QuestLibSim: Unable to get qubit probability 1");
261 return fGetOutcomeProbability(sim, outcome);
263 throw std::runtime_error(
264 "QuestLibSim: Unable to get outcome probability");
271 return fGetExpectationValue(sim, pauliStr);
273 throw std::runtime_error(
"QuestLibSim: Unable to get expectation value");
282 return fMeasure(sim, qubit);
284 throw std::runtime_error(
"QuestLibSim: Unable to measure qubit");
291 return fMeasureQubits(sim, qubits, numQubits);
293 throw std::runtime_error(
"QuestLibSim: Unable to measure qubits");
300 void ApplyP(
void *sim,
int qubit,
double angle) {
302 fApplyP(sim, qubit, angle);
304 throw std::runtime_error(
"QuestLibSim: Unable to apply P gate");
311 throw std::runtime_error(
"QuestLibSim: Unable to apply X gate");
318 throw std::runtime_error(
"QuestLibSim: Unable to apply Y gate");
325 throw std::runtime_error(
"QuestLibSim: Unable to apply Z gate");
332 throw std::runtime_error(
"QuestLibSim: Unable to apply H gate");
339 throw std::runtime_error(
"QuestLibSim: Unable to apply S gate");
346 throw std::runtime_error(
"QuestLibSim: Unable to apply T gate");
351 fApplySdg(sim, qubit);
353 throw std::runtime_error(
"QuestLibSim: Unable to apply Sdg gate");
358 fApplyTdg(sim, qubit);
360 throw std::runtime_error(
"QuestLibSim: Unable to apply Tdg gate");
365 fApplySx(sim, qubit);
367 throw std::runtime_error(
"QuestLibSim: Unable to apply Sx gate");
372 fApplySxDg(sim, qubit);
374 throw std::runtime_error(
"QuestLibSim: Unable to apply SxDg gate");
381 throw std::runtime_error(
"QuestLibSim: Unable to apply K gate");
386 void ApplyRx(
void *sim,
int qubit,
double angle) {
388 fApplyRx(sim, qubit, angle);
390 throw std::runtime_error(
"QuestLibSim: Unable to apply Rx gate");
393 void ApplyRy(
void *sim,
int qubit,
double angle) {
395 fApplyRy(sim, qubit, angle);
397 throw std::runtime_error(
"QuestLibSim: Unable to apply Ry gate");
400 void ApplyRz(
void *sim,
int qubit,
double angle) {
402 fApplyRz(sim, qubit, angle);
404 throw std::runtime_error(
"QuestLibSim: Unable to apply Rz gate");
407 void ApplyU(
void *sim,
int qubit,
double theta,
double phi,
double lambda,
410 fApplyU(sim, qubit, theta, phi, lambda, gamma);
412 throw std::runtime_error(
"QuestLibSim: Unable to apply U gate");
417 void ApplyCS(
void *sim,
int control,
int target) {
419 fApplyCS(sim, control, target);
421 throw std::runtime_error(
"QuestLibSim: Unable to apply CS gate");
424 void ApplyCT(
void *sim,
int control,
int target) {
426 fApplyCT(sim, control, target);
428 throw std::runtime_error(
"QuestLibSim: Unable to apply CT gate");
431 void ApplyCH(
void *sim,
int control,
int target) {
433 fApplyCH(sim, control, target);
435 throw std::runtime_error(
"QuestLibSim: Unable to apply CH gate");
440 fApplySwap(sim, qubit1, qubit2);
442 throw std::runtime_error(
"QuestLibSim: Unable to apply Swap gate");
445 void ApplyCX(
void *sim,
int control,
int target) {
447 fApplyCX(sim, control, target);
449 throw std::runtime_error(
"QuestLibSim: Unable to apply CX gate");
452 void ApplyCY(
void *sim,
int control,
int target) {
454 fApplyCY(sim, control, target);
456 throw std::runtime_error(
"QuestLibSim: Unable to apply CY gate");
459 void ApplyCZ(
void *sim,
int control,
int target) {
461 fApplyCZ(sim, control, target);
463 throw std::runtime_error(
"QuestLibSim: Unable to apply CZ gate");
466 void ApplyCRx(
void *sim,
int control,
int target,
double angle) {
468 fApplyCRx(sim, control, target, angle);
470 throw std::runtime_error(
"QuestLibSim: Unable to apply CRx gate");
473 void ApplyCRy(
void *sim,
int control,
int target,
double angle) {
475 fApplyCRy(sim, control, target, angle);
477 throw std::runtime_error(
"QuestLibSim: Unable to apply CRy gate");
480 void ApplyCRz(
void *sim,
int control,
int target,
double angle) {
482 fApplyCRz(sim, control, target, angle);
484 throw std::runtime_error(
"QuestLibSim: Unable to apply CRz gate");
487 void ApplyCP(
void *sim,
int control,
int target,
double angle) {
489 fApplyCP(sim, control, target, angle);
491 throw std::runtime_error(
"QuestLibSim: Unable to apply CP gate");
494 void ApplyCU(
void *sim,
int control,
int target,
double theta,
double phi,
495 double lambda,
double gamma) {
497 fApplyCU(sim, control, target, theta, phi, lambda, gamma);
499 throw std::runtime_error(
"QuestLibSim: Unable to apply CU gate");
502 void ApplyCSx(
void *sim,
int control,
int target) {
504 fApplyCSx(sim, control, target);
506 throw std::runtime_error(
"QuestLibSim: Unable to apply CSx gate");
511 fApplyCSxDg(sim, control, target);
513 throw std::runtime_error(
"QuestLibSim: Unable to apply CSxDg gate");
518 void ApplyCSwap(
void *sim,
int control,
int qubit1,
int qubit2) {
520 fApplyCSwap(sim, control, qubit1, qubit2);
522 throw std::runtime_error(
"QuestLibSim: Unable to apply CSwap gate");
525 void ApplyCCX(
void *sim,
int control1,
int control2,
int target) {
527 fApplyCCX(sim, control1, control2, target);
529 throw std::runtime_error(
"QuestLibSim: Unable to apply CCX gate");
535 std::vector<std::complex<double>> &litudes)
const {
538 return fGetAmplitudes(
539 sim, amplitudes.data(),
540 amplitudes.size() *
sizeof(std::complex<double>)) == 1;
542 std::vector<std::complex<float>> amplitudesSingle(amplitudes.size());
544 sim, amplitudesSingle.data(),
545 amplitudesSingle.size() *
sizeof(std::complex<float>)) == 1) {
546 for (
size_t i = 0; i < amplitudes.size(); ++i)
547 amplitudes[i] = std::complex<double>(
548 static_cast<double>(amplitudesSingle[i].real()),
549 static_cast<double>(amplitudesSingle[i].imag()));
555 throw std::runtime_error(
"QuestLibSim: Unable to get amplitudes");
561 std::complex<double> &litude)
const {
564 return fGetAmplitude(sim, index, &litude,
565 sizeof(std::complex<double>)) == 1;
567 std::complex<float> ampSingle;
568 if (fGetAmplitude(sim, index, &Single,
569 sizeof(std::complex<float>)) == 1) {
571 std::complex<double>(
static_cast<double>(ampSingle.real()),
572 static_cast<double>(ampSingle.imag()));
577 throw std::runtime_error(
"QuestLibSim: Unable to get amplitude");
583 return fIsDoublePrecision() == 1;
585 throw std::runtime_error(
"QuestLibSim: Unable to check double precision");
590 bool initialized =
false;
592 void (*fInitialize)() =
nullptr;
593 void (*fFinalize)() =
nullptr;
595 unsigned long int (*fCreateSimulator)(int) =
nullptr;
596 void (*fDestroySimulator)(
unsigned long int) =
nullptr;
597 unsigned long int (*fCloneSimulator)(
void *) =
nullptr;
598 void *(*fGetSimulator)(
unsigned long int) =
nullptr;
600 int (*fGetNumQubits)(
void *) =
nullptr;
601 double (*fGetQubitProbability0)(
void *, int) =
nullptr;
602 double (*fGetQubitProbability1)(
void *, int) =
nullptr;
603 double (*fGetOutcomeProbability)(
void *,
long long int) =
nullptr;
604 double (*fGetExpectationValue)(
void *,
const char *) =
nullptr;
606 int (*fMeasure)(
void *, int) =
nullptr;
607 long long int (*fMeasureQubits)(
void *,
int *, int) =
nullptr;
609 void (*fApplyP)(
void *, int, double) =
nullptr;
610 void (*fApplyX)(
void *, int) =
nullptr;
611 void (*fApplyY)(
void *, int) =
nullptr;
612 void (*fApplyZ)(
void *, int) =
nullptr;
613 void (*fApplyH)(
void *, int) =
nullptr;
614 void (*fApplyS)(
void *, int) =
nullptr;
615 void (*fApplyT)(
void *, int) =
nullptr;
616 void (*fApplyRx)(
void *, int, double) =
nullptr;
617 void (*fApplyRy)(
void *, int, double) =
nullptr;
618 void (*fApplyRz)(
void *, int, double) =
nullptr;
620 void (*fApplyCS)(
void *, int, int) =
nullptr;
621 void (*fApplyCT)(
void *, int, int) =
nullptr;
622 void (*fApplyCH)(
void *, int, int) =
nullptr;
623 void (*fApplySwap)(
void *, int, int) =
nullptr;
624 void (*fApplyCX)(
void *, int, int) =
nullptr;
625 void (*fApplyCY)(
void *, int, int) =
nullptr;
626 void (*fApplyCZ)(
void *, int, int) =
nullptr;
627 void (*fApplyCRx)(
void *, int, int, double) =
nullptr;
628 void (*fApplyCRy)(
void *, int, int, double) =
nullptr;
629 void (*fApplyCRz)(
void *, int, int, double) =
nullptr;
631 void (*fApplyCSwap)(
void *, int, int, int) =
nullptr;
632 void (*fApplyCCX)(
void *, int, int, int) =
nullptr;
634 void (*fApplySdg)(
void *, int) =
nullptr;
635 void (*fApplyTdg)(
void *, int) =
nullptr;
636 void (*fApplySx)(
void *, int) =
nullptr;
637 void (*fApplySxDg)(
void *, int) =
nullptr;
638 void (*fApplyK)(
void *, int) =
nullptr;
640 void (*fApplyU)(
void *, int, double, double, double, double) =
nullptr;
641 void (*fApplyCU)(
void *, int, int, double, double, double, double) =
nullptr;
642 void (*fApplyCP)(
void *, int, int, double) =
nullptr;
643 void (*fApplyCSx)(
void *, int, int) =
nullptr;
644 void (*fApplyCSxDg)(
void *, int, int) =
nullptr;
645 int (*fGetAmplitudes)(
void *,
void *,
unsigned long long int) =
nullptr;
646 int (*fGetAmplitude)(
void *,
long long int,
void *,
647 unsigned long long int) =
nullptr;
648 int (*fIsDoublePrecision)() =
nullptr;
unsigned long int CreateSimulator(int nrQubits)
void ApplyCRz(void *sim, int control, int target, double angle)
bool IsDoublePrecision() const
QuestLibSim(QuestLibSim &&)=default
void ApplyRy(void *sim, int qubit, double angle)
void ApplyU(void *sim, int qubit, double theta, double phi, double lambda, double gamma)
void ApplyCS(void *sim, int control, int target)
void ApplyCZ(void *sim, int control, int target)
void ApplyCH(void *sim, int control, int target)
bool GetAmplitude(void *sim, long long int index, std::complex< double > &litude) const
void ApplyCRx(void *sim, int control, int target, double angle)
void ApplyTdg(void *sim, int qubit)
int Measure(void *sim, int qubit)
void ApplyCP(void *sim, int control, int target, double angle)
void ApplyCX(void *sim, int control, int target)
void ApplyX(void *sim, int qubit)
void ApplyRz(void *sim, int qubit, double angle)
void DestroySimulator(unsigned long int simHandle)
void ApplyCSxDg(void *sim, int control, int target)
void ApplyK(void *sim, int qubit)
void ApplyH(void *sim, int qubit)
void ApplySx(void *sim, int qubit)
double GetQubitProbability1(void *sim, int qubit) const
long long int MeasureQubits(void *sim, int *qubits, int numQubits)
void ApplyCY(void *sim, int control, int target)
void ApplyCSwap(void *sim, int control, int qubit1, int qubit2)
void ApplyS(void *sim, int qubit)
void ApplyCU(void *sim, int control, int target, double theta, double phi, double lambda, double gamma)
void ApplyZ(void *sim, int qubit)
int GetNumQubits(void *sim) const
double GetQubitProbability0(void *sim, int qubit) const
void ApplySdg(void *sim, int qubit)
double GetExpectationValue(void *sim, const char *pauliStr) const
void ApplySxDg(void *sim, int qubit)
QuestLibSim(const QuestLibSim &)=delete
bool Init(const char *libName) noexcept override
void ApplySwap(void *sim, int qubit1, int qubit2)
void ApplyCSx(void *sim, int control, int target)
unsigned long int CloneSimulator(void *sim)
void ApplyCCX(void *sim, int control1, int control2, int target)
QuestLibSim & operator=(QuestLibSim &&)=default
double GetOutcomeProbability(void *sim, long long int outcome) const
static void CheckFunction(void *func, int line) noexcept
void ApplyP(void *sim, int qubit, double angle)
bool GetAmplitudes(void *sim, std::vector< std::complex< double > > &litudes) const
void ApplyT(void *sim, int qubit)
QuestLibSim & operator=(const QuestLibSim &)=delete
void ApplyRx(void *sim, int qubit, double angle)
void * GetSimulator(unsigned long int simHandle)
void ApplyY(void *sim, int qubit)
void ApplyCT(void *sim, int control, int target)
void ApplyCRy(void *sim, int control, int target, double angle)
void * GetFunction(const char *funcName) noexcept
virtual bool Init(const char *libName) noexcept