2#if defined(INCLUDED_BY_FACTORY)
4#include "QubitRegister.h"
5#define _USE_MATH_DEFINES
12class SamplingQubitRegister :
public QC::QubitRegister<>
15 using QC::QubitRegister<>::QubitRegister;
17 size_t MeasureQubitReproducible(
size_t qubit)
19 if (qubit >= NrQubits)
20 throw std::out_of_range(
"Measured qubit is outside the register");
22 return MeasureRemainingQubit(qubit);
23 if (!UseMultithreading())
25 const size_t outcome = QC::QubitRegister<>::MeasureQubit(qubit);
26 RememberMeasurement(qubit, outcome);
34 const double draw = 1. - uniformZeroOne(rng);
35 const size_t mask =
size_t{1} << qubit;
36 const size_t outcome = (BaseClass::SampleBasisState(NrBasisStates, registerStorage, draw, 0,
false) >> qubit) & 1;
37 const size_t lowMask = mask - 1;
38 const size_t selected = outcome << qubit;
39 double probability = 0.;
40 for (
size_t k = 0; k < NrBasisStates / 2; ++k)
41 probability += std::norm(registerStorage(((k & ~lowMask) << 1) | selected | (k & lowMask)));
42 const double norm = 1. / std::sqrt(probability);
44#pragma omp parallel for schedule(static) if (!omp_in_parallel())
46 for (
long long i = 0; i < static_cast<long long>(NrBasisStates); ++i)
47 registerStorage(i) = (
static_cast<size_t>(i) & mask) == selected ? registerStorage(i) * norm : std::complex<double>(0., 0.);
48 if (std::isfinite(norm))
49 RememberMeasurement(qubit, outcome);
53 void InvalidateMeasurements()
55 measuredMask = measuredValues = 0;
61 snapshot = std::make_shared<const Eigen::VectorXcd>(registerStorage);
67 registerStorage = *snapshot;
68 InvalidateMeasurements();
71 void DiscardMeasurementDraw()
75 (void)uniformZeroOne(rng);
78 void ReplaceAmplitudes(
size_t qubits, Eigen::VectorXcd &litudes)
81 NrBasisStates =
static_cast<size_t>(amplitudes.size());
82 registerStorage.swap(amplitudes);
83 savedStateStorage.resize(0);
87 InvalidateMeasurements();
91 void RememberMeasurement(
size_t qubit,
size_t outcome)
93 measuredMask |=
size_t{1} << qubit;
94 measuredValues = (measuredValues & ~(
size_t{1} << qubit)) | (outcome << qubit);
99 size_t Expand(
size_t packed)
const
101 size_t result = measuredValues;
102 for (
size_t free = (NrBasisStates - 1) & ~measuredMask; packed; packed >>= 1)
104 const size_t bit = free & (~free + 1);
112 size_t MeasureRemainingQubit(
size_t qubit)
114 const double draw = 1. - uniformZeroOne(rng);
115 const size_t mask =
size_t{1} << qubit;
116 double cumulative = 0.;
120 for (
size_t i = measuredValues; i < NrBasisStates; i = (((i | measuredMask) + 1) & ~measuredMask) | measuredValues)
122 cumulative += std::norm(registerStorage(i));
123 if (draw <= cumulative)
129 const size_t outcome = (sampled >> qubit) & 1;
130 const size_t selected = outcome << qubit;
131 const size_t fixed = measuredMask | mask;
132 const size_t values = (measuredValues & ~mask) | selected;
133 double probability = 0.;
134 if (!(measuredMask & mask) || (measuredValues & mask) == selected)
135 for (
size_t i = values; i < NrBasisStates; i = (((i | fixed) + 1) & ~fixed) | values)
136 probability += std::norm(registerStorage(i));
137 const double norm = 1. / std::sqrt(probability);
139 if (!std::isfinite(norm))
141 for (
size_t i = 0; i < NrBasisStates; ++i)
142 registerStorage(i) = (i & mask) == selected ? registerStorage(i) * norm : std::complex<double>(0., 0.);
143 InvalidateMeasurements();
146 size_t active = NrBasisStates;
147 for (
size_t bits = measuredMask; bits; bits &= bits - 1)
149 constexpr size_t tileSize = 1024;
150 const size_t tiles = (active + tileSize - 1) / tileSize;
153#pragma omp parallel for schedule(static) if (threads > 1) num_threads(threads)
155 for (
long long tile = 0; tile < static_cast<long long>(tiles); ++tile)
157 size_t index = Expand(
static_cast<size_t>(tile) * tileSize);
158 const size_t end = std::min(active, (
static_cast<size_t>(tile) + 1) * tileSize);
159 for (
size_t k =
static_cast<size_t>(tile) * tileSize; k < end; ++k)
161 registerStorage(index) = (index & mask) == selected ? registerStorage(index) * norm : std::complex<double>(0., 0.);
162 index = (((index | measuredMask) + 1) & ~measuredMask) | measuredValues;
165 RememberMeasurement(qubit, outcome);
169 size_t measuredMask = 0, measuredValues = 0;
170 std::shared_ptr<const Eigen::VectorXcd> snapshot;
174class QCSimStatevectorSimulator :
public QCSimGateSimulator
177 QCSimStatevectorSimulator()
179 configuration.SetConfiguration(
"method",
"statevector");
182 const char *MethodName()
const override
184 return "statevector";
186 friend class IndividualSimulator;
188 struct SamplingProbability
190 const Eigen::VectorXcd *storage;
192 double operator()(
size_t row)
const
194 return std::norm((*storage)[row]);
198 using SamplingPlan = Utils::Sampling::Prepared<SamplingProbability>;
200 SamplingPlan PrepareSampling(
size_t shots)
const
202 return SamplingPlan(
size_t{1} << samplingSupportQubits, shots, SamplingProbability{&state->getRegisterStorage()}, SamplingOptions());
206 void Initialize()
override
210 InitializeSamplingSeed();
211 state = std::make_unique<SamplingQubitRegister>(nrQubits);
212 samplingSupportQubits = savedSamplingSupportQubits = 0;
213 SeedBackend(state.get(), samplingSeed);
215 for (
const auto &[key, value] : configuration.GetConfigMap())
217 Configure(key.c_str(), value.c_str());
221 void InitializeState(
size_t num_qubits, std::vector<std::complex<double>> &litudes)
override
226 nrQubits = num_qubits;
228 Eigen::VectorXcd amplitudesEigen(Eigen::Map<Eigen::VectorXcd, Eigen::Unaligned>(amplitudes.data(), amplitudes.size()));
229 state->setRegisterStorageFastNoNormalize(amplitudesEigen);
230 UpdateSamplingSupport();
234 void InitializeState(
size_t num_qubits, AER::Vector<std::complex<double>> &litudes)
override
239 nrQubits = num_qubits;
241 Eigen::VectorXcd amplitudesEigen(Eigen::Map<Eigen::VectorXcd, Eigen::Unaligned>(amplitudes.data(), amplitudes.size()));
242 state->setRegisterStorageFastNoNormalize(amplitudesEigen);
243 UpdateSamplingSupport();
248 void InitializeState(
size_t num_qubits, Eigen::VectorXcd &litudes)
override
253 nrQubits = num_qubits;
256 state = std::make_unique<SamplingQubitRegister>(nrQubits, amplitudes);
257 state->SetMultithreading(enableMultithreading);
258 SeedBackend(state.get(), samplingSeed);
259 UpdateSamplingSupport();
263 void InitializeToBasisState(
size_t num_qubits,
Types::qubit_t basisState)
override
268 nrQubits = num_qubits;
270 state->setToBasisState(
static_cast<size_t>(basisState));
271 samplingSupportQubits = 0;
272 for (
size_t value = basisState; value; value >>= 1)
273 ++samplingSupportQubits;
276 void Reset()
override
280 state->InvalidateMeasurements();
283 samplingSupportQubits = 0;
284 upcomingGateIndex = 0;
287 void Configure(
const char *key,
const char *value)
override
289 if (ConfigureSampling(key, value))
291 if (std::string(
"method") == key)
293 ValidateMethod(value);
294 configuration.SetConfiguration(key, value);
297 if (!configuration.WasApplied(key, value))
298 configuration.SetConfiguration(key, value);
299 if (std::string(
"seed") == key)
301 const uint64_t seed = std::stoull(value);
302 SeedAuxiliaryRng(seed);
305 SeedBackend(state.get(), seed);
308 if (std::string(key) ==
"pauli_propagator_workers")
310 const auto workers = configuration.GetConfigurationAsUnsigned(key);
312 throw std::invalid_argument(
"pauli_propagator_workers exceeds 1024");
320 const size_t oldNrQubits = nrQubits;
321 nrQubits += num_qubits;
325 void Clear()
override
328 samplingSupportQubits = savedSamplingSupportQubits = 0;
330 upcomingGateIndex = 0;
331 upcomingGates.clear();
336 if (qubits.size() >
sizeof(
size_t) * 8)
337 std::cerr <<
"Warning: The number of qubits to measure is larger than the "
338 "number of bits in the size_t type, the outcome will be undefined"
344 for (
size_t qubit : qubits)
346 if (MeasureQubit(qubit))
352 NotifyObservers(qubits);
358 std::vector<bool> res(qubits.size(),
false);
361 for (
size_t q = 0; q < qubits.size(); ++q)
362 if (MeasureQubit(qubits[q]))
366 NotifyObservers(qubits);
374 for (
size_t qubit : qubits)
375 if (MeasureQubit(qubit))
377 state->InvalidateMeasurements();
378 state->ApplyGate(xgate,
static_cast<unsigned int>(qubit));
382 NotifyObservers(qubits);
385 std::vector<std::complex<double>> GetStateVector()
override
389 const auto count = TensorQueries::DenseSize(nrQubits);
390 const auto values = state->getRegisterStorage();
391 if (
static_cast<size_t>(values.size()) != count)
392 throw std::runtime_error(
"QCSim statevector query returned an invalid size");
393 return {values.data(), values.data() + values.size()};
398 return state->getBasisStateProbability(
static_cast<unsigned int>(outcome));
403 return state->getBasisStateAmplitude(
static_cast<unsigned int>(outcome));
408 const Eigen::VectorXcd probs = state->getRegisterStorage().cwiseAbs2();
409 std::vector<double> result(probs.size());
410 for (
int i = 0; i < probs.size(); ++i)
411 result[i] = probs[i].real();
417 std::vector<double> result(qubits.size());
419 const Eigen::VectorXcd ® = state->getRegisterStorage();
420 for (
int i = 0; i < static_cast<int>(qubits.size()); ++i)
421 result[i] = std::norm(reg[qubits[i]]);
428 if (!LegacySampling())
429 return SamplePrepared<false>(qubits, shots);
430 if (qubits.empty() || shots == 0)
432 if (qubits.size() >
sizeof(
size_t) * 8)
433 std::cerr <<
"Warning: The number of qubits to measure is larger than the "
434 "number of bits in the size_t type, the outcome will be undefined"
436 std::unordered_map<Types::qubit_t, Types::qubit_t> result;
441 const auto &statev = state->getRegisterStorage();
442 const Utils::Alias alias(statev);
443 for (
size_t shot = 0; shot < shots; ++shot)
445 const double prob = 1. - uniformZeroOne(rng);
446 const size_t measRaw = alias.Sample(prob);
449 for (
auto q : qubits)
451 const size_t qubitMask = 1ULL << q;
452 if ((measRaw & qubitMask) != 0)
461 for (
size_t shot = 0; shot < shots; ++shot)
466 for (
auto q : qubits)
468 const size_t qubitMask = 1ULL << q;
469 if ((measRaw & qubitMask) != 0)
478 NotifyObservers(qubits);
484 if (!LegacySampling())
485 return SamplePrepared<true>(qubits, shots);
486 if (qubits.empty() || shots == 0)
493 const auto &statev = state->getRegisterStorage();
494 const Utils::Alias alias(statev);
495 std::vector<bool> meas(qubits.size());
496 for (
size_t shot = 0; shot < shots; ++shot)
498 const double prob = 1. - uniformZeroOne(rng);
499 const size_t measRaw = alias.Sample(prob);
500 for (
size_t i = 0; i < qubits.size(); ++i)
501 meas[i] = ((measRaw >> qubits[i]) & 1) != 0;
507 for (
size_t shot = 0; shot < shots; ++shot)
509 const auto measRaw = MeasureNoCollapseMany();
510 std::vector<bool> meas(qubits.size(),
false);
511 for (
size_t i = 0; i < qubits.size(); ++i)
512 if (measRaw[qubits[i]])
519 NotifyObservers(qubits);
523 double ExpectationValue(
const std::string &pauliStringOrig)
override
525 if (pauliStringOrig.empty())
527 std::string pauliString = pauliStringOrig;
532 const auto pauliOp = toupper(pauliString[i]);
533 if (pauliOp !=
'I' && pauliOp !=
'Z')
538 std::vector<QC::Gates::AppliedGate<Eigen::MatrixXcd>> pauliStringVec;
539 pauliStringVec.reserve(pauliString.size());
540 for (
size_t q = 0; q < pauliString.size(); ++q)
542 switch (toupper(pauliString[q]))
545 QC::Gates::AppliedGate<Eigen::MatrixXcd> ag(xgate.getRawOperatorMatrix(),
static_cast<Types::qubit_t>(q));
546 pauliStringVec.emplace_back(std::move(ag));
550 QC::Gates::AppliedGate<Eigen::MatrixXcd> ag(ygate.getRawOperatorMatrix(),
static_cast<Types::qubit_t>(q));
551 pauliStringVec.emplace_back(std::move(ag));
555 QC::Gates::AppliedGate<Eigen::MatrixXcd> ag(zgate.getRawOperatorMatrix(),
static_cast<Types::qubit_t>(q));
556 pauliStringVec.emplace_back(std::move(ag));
565 if (pauliStringVec.empty())
567 return state->ExpectationValue(pauliStringVec).real();
572 return SimulationType::kStatevector;
578 savedSamplingSupportQubits = samplingSupportQubits;
583 state->InvalidateMeasurements();
584 state->RestoreState();
585 samplingSupportQubits = std::max(samplingSupportQubits, savedSamplingSupportQubits);
590 enableMultithreading = multithreading;
592 state->SetMultithreading(multithreading);
598 std::cerr <<
"Warning: The number of qubits to measure is larger than the "
599 "number of bits in the Types::qubit_t type, the outcome will be "
602 return state->MeasureNoCollapse();
605 std::vector<bool> MeasureNoCollapseMany()
override
608 std::vector<bool> res(nrQubits);
609 for (
size_t i = 0; i < nrQubits; ++i)
610 res[i] = ((state >> i) & 1) == 1;
616 samplingSupportQubits = std::max(samplingSupportQubits,
size_t(qubit) + 1);
617 const QC::Gates::AppliedGate<> agate(gate, qubit);
618 ApplyNativeGate(agate);
619 NotifyObservers({qubit});
624 samplingSupportQubits = std::max({samplingSupportQubits, size_t(qubit0) + 1, size_t(qubit1) + 1});
625 const QC::Gates::AppliedGate<> agate(gate, qubit0, qubit1);
626 ApplyNativeGate(agate);
627 NotifyObservers({qubit0, qubit1});
632 samplingSupportQubits = std::max({samplingSupportQubits, size_t(q0) + 1, size_t(q1) + 1, size_t(q2) + 1});
633 const QC::Gates::AppliedGate<> applied(gate, q0, q1, q2);
634 ApplyNativeGate(applied);
635 NotifyObservers({q0, q1, q2});
640 pgate.SetPhaseShift(lambda);
641 ApplyNativeGate(pgate,
static_cast<unsigned int>(qubit));
642 NotifyObservers({qubit});
647 ApplyNativeGate(xgate,
static_cast<unsigned int>(qubit));
648 NotifyObservers({qubit});
653 ApplyNativeGate(ygate,
static_cast<unsigned int>(qubit));
654 NotifyObservers({qubit});
659 ApplyNativeGate(zgate,
static_cast<unsigned int>(qubit));
660 NotifyObservers({qubit});
665 ApplyNativeGate(h,
static_cast<unsigned int>(qubit));
666 NotifyObservers({qubit});
671 ApplyNativeGate(sgate,
static_cast<unsigned int>(qubit));
672 NotifyObservers({qubit});
677 ApplyNativeGate(sdggate,
static_cast<unsigned int>(qubit));
678 NotifyObservers({qubit});
683 ApplyNativeGate(tgate,
static_cast<unsigned int>(qubit));
684 NotifyObservers({qubit});
689 ApplyNativeGate(tdggate,
static_cast<unsigned int>(qubit));
690 NotifyObservers({qubit});
695 ApplyNativeGate(sxgate,
static_cast<unsigned int>(qubit));
696 NotifyObservers({qubit});
701 ApplyNativeGate(sxdaggate,
static_cast<unsigned int>(qubit));
702 NotifyObservers({qubit});
707 ApplyNativeGate(k,
static_cast<unsigned int>(qubit));
708 NotifyObservers({qubit});
713 rxgate.SetTheta(theta);
714 ApplyNativeGate(rxgate,
static_cast<unsigned int>(qubit));
715 NotifyObservers({qubit});
720 rygate.SetTheta(theta);
721 ApplyNativeGate(rygate,
static_cast<unsigned int>(qubit));
722 NotifyObservers({qubit});
727 rzgate.SetTheta(theta);
728 ApplyNativeGate(rzgate,
static_cast<unsigned int>(qubit));
729 NotifyObservers({qubit});
732 void ApplyU(
Types::qubit_t qubit,
double theta,
double phi,
double lambda,
double gamma)
override
734 ugate.SetParams(theta, phi, lambda, gamma);
735 ApplyNativeGate(ugate,
static_cast<unsigned int>(qubit));
736 NotifyObservers({qubit});
741 ApplyNativeGate(cxgate,
static_cast<unsigned int>(tgt_qubit),
static_cast<unsigned int>(ctrl_qubit));
742 NotifyObservers({tgt_qubit, ctrl_qubit});
747 ApplyNativeGate(cygate,
static_cast<unsigned int>(tgt_qubit),
static_cast<unsigned int>(ctrl_qubit));
748 NotifyObservers({tgt_qubit, ctrl_qubit});
753 ApplyNativeGate(czgate,
static_cast<unsigned int>(tgt_qubit),
static_cast<unsigned int>(ctrl_qubit));
754 NotifyObservers({tgt_qubit, ctrl_qubit});
759 cpgate.SetPhaseShift(lambda);
760 ApplyNativeGate(cpgate,
static_cast<unsigned int>(tgt_qubit),
static_cast<unsigned int>(ctrl_qubit));
761 NotifyObservers({tgt_qubit, ctrl_qubit});
766 crxgate.SetTheta(theta);
767 ApplyNativeGate(crxgate,
static_cast<unsigned int>(tgt_qubit),
static_cast<unsigned int>(ctrl_qubit));
768 NotifyObservers({tgt_qubit, ctrl_qubit});
773 crygate.SetTheta(theta);
774 ApplyNativeGate(crygate,
static_cast<unsigned int>(tgt_qubit),
static_cast<unsigned int>(ctrl_qubit));
775 NotifyObservers({tgt_qubit, ctrl_qubit});
780 crzgate.SetTheta(theta);
781 ApplyNativeGate(crzgate,
static_cast<unsigned int>(tgt_qubit),
static_cast<unsigned int>(ctrl_qubit));
782 NotifyObservers({tgt_qubit, ctrl_qubit});
787 ApplyNativeGate(ch,
static_cast<unsigned int>(tgt_qubit),
static_cast<unsigned int>(ctrl_qubit));
788 NotifyObservers({tgt_qubit, ctrl_qubit});
793 ApplyNativeGate(csx,
static_cast<unsigned int>(tgt_qubit),
static_cast<unsigned int>(ctrl_qubit));
794 NotifyObservers({tgt_qubit, ctrl_qubit});
799 ApplyNativeGate(csxdag,
static_cast<unsigned int>(tgt_qubit),
static_cast<unsigned int>(ctrl_qubit));
800 NotifyObservers({tgt_qubit, ctrl_qubit});
805 ApplyNativeGate(swapgate,
static_cast<unsigned int>(qubit1),
static_cast<unsigned int>(qubit0));
806 NotifyObservers({qubit1, qubit0});
811 ApplyNativeGate(ccxgate,
static_cast<unsigned int>(qubit2),
static_cast<unsigned int>(qubit1),
static_cast<unsigned int>(qubit0));
812 NotifyObservers({qubit2, qubit1, qubit0});
817 ApplyNativeGate(cswapgate,
static_cast<unsigned int>(qubit1),
static_cast<unsigned int>(qubit0),
static_cast<unsigned int>(ctrl_qubit));
818 NotifyObservers({qubit1, qubit0, ctrl_qubit});
823 cugate.SetParams(theta, phi, lambda, gamma);
824 ApplyNativeGate(cugate,
static_cast<unsigned int>(tgt_qubit),
static_cast<unsigned int>(ctrl_qubit));
825 NotifyObservers({tgt_qubit, ctrl_qubit});
828 std::unique_ptr<ISimulator> Clone()
override
830 return CloneForExecution(NextCloneSeed());
833 std::unique_ptr<ISimulator> CloneForExecution(uint64_t seed)
override
835 auto cloned = std::make_unique<QCSimStatevectorSimulator>();
836 cloned->nrQubits = nrQubits;
837 cloned->enableMultithreading = enableMultithreading;
838 cloned->upcomingGates = upcomingGates;
839 cloned->upcomingGateIndex = upcomingGateIndex;
840 cloned->samplingSupportQubits = samplingSupportQubits;
841 cloned->savedSamplingSupportQubits = savedSamplingSupportQubits;
843 cloned->state = std::make_unique<SamplingQubitRegister>(*state);
844 for (
const auto &[key, value] : configuration.GetConfigMap())
845 cloned->Configure(key.c_str(), value.c_str());
846 cloned->SetSeed(seed);
851 std::unique_ptr<SamplingQubitRegister> state;
854 size_t MeasureQubit(
size_t qubit)
856 if (!LegacySampling())
857 return state->MeasureQubitReproducible(qubit);
858 state->InvalidateMeasurements();
859 return state->MeasureQubit(qubit);
864 void ReplaceState(
size_t qubits, Eigen::VectorXcd &litudes)
866 if (!state || !qubits || qubits >= std::numeric_limits<size_t>::digits ||
static_cast<size_t>(amplitudes.size()) != (
size_t{1} << qubits))
867 throw std::invalid_argument(
"Invalid composite replacement state");
868 state->ReplaceAmplitudes(qubits, amplitudes);
870 savedSamplingSupportQubits = 0;
871 upcomingGateIndex = 0;
872 upcomingGates.clear();
873 UpdateSamplingSupport();
878 if (qubits.empty() || !shots)
885 const size_t row = [&] {
886 struct RestoreThreading
888 QC::QubitRegister<> &state;
892 state.SetMultithreading(enabled);
894 } restore{*state, enableMultithreading};
895 state->SetMultithreading(
false);
896 return state->MeasureNoCollapse();
899 NotifyObservers(qubits);
902 const auto plan = PrepareSampling(shots);
904 plan, shots, qubits.size(), [&](
size_t row,
size_t bit) { return ((row >> qubits[bit]) & 1) != 0; },
905 [&] { return Utils::RandomStream::Uniform(rng); });
906 NotifyObservers(qubits);
910 void UpdateSamplingSupport()
915 const auto &storage = state->getRegisterStorage();
916 size_t end =
static_cast<size_t>(storage.size());
917 while (end > 1 && storage[end - 1] == std::complex<double>{})
919 samplingSupportQubits = 0;
920 for (
size_t last = end ? end - 1 : 0; last; last >>= 1)
921 ++samplingSupportQubits;
926 size_t samplingSupportQubits = 0, savedSamplingSupportQubits = 0;
928 template <
class Gate,
class...
Qubits>
void ApplyNativeGate(
const Gate &gate,
Qubits... qubits)
930 state->InvalidateMeasurements();
936 struct RestoreThreading
938 SamplingQubitRegister &state;
943 state.SetMultithreading(enabled);
945 } restore{*state, state->GetMultithreading()};
947 bool hasTeam =
false;
949 hasTeam = !omp_in_parallel() && omp_get_max_threads() > 1;
951 if (!LegacySampling() && !hasTeam)
952 state->SetMultithreading(
false);
953 state->ApplyGate(gate, qubits...);
954 ((samplingSupportQubits = std::max(samplingSupportQubits,
size_t(qubits) + 1)), ...);
int ApplyK(void *sim, int qubit)
double Probability(void *sim, unsigned long long int outcome)
int RestoreState(void *sim)
int ApplyRx(void *sim, int qubit, double theta)
int ApplyReset(void *sim, const unsigned long int *qubits, unsigned long int nrQubits)
int ApplyX(void *sim, int qubit)
int ApplyU(void *sim, int qubit, double theta, double phi, double lambda, double gamma)
int ApplyCRy(void *sim, int controlQubit, int targetQubit, double theta)
int ApplyTDG(void *sim, int qubit)
int ApplyS(void *sim, int qubit)
int ApplyCX(void *sim, int controlQubit, int targetQubit)
unsigned long int AllocateQubits(void *sim, unsigned long int nrQubits)
int ApplyCRz(void *sim, int controlQubit, int targetQubit, double theta)
unsigned long int GetNumberOfQubits(void *sim)
double * AllProbabilities(void *sim)
unsigned long long int MeasureNoCollapse(void *sim)
int ApplyCP(void *sim, int controlQubit, int targetQubit, double theta)
int GetMultithreading(void *sim)
int ApplySDG(void *sim, int qubit)
unsigned long long int Measure(void *sim, const unsigned long int *qubits, unsigned long int nrQubits)
int ApplyCSwap(void *sim, int controlQubit, int qubit1, int qubit2)
int ApplyCCX(void *sim, int controlQubit1, int controlQubit2, int targetQubit)
int ApplyY(void *sim, int qubit)
double * Amplitude(void *sim, unsigned long long int outcome)
int ApplyZ(void *sim, int qubit)
int ApplyH(void *sim, int qubit)
int ApplyGenericThreeQubitGate(void *sim, unsigned long q0, unsigned long q1, unsigned long q2, const double *buffer)
int ApplyCY(void *sim, int controlQubit, int targetQubit)
double * Probabilities(void *sim, const unsigned long long int *qubits, unsigned long int nrQubits)
int SetMultithreading(void *sim, int multithreading)
int ApplyCU(void *sim, int controlQubit, int targetQubit, double theta, double phi, double lambda, double gamma)
int ApplySwap(void *sim, int qubit1, int qubit2)
int ApplyRy(void *sim, int qubit, double theta)
int ApplyP(void *sim, int qubit, double theta)
int ApplyCH(void *sim, int controlQubit, int targetQubit)
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 ApplyCZ(void *sim, int controlQubit, int targetQubit)
int ApplyRz(void *sim, int qubit, double theta)
int ApplyT(void *sim, int qubit)
int ApplyCRx(void *sim, int controlQubit, int targetQubit, double theta)
int ApplyGenericOneQubitGate(void *sim, unsigned long q0, const double *buffer)
int ApplyGenericTwoQubitGate(void *sim, unsigned long q0, unsigned long q1, const double *buffer)
std::vector< int > Qubits(const Types::qubits_vector &qubits, size_t width)
SimulationType
The type of simulation.
std::vector< qubit_t > qubits_vector
The type of a vector of qubits.
uint_fast64_t qubit_t
The type of a qubit.
Counts< Many > Count(const Plan &plan, size_t shots, size_t bits, const Bit &bit, Uniform &&uniform)
int Threads(bool permitted, size_t work)
Counts< Many > Single(size_t bits, const Bit &bit)
void ValidateQubits(const Qubits &qubits, size_t width, bool many)
std::unordered_map< std::conditional_t< Many, std::vector< bool >, Types::qubit_t >, Types::qubit_t > Counts