Qrack  10.0
General classical-emulating-quantum development framework
qunit.hpp
Go to the documentation of this file.
1 //
3 // (C) Daniel Strano and the Qrack contributors 2017-2023. All rights reserved.
4 //
5 // QUnit maintains explicit separability of qubits as an optimization on a QEngine.
6 // See https://arxiv.org/abs/1710.05867
7 // (The makers of Qrack have no affiliation with the authors of that paper.)
8 //
9 // Licensed under the GNU Lesser General Public License V3.
10 // See LICENSE.md in the project root or https://www.gnu.org/licenses/lgpl-3.0.en.html
11 // for details.
12 
13 #pragma once
14 
15 #include "qengineshard.hpp"
16 #include "qparity.hpp"
17 
18 #if ENABLE_ALU
19 #include "qalu.hpp"
20 #endif
21 
22 namespace Qrack {
23 
24 class QUnit;
25 typedef std::shared_ptr<QUnit> QUnitPtr;
26 
27 #if ENABLE_ALU
28 class QUnit : public QAlu, public QParity, public QInterface {
29 #else
30 class QUnit : public QParity, public QInterface {
31 #endif
32 protected:
34  bool useHostRam;
36  bool useTGadget;
37  bool isBdt;
38  bool isCpu;
40  bool isSparse;
41  size_t aceMb;
46  double logFidelity;
47  int64_t devID;
50  std::vector<int64_t> deviceIDs;
51  std::vector<QInterfaceEngine> engines;
52 
53  QInterfacePtr MakeEngine(bitLenInt length, const bitCapInt& perm);
54 
55  virtual void Copy(QInterfacePtr orig) { Copy(std::dynamic_pointer_cast<QUnit>(orig)); }
56  virtual void Copy(QUnitPtr orig)
57  {
58  QInterface::Copy(orig);
59  freezeBasis2Qb = orig->freezeBasis2Qb;
60  useHostRam = orig->useHostRam;
61  isReactiveSeparate = orig->isReactiveSeparate;
62  useTGadget = orig->useTGadget;
63  thresholdQubits = orig->thresholdQubits;
64  separabilityThreshold = orig->separabilityThreshold;
65  roundingThreshold = orig->roundingThreshold;
66  logFidelity = orig->logFidelity;
67  devID = orig->devID;
68  phaseFactor = orig->phaseFactor;
69  shards = orig->shards;
70  deviceIDs = orig->deviceIDs;
71  engines = orig->engines;
72  }
73 
74  double PhaseInfidelity(const complex& p) { return (double)clampProb(abs(arg(p)) / PI_R1); }
75 
76  // Drafted by Ellie (the OpenAI custom GPT instance), refined by Dan
77  // Returns payload factor in [0,3] = negator + phase0 + phase1
78  // clamped to range [0,2] as lower bound for general worst-case input
79  // m: row-major [u00, u01, u10, u11]
81  {
82  const complex& u00 = m[0];
83  const complex& u01 = m[1];
84  const complex& u10 = m[2];
85  const complex& u11 = m[3];
86 
87  // Negator strength: average off-diagonal power
88  const real1_f n01 = norm(u01);
89  const real1_f n10 = norm(u10);
90  const real1_f N = clampProb((n01 + n10) / 2);
91 
92  // Phase contributions per "input basis branch", weighted by where amplitude goes
93  const real1_f n00 = norm(u00);
94  const real1_f n11 = norm(u11);
95  const real1_f P0 = clampProb(n00 * PhaseInfidelity(u00) + n10 * PhaseInfidelity(u10));
96  const real1_f P1 = clampProb(n11 * PhaseInfidelity(u11) + n01 * PhaseInfidelity(u01));
97 
98  return (double)clampProb((N + P0 + P1) / 2) * 2;
99  }
100 
102  {
103 #if ENABLE_ENV_VARS
104  if ((!(bool)getenv("QRACK_DISABLE_QUNIT_FIDELITY_GUARD")) && (logFidelity <= FIDELITY_MIN)) {
105 #else
106  if (logFidelity <= FIDELITY_MIN) {
107 #endif
108  throw std::runtime_error("QUnit fidelity estimate is effectively 0! (This DOES NOT mean your fidelity is "
109  "necessarily close to 0! Please read the Qrack README, and then, afterward, "
110  "consider setting environment variable QRACK_DISABLE_QUNIT_FIDELITY_GUARD=1.)");
111  }
112  }
113 
114  void ElideCz(
115  const bool& isAnti, const bitLenInt& control, const bitLenInt& target, const real1_f& pth, const real1_f& pc)
116  {
117  // Act CNOT shadow.
118  const bool ptHi = pth > pc;
119  const real1_f pHi = ptHi ? pth : pc;
120  const real1_f pLo = ptHi ? pc : pth;
121  const bool pState = abs(pHi - HALF_R1) >= abs(pLo - HALF_R1);
122 
123  logFidelity += (double)log(pState ? pHi : (ONE_R1_F - pLo));
124  CheckFidelity();
125 
126  if (pState) {
127  if (!ptHi) {
128  Phase(ONE_CMPLX, -ONE_CMPLX, target);
129  } else if (isAnti) {
130  // This makes absolutely no detectable difference,
131  // according to canonical quantum mechanics.
132  // Trump is Hitler, by the way, and Dan needs
133  // to make that explicitly obvious as part of
134  // the statement of free speech that is Qrack.
135  // (I'm saying, you should've already known.)
136  Phase(-ONE_CMPLX, ONE_CMPLX, control);
137  } else {
138  Phase(ONE_CMPLX, -ONE_CMPLX, control);
139  }
140  }
141  }
142 
143 public:
144  QUnit(std::vector<QInterfaceEngine> eng, bitLenInt qBitCount, const bitCapInt& initState = ZERO_BCI,
145  qrack_rand_gen_ptr rgp = nullptr, const complex& phaseFac = CMPLX_DEFAULT_ARG, bool doNorm = false,
146  bool randomGlobalPhase = true, bool useHostMem = false, int64_t deviceId = -1, bool useHardwareRNG = true,
147  bool ignored = false, real1_f norm_thresh = REAL1_EPSILON, std::vector<int64_t> devIDs = {},
148  bitLenInt qubitThreshold = 0U, real1_f separation_thresh = _qrack_qunit_sep_thresh);
149 
150  QUnit(bitLenInt qBitCount, const bitCapInt& initState = ZERO_BCI, qrack_rand_gen_ptr rgp = nullptr,
151  const complex& phaseFac = CMPLX_DEFAULT_ARG, bool doNorm = false, bool randomGlobalPhase = true,
152  bool useHostMem = false, int64_t deviceId = -1, bool useHardwareRNG = true, bool ignored = false,
153  real1_f norm_thresh = REAL1_EPSILON, std::vector<int64_t> devIDs = {}, bitLenInt qubitThreshold = 0U,
154  real1_f separation_thresh = _qrack_qunit_sep_thresh)
155  : QUnit({ QINTERFACE_STABILIZER_HYBRID }, qBitCount, initState, rgp, phaseFac, doNorm, randomGlobalPhase,
156  useHostMem, deviceId, useHardwareRNG, ignored, norm_thresh, devIDs, qubitThreshold, separation_thresh)
157  {
158  }
159 
160  virtual ~QUnit() { Dump(); }
161 
162  virtual void SetConcurrency(uint32_t threadsPerEngine)
163  {
164  QInterface::SetConcurrency(threadsPerEngine);
166  [](QInterfacePtr unit, real1_f unused1, real1_f unused2, real1_f unused3, int64_t threadsPerEngine,
167  std::vector<int64_t> unused4) {
168  unit->SetConcurrency((uint32_t)threadsPerEngine);
169  return true;
170  },
171  ZERO_R1_F, ZERO_R1_F, ZERO_R1_F, threadsPerEngine);
172  }
173 
174  virtual void SetTInjection(bool useGadget)
175  {
176  useTGadget = useGadget;
178  [](QInterfacePtr unit, real1_f unused1, real1_f unused2, real1_f unused3, int64_t useGadget,
179  std::vector<int64_t> unused4) {
180  unit->SetTInjection((bool)useGadget);
181  return true;
182  },
183  ZERO_R1_F, ZERO_R1_F, ZERO_R1_F, useGadget ? 1U : 0U);
184  }
185 
186  virtual void SetReactiveSeparate(bool isAggSep) { isReactiveSeparate = isAggSep; }
187  virtual bool GetReactiveSeparate() { return isReactiveSeparate; }
188 
189  virtual void SetDevice(int64_t dID);
190  virtual void SetDeviceList(std::vector<int64_t> dIDs);
191  virtual int64_t GetDevice() { return devID; }
192  virtual std::vector<int64_t> GetDeviceList() { return deviceIDs; }
193 
194  virtual real1_f ProbRdm(bitLenInt qubit)
195  {
196  if (qubit >= qubitCount) {
197  throw std::invalid_argument("Qubit index " + std::to_string(qubit) + " out of range in QUnit::ProbRdm!");
198  }
199 
200  const QEngineShard& shard = shards[qubit];
201  if (!shard.unit) {
202  return Prob(qubit);
203  }
204 
205  return shard.unit->ProbRdm(qubit);
206  }
207  virtual real1_f CProbRdm(bitLenInt control, bitLenInt target)
208  {
209  AntiCNOT(control, target);
210  const real1_f prob = ProbRdm(target);
211  AntiCNOT(control, target);
212 
213  return prob;
214  }
215  virtual real1_f ACProbRdm(bitLenInt control, bitLenInt target)
216  {
217  CNOT(control, target);
218  const real1_f prob = ProbRdm(target);
219  CNOT(control, target);
220 
221  return prob;
222  }
223 
224  virtual void SetQuantumState(const complex* inputState);
225  virtual void GetQuantumState(complex* outputState) { GetQuantumStateOrProbs(outputState, nullptr); }
226  virtual void GetProbs(real1* outputProbs) { GetQuantumStateOrProbs(nullptr, outputProbs); }
227  virtual void GetQuantumStateOrProbs(complex* outputState, real1* outputProbs);
228  virtual complex GetAmplitude(const bitCapInt& perm);
229  virtual void SetAmplitude(const bitCapInt& perm, const complex& amp)
230  {
231  if (!qubitCount) {
232  throw std::domain_error("QUnit::SetAmplitude called for 0 qubits!");
233  }
234 
235  if (bi_compare(perm, maxQPower) >= 0) {
236  throw std::invalid_argument("QUnit::SetAmplitude argument out-of-bounds!");
237  }
238 
239  EntangleAll();
240  shards[0U].unit->SetAmplitude(perm, amp);
241  }
242  virtual void SetPermutation(const bitCapInt& perm, const complex& phaseFac = CMPLX_DEFAULT_ARG);
243  using QInterface::Compose;
244  virtual bitLenInt Compose(QUnitPtr toCopy) { return Compose(toCopy, qubitCount); }
245  virtual bitLenInt Compose(QInterfacePtr toCopy) { return Compose(std::dynamic_pointer_cast<QUnit>(toCopy)); }
246  virtual bitLenInt Compose(QUnitPtr toCopy, bitLenInt start)
247  {
248  if (start > qubitCount) {
249  throw std::invalid_argument("QUnit::Compose start index is out-of-bounds!");
250  }
251 
252  ToPermBasisAll();
253 
254  /* Create a clone of the quantum state in toCopy. */
255  QUnitPtr clone = std::dynamic_pointer_cast<QUnit>(toCopy->Clone());
256 
257  clone->ToPermBasisAll();
258 
259  /* Insert the new shards in the middle */
260  shards.insert(start, clone->shards);
261 
262  SetQubitCount(qubitCount + toCopy->GetQubitCount());
263 
264  return start;
265  }
266  virtual bitLenInt Compose(QInterfacePtr toCopy, bitLenInt start)
267  {
268  return Compose(std::dynamic_pointer_cast<QUnit>(toCopy), start);
269  }
270  virtual void Decompose(bitLenInt start, QInterfacePtr dest)
271  {
272  Decompose(start, std::dynamic_pointer_cast<QUnit>(dest));
273  }
274  virtual void Decompose(bitLenInt start, QUnitPtr dest) { Detach(start, dest->GetQubitCount(), dest); }
276  {
277  QUnitPtr dest = std::make_shared<QUnit>(engines, length, ZERO_BCI, rand_generator, phaseFactor, doNormalize,
280 
281  Decompose(start, dest);
282 
283  return dest;
284  }
285  virtual void Dispose(bitLenInt start, bitLenInt length) { Detach(start, length, nullptr); }
286  virtual void Dispose(bitLenInt start, bitLenInt length, const bitCapInt& disposedPerm)
287  {
288  Detach(start, length, nullptr);
289  }
290  virtual bool TryDecompose(bitLenInt start, QInterfacePtr dest, real1_f error_tol = TRYDECOMPOSE_EPSILON)
291  {
292  return TryDecompose(start, std::dynamic_pointer_cast<QUnit>(dest), error_tol);
293  }
294  virtual bool TryDecompose(bitLenInt start, QUnitPtr dest, real1_f error_tol = TRYDECOMPOSE_EPSILON)
295  {
296  return Detach(start, dest->GetQubitCount(), dest, true, error_tol);
297  }
298  using QInterface::Allocate;
299  virtual bitLenInt Allocate(bitLenInt start, bitLenInt length);
300 
306  using QInterface::H;
307  virtual void H(bitLenInt target);
308  using QInterface::S;
309  virtual void S(bitLenInt target);
310  using QInterface::IS;
311  virtual void IS(bitLenInt target);
312 
313  virtual void ZMask(const bitCapInt& mask) { PhaseParity(PI_R1, mask); }
314  virtual void PhaseParity(real1 radians, const bitCapInt& mask);
315 
316  virtual void Phase(const complex& topLeft, const complex& bottomRight, bitLenInt qubitIndex);
317  virtual void Invert(const complex& topRight, const complex& bottomLeft, bitLenInt qubitIndex);
318  virtual void MCPhase(
319  const std::vector<bitLenInt>& controls, const complex& topLeft, const complex& bottomRight, bitLenInt target)
320  {
321  bitCapInt m = pow2(controls.size());
322  bi_decrement(&m, 1U);
323  UCPhase(controls, topLeft, bottomRight, target, m);
324  }
325  virtual void MCInvert(
326  const std::vector<bitLenInt>& controls, const complex& topRight, const complex& bottomLeft, bitLenInt target)
327  {
328  bitCapInt m = pow2(controls.size());
329  bi_decrement(&m, 1U);
330  UCInvert(controls, topRight, bottomLeft, target, m);
331  }
332  virtual void MACPhase(
333  const std::vector<bitLenInt>& controls, const complex& topLeft, const complex& bottomRight, bitLenInt target)
334  {
335  UCPhase(controls, topLeft, bottomRight, target, ZERO_BCI);
336  }
337  virtual void MACInvert(
338  const std::vector<bitLenInt>& controls, const complex& topRight, const complex& bottomLeft, bitLenInt target)
339  {
340  UCInvert(controls, topRight, bottomLeft, target, ZERO_BCI);
341  }
342  virtual void UCPhase(const std::vector<bitLenInt>& controls, const complex& topLeft, const complex& bottomRight,
343  bitLenInt target, const bitCapInt& controlPerm);
344  virtual void UCInvert(const std::vector<bitLenInt>& controls, const complex& topRight, const complex& bottomLeft,
345  bitLenInt target, const bitCapInt& controlPerm);
346  virtual void Mtrx(const complex* mtrx, bitLenInt qubit);
347  virtual void MCMtrx(const std::vector<bitLenInt>& controls, const complex* mtrx, bitLenInt target)
348  {
349  bitCapInt m = pow2(controls.size());
350  bi_decrement(&m, 1U);
351  UCMtrx(controls, mtrx, target, m);
352  }
353  virtual void MACMtrx(const std::vector<bitLenInt>& controls, const complex* mtrx, bitLenInt target)
354  {
355  UCMtrx(controls, mtrx, target, ZERO_BCI);
356  }
357  virtual void UCMtrx(
358  const std::vector<bitLenInt>& controls, const complex* mtrx, bitLenInt target, const bitCapInt& controlPerm);
360  virtual void UniformlyControlledSingleBit(const std::vector<bitLenInt>& controls, bitLenInt qubitIndex,
361  const complex* mtrxs, const std::vector<bitCapInt>& mtrxSkipPowers, const bitCapInt& mtrxSkipValueMask);
362  virtual void CUniformParityRZ(const std::vector<bitLenInt>& controls, const bitCapInt& mask, real1_f angle);
363  virtual void CSwap(const std::vector<bitLenInt>& controls, bitLenInt qubit1, bitLenInt qubit2);
364  virtual void AntiCSwap(const std::vector<bitLenInt>& controls, bitLenInt qubit1, bitLenInt qubit2);
365  virtual void CSqrtSwap(const std::vector<bitLenInt>& controls, bitLenInt qubit1, bitLenInt qubit2);
366  virtual void AntiCSqrtSwap(const std::vector<bitLenInt>& controls, bitLenInt qubit1, bitLenInt qubit2);
367  virtual void CISqrtSwap(const std::vector<bitLenInt>& controls, bitLenInt qubit1, bitLenInt qubit2);
368  virtual void AntiCISqrtSwap(const std::vector<bitLenInt>& controls, bitLenInt qubit1, bitLenInt qubit2);
369  using QInterface::ForceM;
370  virtual bool ForceM(bitLenInt qubitIndex, bool result, bool doForce = true, bool doApply = true);
371  using QInterface::ForceMReg;
372  virtual bitCapInt ForceMReg(
373  bitLenInt start, bitLenInt length, const bitCapInt& result, bool doForce = true, bool doApply = true);
374  virtual bitCapInt HighestProbAll();
375  virtual bitCapInt MAll();
376  virtual std::map<bitCapInt, int> MultiShotMeasureMask(const std::vector<bitCapInt>& qPowers, unsigned shots);
377  virtual void MultiShotMeasureMask(
378  const std::vector<bitCapInt>& qPowers, unsigned shots, unsigned long long* shotsArray);
379 
382 #if ENABLE_ALU
383  using QInterface::M;
384  virtual bool M(bitLenInt q) { return QInterface::M(q); }
385  using QInterface::X;
386  virtual void X(bitLenInt q) { QInterface::X(q); }
387 
394  virtual void DEC(const bitCapInt& toSub, bitLenInt start, bitLenInt length)
395  {
396  QInterface::DEC(toSub, start, length);
397  }
398  virtual void DECS(const bitCapInt& toSub, bitLenInt start, bitLenInt length, bitLenInt overflowIndex)
399  {
400  QInterface::DECS(toSub, start, length, overflowIndex);
401  }
402  virtual void CINC(
403  const bitCapInt& toAdd, bitLenInt inOutStart, bitLenInt length, const std::vector<bitLenInt>& controls)
404  {
405  QInterface::CINC(toAdd, inOutStart, length, controls);
406  }
407  virtual void CDEC(
408  const bitCapInt& toSub, bitLenInt inOutStart, bitLenInt length, const std::vector<bitLenInt>& controls)
409  {
410  QInterface::CDEC(toSub, inOutStart, length, controls);
411  }
412  virtual void INCDECC(const bitCapInt& toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
413  {
414  QInterface::INCDECC(toAdd, start, length, carryIndex);
415  }
416  virtual void MULModNOut(
417  const bitCapInt& toMul, const bitCapInt& modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length)
418  {
419  QInterface::MULModNOut(toMul, modN, inStart, outStart, length);
420  }
421  virtual void IMULModNOut(
422  const bitCapInt& toMul, const bitCapInt& modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length)
423  {
424  QInterface::IMULModNOut(toMul, modN, inStart, outStart, length);
425  }
426  virtual void CMULModNOut(const bitCapInt& toMul, const bitCapInt& modN, bitLenInt inStart, bitLenInt outStart,
427  bitLenInt length, const std::vector<bitLenInt>& controls)
428  {
429  QInterface::CMULModNOut(toMul, modN, inStart, outStart, length, controls);
430  }
431  virtual void CIMULModNOut(const bitCapInt& toMul, const bitCapInt& modN, bitLenInt inStart, bitLenInt outStart,
432  bitLenInt length, const std::vector<bitLenInt>& controls)
433  {
434  QInterface::CIMULModNOut(toMul, modN, inStart, outStart, length, controls);
435  }
436 
437  virtual void INC(const bitCapInt& toAdd, bitLenInt start, bitLenInt length);
438  virtual void INCC(const bitCapInt& toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex);
439  virtual void INCS(const bitCapInt& toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex);
440  virtual void INCDECSC(
441  const bitCapInt& toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex, bitLenInt carryIndex);
442  virtual void INCDECSC(const bitCapInt& toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex);
443  virtual void DECC(const bitCapInt& toSub, bitLenInt start, bitLenInt length, bitLenInt carryIndex);
444 #if ENABLE_BCD
445  virtual void INCBCD(const bitCapInt& toAdd, bitLenInt start, bitLenInt length);
446  virtual void DECBCD(const bitCapInt& toAdd, bitLenInt start, bitLenInt length);
447  virtual void INCDECBCDC(const bitCapInt& toSub, bitLenInt start, bitLenInt length, bitLenInt carryIndex);
448 #endif
449  virtual void MUL(const bitCapInt& toMul, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length);
450  virtual void DIV(const bitCapInt& toDiv, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length);
451  virtual void POWModNOut(
452  const bitCapInt& base, const bitCapInt& modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length);
453  virtual void CMUL(const bitCapInt& toMul, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length,
454  const std::vector<bitLenInt>& controls);
455  virtual void CDIV(const bitCapInt& toDiv, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length,
456  const std::vector<bitLenInt>& controls);
457  virtual void CPOWModNOut(const bitCapInt& base, const bitCapInt& modN, bitLenInt inStart, bitLenInt outStart,
458  bitLenInt length, const std::vector<bitLenInt>& controls);
459  virtual bitCapInt IndexedLDA(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart,
460  bitLenInt valueLength, const unsigned char* values, bool resetValue = true);
461  virtual bitCapInt IndexedADC(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart,
462  bitLenInt valueLength, bitLenInt carryIndex, const unsigned char* values);
463  virtual bitCapInt IndexedSBC(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart,
464  bitLenInt valueLength, bitLenInt carryIndex, const unsigned char* values);
465  virtual void Hash(bitLenInt start, bitLenInt length, const unsigned char* values);
466  virtual void CPhaseFlipIfLess(const bitCapInt& greaterPerm, bitLenInt start, bitLenInt length, bitLenInt flagIndex);
467  virtual void PhaseFlipIfLess(const bitCapInt& greaterPerm, bitLenInt start, bitLenInt length);
468 
470 #endif
471 
478  virtual void SetReg(bitLenInt start, bitLenInt length, const bitCapInt& value);
479  virtual void Swap(bitLenInt qubit1, bitLenInt qubit2)
480  {
481  if (qubit1 >= qubitCount) {
482  throw std::invalid_argument("QUnit::Swap qubit index parameter must be within allocated qubit bounds!");
483  }
484 
485  if (qubit2 >= qubitCount) {
486  throw std::invalid_argument("QUnit::Swap qubit index parameter must be within allocated qubit bounds!");
487  }
488 
489  if (qubit1 == qubit2) {
490  return;
491  }
492 
493  // Simply swap the bit mapping.
494  shards.swap(qubit1, qubit2);
495  }
496  virtual void ISwap(bitLenInt qubit1, bitLenInt qubit2) { EitherISwap(qubit1, qubit2, false); }
497  virtual void IISwap(bitLenInt qubit1, bitLenInt qubit2) { EitherISwap(qubit1, qubit2, true); }
498  virtual void SqrtSwap(bitLenInt qubit1, bitLenInt qubit2);
499  virtual void ISqrtSwap(bitLenInt qubit1, bitLenInt qubit2);
500 
509  virtual real1_f Prob(bitLenInt qubit)
510  {
511  if (qubit >= qubitCount) {
512  throw std::invalid_argument("QUnit::Prob target parameter must be within allocated qubit bounds!");
513  }
514 
515  ToPermBasisProb(qubit);
516  return ProbBase(qubit);
517  }
518  virtual real1_f ProbAll(const bitCapInt& perm) { return clampProb((real1_f)norm(GetAmplitudeOrProb(perm, true))); }
519  virtual real1_f ProbAllRdm(bool roundRz, const bitCapInt& perm)
520  {
521  if (!qubitCount) {
522  throw std::domain_error("QUnit::ProbAllRdm called for 0 qubits!");
523  }
524 
525  if (shards[0U].unit && (shards[0U].unit->GetQubitCount() == qubitCount)) {
526  OrderContiguous(shards[0U].unit);
527  return shards[0U].unit->ProbAllRdm(roundRz, perm);
528  }
529 
530  QUnitPtr clone = std::dynamic_pointer_cast<QUnit>(Clone());
531  QInterfacePtr unit = clone->EntangleAll(true);
532  clone->OrderContiguous(unit);
533 
534  return unit->ProbAllRdm(roundRz, perm);
535  }
536  virtual real1_f ProbParity(const bitCapInt& mask);
537  virtual bool ForceMParity(const bitCapInt& mask, bool result, bool doForce = true);
538  virtual real1_f SumSqrDiff(QInterfacePtr toCompare)
539  {
540  return SumSqrDiff(std::dynamic_pointer_cast<QUnit>(toCompare));
541  }
542  virtual real1_f SumSqrDiff(QUnitPtr toCompare);
544  const std::vector<bitLenInt>& bits, const std::vector<bitCapInt>& perms, const bitCapInt& offset = ZERO_BCI)
545  {
546  return ExpVarFactorized(true, false, false, bits, perms, std::vector<real1_f>(), offset, false);
547  }
548  virtual real1_f ExpectationBitsFactorizedRdm(bool roundRz, const std::vector<bitLenInt>& bits,
549  const std::vector<bitCapInt>& perms, const bitCapInt& offset = ZERO_BCI)
550  {
551  return ExpVarFactorized(true, true, false, bits, perms, std::vector<real1_f>(), offset, roundRz);
552  }
554  const std::vector<bitLenInt>& bits, const std::vector<bitCapInt>& perms, const bitCapInt& offset = ZERO_BCI)
555  {
556  return ExpVarFactorized(false, false, false, bits, perms, std::vector<real1_f>(), offset, false);
557  }
558  virtual real1_f VarianceBitsFactorizedRdm(bool roundRz, const std::vector<bitLenInt>& bits,
559  const std::vector<bitCapInt>& perms, const bitCapInt& offset = ZERO_BCI)
560  {
561  return ExpVarFactorized(false, true, false, bits, perms, std::vector<real1_f>(), offset, roundRz);
562  }
563  virtual void UpdateRunningNorm(real1_f norm_thresh = REAL1_DEFAULT_ARG);
564  virtual void NormalizeState(
565  real1_f nrm = REAL1_DEFAULT_ARG, real1_f norm_thresh = REAL1_DEFAULT_ARG, real1_f phaseArg = ZERO_R1_F);
566  virtual void Finish();
567  virtual bool isFinished();
568  virtual void Dump()
569  {
570  for (QEngineShard& shard : shards) {
571  // Setting shard to NULL seems theoretically memory-safe, as previously used here,
572  // but it's safer (in the intent of dumping remaining QInterface work)
573  // to set shard.unit to nullptr.
574  shard.unit = nullptr;
575  }
576  }
578  virtual bool isClifford(bitLenInt qubit)
579  {
580  if (qubit >= qubitCount) {
581  throw std::invalid_argument("Qubit index " + std::to_string(qubit) + " out of range in QUnit::isClifford!");
582  }
583 
584  return shards[qubit].isClifford();
585  };
586 
588  virtual bool TrySeparate(bitLenInt qubit);
589  virtual bool TrySeparate(bitLenInt qubit1, bitLenInt qubit2);
590  virtual bool TrySeparate(const std::vector<bitLenInt>& qubits, real1_f error_tol)
591  {
592  for (size_t i = 0U; i < qubits.size(); ++i) {
593  Swap(qubitCount - (i + 1U), qubits[i]);
594  }
595 
596  QUnitPtr dest = std::make_shared<QUnit>(engines, qubits.size(), ZERO_BCI, rand_generator, phaseFactor,
599 
600  const bool result = TryDecompose(qubitCount - qubits.size(), dest);
601  if (result) {
602  Compose(dest);
603  }
604 
605  for (bitLenInt i = qubits.size(); i > 0U; --i) {
606  Swap(qubitCount - i, qubits[i - 1U]);
607  }
608 
609  return result;
610  }
611  virtual double GetUnitaryFidelity();
612  virtual void ResetUnitaryFidelity() { logFidelity = 0.0; }
613  virtual void SetSdrp(real1_f sdrp)
614  {
615  separabilityThreshold = sdrp;
617  };
618  virtual void SetNcrp(real1_f ncrp)
619  {
620  roundingThreshold = ncrp;
622  [](QInterfacePtr unit, real1_f rp, real1_f unused, real1_f unused2, int64_t unused3,
623  std::vector<int64_t> unused4) {
624  unit->SetNcrp(rp);
625  return true;
626  },
627  ncrp, ZERO_R1_F, ZERO_R1_F, 0);
628  }
629  virtual void SetAceMaxQubits(bitLenInt qb) { aceQubits = qb; }
630  virtual void SetSparseAceMaxMb(size_t mb) { aceMb = mb; }
631 
632  virtual QInterfacePtr Clone();
633  virtual QInterfacePtr Copy();
634 
637 protected:
638  virtual complex GetAmplitudeOrProb(const bitCapInt& perm, bool isProb);
639 
640  virtual void XBase(bitLenInt target)
641  {
642  if (target >= qubitCount) {
643  throw std::invalid_argument("QUnit::XBase qubit index parameter must be within allocated qubit bounds!");
644  }
645 
646  QEngineShard& shard = shards[target];
647 
648  if (shard.unit) {
649  shard.unit->X(shard.mapped);
650  }
651 
652  std::swap(shard.amp0, shard.amp1);
653  }
654 
655  virtual void YBase(bitLenInt target)
656  {
657  if (target >= qubitCount) {
658  throw std::invalid_argument("QUnit::YBase qubit index parameter must be within allocated qubit bounds!");
659  }
660 
661  QEngineShard& shard = shards[target];
662 
663  if (shard.unit) {
664  shard.unit->Y(shard.mapped);
665  }
666 
667  const complex Y0 = shard.amp0;
668  shard.amp0 = -I_CMPLX * shard.amp1;
669  shard.amp1 = I_CMPLX * Y0;
670  }
671 
672  virtual void ZBase(bitLenInt target)
673  {
674  if (target >= qubitCount) {
675  throw std::invalid_argument("QUnit::ZBase qubit index parameter must be within allocated qubit bounds!");
676  }
677 
678  QEngineShard& shard = shards[target];
679 
680  if (shard.unit) {
681  shard.unit->Z(shard.mapped);
682  }
683 
684  shard.amp1 = -shard.amp1;
685  }
686  virtual real1_f ProbBase(bitLenInt qubit);
687 
688  virtual bool TrySeparateClifford(bitLenInt qubit);
689 
690  virtual void EitherISwap(bitLenInt qubit1, bitLenInt qubit2, bool isInverse);
691 
692 #if ENABLE_ALU
693  typedef void (QAlu::*INCxFn)(const bitCapInt&, bitLenInt, bitLenInt, bitLenInt);
695  typedef void (QAlu::*CMULFn)(const bitCapInt&, bitLenInt, bitLenInt, bitLenInt, const std::vector<bitLenInt>&);
696  typedef void (QAlu::*CMULModFn)(
697  const bitCapInt&, const bitCapInt&, bitLenInt, bitLenInt, bitLenInt, const std::vector<bitLenInt>&);
698  void INT(const bitCapInt& toMod, bitLenInt start, bitLenInt length, bitLenInt carryIndex, bool hasCarry,
699  std::vector<bitLenInt> controlVec = std::vector<bitLenInt>());
700  void INTS(const bitCapInt& toMod, bitLenInt start, bitLenInt length, bitLenInt overflowIndex, bitLenInt carryIndex,
701  bool hasCarry);
702  void INCx(INCxFn fn, const bitCapInt& toMod, bitLenInt start, bitLenInt length, bitLenInt flagIndex);
703  void INCxx(INCxxFn fn, const bitCapInt& toMod, bitLenInt start, bitLenInt length, bitLenInt flag1Index,
704  bitLenInt flag2Index);
705  QInterfacePtr CMULEntangle(std::vector<bitLenInt> controlVec, bitLenInt start, bitLenInt carryStart,
706  bitLenInt length, std::vector<bitLenInt>* controlsMapped);
707  std::vector<bitLenInt> CMULEntangle(
708  std::vector<bitLenInt> controlVec, bitLenInt start, const bitCapInt& carryStart, bitLenInt length);
709  void CMULx(CMULFn fn, const bitCapInt& toMod, bitLenInt start, bitLenInt carryStart, bitLenInt length,
710  std::vector<bitLenInt> controlVec);
711  void CMULModx(CMULModFn fn, const bitCapInt& toMod, const bitCapInt& modN, bitLenInt start, bitLenInt carryStart,
712  bitLenInt length, std::vector<bitLenInt> controlVec);
713  bool INTCOptimize(const bitCapInt& toMod, bitLenInt start, bitLenInt length, bool isAdd, bitLenInt carryIndex);
714  bool INTSOptimize(const bitCapInt& toMod, bitLenInt start, bitLenInt length, bool isAdd, bitLenInt overflowIndex);
715  bool INTSCOptimize(const bitCapInt& toMod, bitLenInt start, bitLenInt length, bool isAdd, bitLenInt carryIndex,
716  bitLenInt overflowIndex);
717  bitCapInt GetIndexedEigenstate(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart,
718  bitLenInt valueLength, const unsigned char* values);
719  bitCapInt GetIndexedEigenstate(bitLenInt start, bitLenInt length, const unsigned char* values);
720 #endif
721 
722  real1_f ExpVarFactorized(bool isExp, bool isRdm, bool isFloat, const std::vector<bitLenInt>& bits,
723  const std::vector<bitCapInt>& perms, const std::vector<real1_f>& weights, const bitCapInt& offset, bool roundRz)
724  {
725  if (!qubitCount) {
726  throw std::domain_error("QUnit::ProbAllRdm called for 0 qubits!");
727  }
728 
729  if ((isFloat && (weights.size() < bits.size())) || (!isFloat && (perms.size() < bits.size()))) {
730  throw std::invalid_argument("QUnit::ExpectationFactorized() must supply at least as many weights as bits!");
731  }
732 
734  "QUnit::ExpectationFactorized parameter qubits vector values must be within allocated qubit bounds!");
735 
736  if (shards[0U].unit && (shards[0U].unit->GetQubitCount() == qubitCount)) {
737  OrderContiguous(shards[0U].unit);
738  return isExp ? isFloat
739  ? (isRdm ? shards[0U].unit->ExpectationFloatsFactorizedRdm(roundRz, bits, weights)
740  : shards[0U].unit->ExpectationFloatsFactorized(bits, weights))
741  : (isRdm ? shards[0U].unit->ExpectationBitsFactorizedRdm(roundRz, bits, perms, offset)
742  : shards[0U].unit->ExpectationBitsFactorized(bits, perms, offset))
743  : isFloat ? (isRdm ? shards[0U].unit->VarianceFloatsFactorizedRdm(roundRz, bits, weights)
744  : shards[0U].unit->VarianceFloatsFactorized(bits, weights))
745  : (isRdm ? shards[0U].unit->VarianceBitsFactorizedRdm(roundRz, bits, perms, offset)
746  : shards[0U].unit->VarianceBitsFactorized(bits, perms, offset));
747  }
748 
749  QUnitPtr clone = std::dynamic_pointer_cast<QUnit>(Clone());
750  QInterfacePtr unit = clone->EntangleAll(true);
751  clone->OrderContiguous(unit);
752 
753  return isExp ? isFloat ? (isRdm ? unit->ExpectationFloatsFactorizedRdm(roundRz, bits, weights)
754  : unit->ExpectationFloatsFactorized(bits, weights))
755  : (isRdm ? unit->ExpectationBitsFactorizedRdm(roundRz, bits, perms, offset)
756  : unit->ExpectationBitsFactorized(bits, perms, offset))
757  : isFloat ? (isRdm ? unit->VarianceFloatsFactorizedRdm(roundRz, bits, weights)
758  : unit->VarianceFloatsFactorized(bits, weights))
759  : (isRdm ? unit->VarianceBitsFactorizedRdm(roundRz, bits, perms, offset)
760  : unit->VarianceBitsFactorized(bits, perms, offset));
761  }
762 
763  virtual QInterfacePtr Entangle(std::vector<bitLenInt> bits);
764  virtual QInterfacePtr Entangle(std::vector<bitLenInt*> bits);
765  virtual QInterfacePtr EntangleRange(bitLenInt start, bitLenInt length, bool isForProb = false);
766  virtual QInterfacePtr EntangleRange(bitLenInt start, bitLenInt length, bitLenInt start2, bitLenInt length2);
768  bitLenInt start, bitLenInt length, bitLenInt start2, bitLenInt length2, bitLenInt start3, bitLenInt length3);
769  virtual QInterfacePtr EntangleAll(bool isForProb = false)
770  {
771  QInterfacePtr toRet = EntangleRange(0, qubitCount, isForProb);
772  OrderContiguous(toRet);
773  return toRet;
774  }
775 
776  virtual QInterfacePtr CloneBody(QUnitPtr copyPtr, bool isCopy);
777 
778  virtual bool CheckBitsPermutation(bitLenInt start, bitLenInt length = 1);
779  virtual bitCapInt GetCachedPermutation(bitLenInt start, bitLenInt length);
780  virtual bitCapInt GetCachedPermutation(const std::vector<bitLenInt>& bitArray);
781  virtual bool CheckBitsPlus(bitLenInt qubitIndex, bitLenInt length);
782 
784  std::vector<bitLenInt*>::iterator first, std::vector<bitLenInt*>::iterator last);
785 
786  typedef bool (*ParallelUnitFn)(QInterfacePtr unit, real1_f param1, real1_f param2, real1_f param3, int64_t param4,
787  std::vector<int64_t> param5);
789  real1_f param3 = ZERO_R1_F, int64_t param4 = 0, std::vector<int64_t> param5 = {});
790 
791  virtual bool SeparateBit(bool value, bitLenInt qubit);
792 
793  void OrderContiguous(QInterfacePtr unit);
794 
795  virtual bool Detach(
796  bitLenInt start, bitLenInt length, QUnitPtr dest, bool isTry = false, real1_f tol = TRYDECOMPOSE_EPSILON);
797 
798  struct QSortEntry {
801  bool operator<(const QSortEntry& rhs) { return mapped < rhs.mapped; }
802  bool operator>(const QSortEntry& rhs) { return mapped > rhs.mapped; }
803  };
804  void SortUnit(QInterfacePtr unit, std::vector<QSortEntry>& bits, bitLenInt low, bitLenInt high);
805 
806  bool TrimControls(const std::vector<bitLenInt>& controls, std::vector<bitLenInt>& controlVec, bitCapInt* perm);
807 
808  template <typename CF>
809  void ApplyEitherControlled(std::vector<bitLenInt> controlVec, const std::vector<bitLenInt> targets, CF cfn,
810  bool isPhase, const bitCapInt& controlPerm, const double payloadInfidelity);
811 
812  void ClampShard(bitLenInt qubit)
813  {
814  if (qubit >= qubitCount) {
815  throw std::invalid_argument("Qubit index " + std::to_string(qubit) + " out of range in QUnit::ClampShard!");
816  }
817 
818  QEngineShard& shard = shards[qubit];
819  if (!shard.ClampAmps() || !shard.unit) {
820  return;
821  }
822 
823  if (IS_NORM_0(shard.amp1)) {
824  logFidelity += (double)log(clampProb(ONE_R1_F - norm(shard.amp1)));
825  SeparateBit(false, qubit);
826  } else if (IS_NORM_0(shard.amp0)) {
827  logFidelity += (double)log(clampProb(ONE_R1_F - norm(shard.amp0)));
828  SeparateBit(true, qubit);
829  }
830 
831  CheckFidelity();
832  }
833 
834  void TransformX2x2(const complex* mtrxIn, complex* mtrxOut)
835  {
836  mtrxOut[0U] = HALF_R1 * (mtrxIn[0U] + mtrxIn[1U] + mtrxIn[2U] + mtrxIn[3U]);
837  mtrxOut[1U] = HALF_R1 * (mtrxIn[0U] - mtrxIn[1U] + mtrxIn[2U] - mtrxIn[3U]);
838  mtrxOut[2U] = HALF_R1 * (mtrxIn[0U] + mtrxIn[1U] - mtrxIn[2U] - mtrxIn[3U]);
839  mtrxOut[3U] = HALF_R1 * (mtrxIn[0U] - mtrxIn[1U] - mtrxIn[2U] + mtrxIn[3U]);
840  }
841 
842  void TransformXInvert(const complex& topRight, const complex& bottomLeft, complex* mtrxOut)
843  {
844  mtrxOut[0U] = HALF_R1 * (topRight + bottomLeft);
845  mtrxOut[1U] = HALF_R1 * (-topRight + bottomLeft);
846  mtrxOut[2U] = -mtrxOut[1U];
847  mtrxOut[3U] = -mtrxOut[0U];
848  }
849 
850  void TransformY2x2(const complex* mtrxIn, complex* mtrxOut)
851  {
852  mtrxOut[0U] = HALF_R1 * (mtrxIn[0U] + I_CMPLX * (mtrxIn[1U] - mtrxIn[2U]) + mtrxIn[3U]);
853  mtrxOut[1U] = HALF_R1 * (mtrxIn[0U] - I_CMPLX * (mtrxIn[1U] + mtrxIn[2U]) - mtrxIn[3U]);
854  mtrxOut[2U] = HALF_R1 * (mtrxIn[0U] + I_CMPLX * (mtrxIn[1U] + mtrxIn[2U]) - mtrxIn[3U]);
855  mtrxOut[3U] = HALF_R1 * (mtrxIn[0U] - I_CMPLX * (mtrxIn[1U] - mtrxIn[2U]) + mtrxIn[3U]);
856  }
857 
858  void TransformYInvert(const complex& topRight, const complex& bottomLeft, complex* mtrxOut)
859  {
860  mtrxOut[0U] = I_CMPLX * HALF_R1 * (topRight - bottomLeft);
861  mtrxOut[1U] = I_CMPLX * HALF_R1 * (-topRight - bottomLeft);
862  mtrxOut[2U] = -mtrxOut[1U];
863  mtrxOut[3U] = -mtrxOut[0U];
864  }
865 
866  void TransformPhase(const complex& topLeft, const complex& bottomRight, complex* mtrxOut)
867  {
868  mtrxOut[0U] = HALF_R1 * (topLeft + bottomRight);
869  mtrxOut[1U] = HALF_R1 * (topLeft - bottomRight);
870  mtrxOut[2U] = mtrxOut[1U];
871  mtrxOut[3U] = mtrxOut[0U];
872  }
873 
875  {
876  if (i >= qubitCount) {
877  throw std::invalid_argument("Qubit index " + std::to_string(i) + " out of range in QUnit::RevertBasisX!");
878  }
879 
880  QEngineShard& shard = shards[i];
881  if (shard.pauliBasis != PauliX) {
882  // Recursive call that should be blocked,
883  // or already in target basis.
884  return;
885  }
886 
887  ConvertZToX(i);
888  }
889 
891  {
892  if (i >= qubitCount) {
893  throw std::invalid_argument("Qubit index " + std::to_string(i) + " out of range in QUnit::RevertBasisY!");
894  }
895 
896  QEngineShard& shard = shards[i];
897 
898  if (shard.pauliBasis != PauliY) {
899  // Recursive call that should be blocked,
900  // or already in target basis.
901  return;
902  }
903 
904  shard.pauliBasis = PauliX;
905 
906  if (shard.unit) {
907  shard.unit->SqrtX(shard.mapped);
908  }
909 
910  if (shard.isPhaseDirty || shard.isProbDirty) {
911  shard.isProbDirty = true;
912  return;
913  }
914 
917  QRACK_CONST complex mtrx[4U]{ diag, cross, cross, diag };
918 
919  const complex Y0 = shard.amp0;
920  const complex& Y1 = shard.amp1;
921  shard.amp0 = (mtrx[0U] * Y0) + (mtrx[1U] * Y1);
922  shard.amp1 = (mtrx[2U] * Y0) + (mtrx[3U] * Y1);
923  ClampShard(i);
924  }
925 
927  {
928  if (i >= qubitCount) {
929  throw std::invalid_argument("Qubit index " + std::to_string(i) + " out of range in QUnit::RevertBasis1Qb!");
930  }
931 
932  QEngineShard& shard = shards[i];
933 
934  if (shard.pauliBasis == PauliY) {
935  ConvertYToZ(i);
936  } else {
937  RevertBasisX(i);
938  }
939  }
940 
942  {
943  if (i >= qubitCount) {
944  throw std::invalid_argument(
945  "Qubit index " + std::to_string(i) + " out of range in QUnit::RevertBasisToX1Qb!");
946  }
947 
948  QEngineShard& shard = shards[i];
949  if (shard.pauliBasis == PauliZ) {
950  ConvertZToX(i);
951  } else if (shard.pauliBasis == PauliY) {
952  RevertBasisY(i);
953  }
954  }
955 
957  {
958  if (i >= qubitCount) {
959  throw std::invalid_argument(
960  "Qubit index " + std::to_string(i) + " out of range in QUnit::RevertBasisToY1Qb!");
961  }
962 
963  QEngineShard& shard = shards[i];
964  if (shard.pauliBasis == PauliZ) {
965  ConvertZToY(i);
966  } else if (shard.pauliBasis == PauliX) {
967  ConvertXToY(i);
968  }
969  }
970 
972  {
973  if (i >= qubitCount) {
974  throw std::invalid_argument("Qubit index " + std::to_string(i) + " out of range in QUnit::ConvertZToX!");
975  }
976 
977  QEngineShard& shard = shards[i];
978 
979  // WARNING: Might be called when shard is in either Z or X basis
980  shard.pauliBasis = (shard.pauliBasis == PauliX) ? PauliZ : PauliX;
981 
982  if (shard.unit) {
983  shard.unit->H(shard.mapped);
984  }
985 
986  if (shard.isPhaseDirty || shard.isProbDirty) {
987  shard.isProbDirty = true;
988  return;
989  }
990 
991  const complex tempAmp1 = SQRT1_2_R1 * (shard.amp0 - shard.amp1);
992  shard.amp0 = SQRT1_2_R1 * (shard.amp0 + shard.amp1);
993  shard.amp1 = tempAmp1;
994  ClampShard(i);
995  }
997  {
998  if (i >= qubitCount) {
999  throw std::invalid_argument("Qubit index " + std::to_string(i) + " out of range in QUnit::ConvertXToY!");
1000  }
1001 
1002  QEngineShard& shard = shards[i];
1003 
1004  shard.pauliBasis = PauliY;
1005 
1006  if (shard.unit) {
1007  shard.unit->ISqrtX(shard.mapped);
1008  }
1009 
1010  if (shard.isPhaseDirty || shard.isProbDirty) {
1011  shard.isProbDirty = true;
1012  return;
1013  }
1014 
1015  QRACK_CONST complex diag = complex(ONE_R1 / (real1)2, -ONE_R1 / (real1)2);
1016  QRACK_CONST complex cross = complex(ONE_R1 / (real1)2, ONE_R1 / (real1)2);
1017  QRACK_CONST complex mtrx[4U]{ diag, cross, cross, diag };
1018 
1019  const complex Y0 = shard.amp0;
1020  const complex& Y1 = shard.amp1;
1021  shard.amp0 = (mtrx[0U] * Y0) + (mtrx[1U] * Y1);
1022  shard.amp1 = (mtrx[2U] * Y0) + (mtrx[3U] * Y1);
1023  ClampShard(i);
1024  }
1026  {
1027  if (i >= qubitCount) {
1028  throw std::invalid_argument("Qubit index " + std::to_string(i) + " out of range in QUnit::ConvertYToZ!");
1029  }
1030 
1031  QEngineShard& shard = shards[i];
1032 
1033  shard.pauliBasis = PauliZ;
1034 
1035  if (shard.unit) {
1036  shard.unit->SH(shard.mapped);
1037  }
1038 
1039  if (shard.isPhaseDirty || shard.isProbDirty) {
1040  shard.isProbDirty = true;
1041  return;
1042  }
1043 
1045  QRACK_CONST complex mtrx[4U]{ row1, row1, complex(ZERO_R1, SQRT1_2_R1), complex(ZERO_R1, -SQRT1_2_R1) };
1046 
1047  const complex Y0 = shard.amp0;
1048  const complex& Y1 = shard.amp1;
1049  shard.amp0 = (mtrx[0U] * Y0) + (mtrx[1U] * Y1);
1050  shard.amp1 = (mtrx[2U] * Y0) + (mtrx[3U] * Y1);
1051  ClampShard(i);
1052  }
1054  {
1055  if (i >= qubitCount) {
1056  throw std::invalid_argument("Qubit index " + std::to_string(i) + " out of range in QUnit::ConvertZToY!");
1057  }
1058 
1059  QEngineShard& shard = shards[i];
1060 
1061  shard.pauliBasis = PauliY;
1062 
1063  if (shard.unit) {
1064  shard.unit->HIS(shard.mapped);
1065  }
1066 
1067  if (shard.isPhaseDirty || shard.isProbDirty) {
1068  shard.isProbDirty = true;
1069  return;
1070  }
1071 
1073  QRACK_CONST complex mtrx[4U]{ col1, complex(ZERO_R1, -SQRT1_2_R1), col1, complex(ZERO_R1, SQRT1_2_R1) };
1074 
1075  const complex Y0 = shard.amp0;
1076  const complex& Y1 = shard.amp1;
1077  shard.amp0 = (mtrx[0U] * Y0) + (mtrx[1U] * Y1);
1078  shard.amp1 = (mtrx[2U] * Y0) + (mtrx[3U] * Y1);
1079  ClampShard(i);
1080  }
1081  void ShardAI(bitLenInt qubit, real1_f azimuth, real1_f inclination)
1082  {
1083  if (qubit >= qubitCount) {
1084  throw std::invalid_argument("Qubit index " + std::to_string(qubit) + " out of range in QUnit::ShardAI!");
1085  }
1086 
1087  real1 cosineA = (real1)cos(azimuth);
1088  real1 sineA = (real1)sin(azimuth);
1089  real1 cosineI = (real1)cos(inclination / 2);
1090  real1 sineI = (real1)sin(inclination / 2);
1091  complex expA = complex(cosineA, sineA);
1092  complex expNegA = complex(cosineA, -sineA);
1093  complex mtrx[4U]{ cosineI, -expNegA * sineI, expA * sineI, cosineI };
1094 
1095  QEngineShard& shard = shards[qubit];
1096 
1097  const complex Y0 = shard.amp0;
1098  const complex& Y1 = shard.amp1;
1099  shard.amp0 = (mtrx[0U] * Y0) + (mtrx[1U] * Y1);
1100  shard.amp1 = (mtrx[2U] * Y0) + (mtrx[3U] * Y1);
1101  ClampShard(qubit);
1102  }
1103 
1107 
1108  void ApplyBuffer(PhaseShardPtr phaseShard, bitLenInt control, bitLenInt target, bool isAnti);
1109  void ApplyBufferMap(bitLenInt bitIndex, ShardToPhaseMap bufferMap, RevertExclusivity exclusivity, bool isControl,
1110  bool isAnti, const std::set<bitLenInt>& exceptPartners, bool dumpSkipped);
1112  RevertControl controlExclusivity = CONTROLS_AND_TARGETS, RevertAnti antiExclusivity = CTRL_AND_ANTI,
1113  const std::set<bitLenInt>& exceptControlling = {}, const std::set<bitLenInt>& exceptTargetedBy = {},
1114  bool dumpSkipped = false, bool skipOptimized = false);
1115 
1117  {
1118  if (i >= qubitCount) {
1119  throw std::invalid_argument(
1120  "Qubit index " + std::to_string(i) + " out of range in QUnit::Flush0Eigenstate!");
1121  }
1122 
1123  QEngineShard& shard = shards[i];
1124  shard.DumpControlOf();
1125  if (randGlobalPhase) {
1127  }
1129  }
1131  {
1132  if (i >= qubitCount) {
1133  throw std::invalid_argument(
1134  "Qubit index " + std::to_string(i) + " out of range in QUnit::Flush1Eigenstate!");
1135  }
1136 
1137  QEngineShard& shard = shards[i];
1138  shard.DumpAntiControlOf();
1139  if (randGlobalPhase) {
1140  shard.DumpSamePhaseControlOf();
1141  }
1143  }
1145  {
1146  RevertBasis1Qb(i);
1147  RevertBasis2Qb(i);
1148  }
1149  void ToPermBasis(bitLenInt start, bitLenInt length)
1150  {
1151  for (bitLenInt i = 0U; i < length; ++i) {
1152  RevertBasis1Qb(start + i);
1153  }
1154  for (bitLenInt i = 0U; i < length; ++i) {
1155  RevertBasis2Qb(start + i);
1156  }
1157  }
1159  {
1160  RevertBasis1Qb(qubit);
1162  }
1164  {
1165  for (bitLenInt i = 0U; i < length; ++i) {
1166  RevertBasis1Qb(start + i);
1167  }
1168  for (bitLenInt i = 0U; i < length; ++i) {
1170  }
1171  }
1175  {
1176  RevertBasis1Qb(qubit);
1177  RevertBasis2Qb(qubit, ONLY_INVERT);
1179 
1180  shards[qubit].DumpMultiBit();
1181  }
1182  void ToPermBasisMeasure(bitLenInt start, bitLenInt length);
1183  void ToPermBasisAllMeasure();
1184 
1186  {
1187  if ((start + length) > qubitCount) {
1188  throw std::invalid_argument(
1189  "Qubit index " + std::to_string(start + length) + " out of range in QUnit::DirtyShardRange!");
1190  }
1191 
1192  for (bitLenInt i = 0U; i < length; ++i) {
1193  shards[start + i].MakeDirty();
1194  }
1195  }
1196 
1198  {
1199  if ((start + length) > qubitCount) {
1200  throw std::invalid_argument(
1201  "Qubit index " + std::to_string(start + length) + " out of range in QUnit::DirtyShardRangePhase!");
1202  }
1203 
1204  for (bitLenInt i = 0U; i < length; ++i) {
1205  shards[start + i].isPhaseDirty = true;
1206  }
1207  }
1208 
1209  void DirtyShardIndexVector(std::vector<bitLenInt> bitIndices)
1210  {
1211  for (const bitLenInt& bitIndex : bitIndices) {
1212  if (bitIndex >= qubitCount) {
1213  throw std::invalid_argument(
1214  "Qubit index " + std::to_string(bitIndex) + " out of range in QUnit::DirtyShardRangePhase!");
1215  }
1216 
1217  shards[bitIndex].MakeDirty();
1218  }
1219  }
1220 
1222  {
1223  if (target >= qubitCount) {
1224  throw std::invalid_argument(
1225  "Qubit index " + std::to_string(target) + " out of range in QUnit::EndEmulation!");
1226  }
1227 
1228  QEngineShard& shard = shards[target];
1229  if (shard.unit) {
1230  return;
1231  }
1232 
1233  if (norm(shard.amp1) <= FP_NORM_EPSILON) {
1234  shard.unit = MakeEngine(1U, ZERO_BCI);
1235  } else if (norm(shard.amp0) <= FP_NORM_EPSILON) {
1236  shard.unit = MakeEngine(1U, ONE_BCI);
1237  } else {
1238  const complex bitState[2U]{ shard.amp0, shard.amp1 };
1239  shard.unit = MakeEngine(1U, ZERO_BCI);
1240  shard.unit->SetQuantumState(bitState);
1241  }
1242  }
1243 
1245  {
1246  shard->found = true;
1247  for (bitLenInt i = 0U; i < shards.size(); ++i) {
1248  if (shards[i].found) {
1249  shard->found = false;
1250  return i;
1251  }
1252  }
1253  shard->found = false;
1254  return shards.size();
1255  }
1256 
1257  void CommuteH(bitLenInt bitIndex);
1258 
1259  void OptimizePairBuffers(bitLenInt control, bitLenInt target, bool anti);
1260 };
1261 
1262 } // namespace Qrack
void bi_decrement(BigInteger *pBigInt, const BIG_INTEGER_WORD &value)
Definition: big_integer.hpp:237
int bi_compare(const BigInteger &left, const BigInteger &right)
Definition: big_integer.hpp:125
Definition: qalu.hpp:22
Definition: qengineshard.hpp:316
std::vector< QEngineShard > shards
Definition: qengineshard.hpp:318
bitLenInt size()
Definition: qengineshard.hpp:352
void swap(bitLenInt qubit1, bitLenInt qubit2)
Definition: qengineshard.hpp:388
void insert(bitLenInt start, QEngineShardMap &toInsert)
Definition: qengineshard.hpp:360
Associates a QInterface object with a set of bits.
Definition: qengineshard.hpp:50
void DumpControlOf()
Definition: qengineshard.hpp:163
complex amp0
Definition: qengineshard.hpp:63
bool ClampAmps()
Definition: qengineshard.cpp:26
bitLenInt mapped
Definition: qengineshard.hpp:60
bool isProbDirty
Definition: qengineshard.hpp:61
void DumpAntiControlOf()
Definition: qengineshard.hpp:164
QInterfacePtr unit
Definition: qengineshard.hpp:59
Pauli pauliBasis
Definition: qengineshard.hpp:65
complex amp1
Definition: qengineshard.hpp:64
void DumpSamePhaseAntiControlOf()
Definition: qengineshard.hpp:172
bool found
Definition: qengineshard.hpp:75
void DumpSamePhaseControlOf()
Definition: qengineshard.hpp:168
bool isPhaseDirty
Definition: qengineshard.hpp:62
A "Qrack::QInterface" is an abstract interface exposing qubit permutation state vector with methods t...
Definition: qinterface.hpp:141
bitCapInt maxQPower
Definition: qinterface.hpp:149
virtual void SetConcurrency(uint32_t threadsPerEngine)
Set the number of threads in parallel for loops, per component QEngine.
Definition: qinterface.hpp:275
real1 amplitudeFloor
Definition: qinterface.hpp:148
bool useRDRAND
Definition: qinterface.hpp:145
virtual bitLenInt Allocate(bitLenInt length)
Allocate new "length" count of |0> state qubits at end of qubit index position.
Definition: qinterface.hpp:477
virtual bitLenInt Compose(QInterfacePtr toCopy)
Combine another QInterface with this one, after the last bit index of this one.
Definition: qinterface.hpp:371
qrack_rand_gen_ptr rand_generator
Definition: qinterface.hpp:150
bool randGlobalPhase
Definition: qinterface.hpp:144
virtual void SetQubitCount(bitLenInt qb)
Definition: qinterface.hpp:268
static real1_f clampProb(real1_f toClamp)
Definition: qinterface.hpp:158
bitLenInt qubitCount
Definition: qinterface.hpp:146
bool doNormalize
Definition: qinterface.hpp:143
Definition: qparity.hpp:22
Definition: qunit.hpp:28
void ConvertYToZ(bitLenInt i)
Definition: qunit.hpp:1025
void ToPermBasisAll()
Definition: qunit.hpp:1172
virtual void SetReactiveSeparate(bool isAggSep)
Set reactive separation option (on by default if available)
Definition: qunit.hpp:186
std::vector< int64_t > deviceIDs
Definition: qunit.hpp:50
void CMULx(CMULFn fn, const bitCapInt &toMod, bitLenInt start, bitLenInt carryStart, bitLenInt length, std::vector< bitLenInt > controlVec)
Definition: qunit.cpp:3360
void OptimizePairBuffers(bitLenInt control, bitLenInt target, bool anti)
Definition: qunit.cpp:4251
virtual void YBase(bitLenInt target)
Definition: qunit.hpp:655
void ApplyEitherControlled(std::vector< bitLenInt > controlVec, const std::vector< bitLenInt > targets, CF cfn, bool isPhase, const bitCapInt &controlPerm, const double payloadInfidelity)
Definition: qunit.cpp:2647
void OrderContiguous(QInterfacePtr unit)
Definition: qunit.cpp:844
virtual complex GetAmplitudeOrProb(const bitCapInt &perm, bool isProb)
Definition: qunit.cpp:246
double PhaseInfidelity(const complex &p)
Definition: qunit.hpp:74
real1_f ExpVarFactorized(bool isExp, bool isRdm, bool isFloat, const std::vector< bitLenInt > &bits, const std::vector< bitCapInt > &perms, const std::vector< real1_f > &weights, const bitCapInt &offset, bool roundRz)
Definition: qunit.hpp:722
void INTS(const bitCapInt &toMod, bitLenInt start, bitLenInt length, bitLenInt overflowIndex, bitLenInt carryIndex, bool hasCarry)
Definition: qunit.cpp:3123
bool ParallelUnitApply(ParallelUnitFn fn, real1_f param1=ZERO_R1_F, real1_f param2=ZERO_R1_F, real1_f param3=ZERO_R1_F, int64_t param4=0, std::vector< int64_t > param5={})
Definition: qunit.cpp:3714
void(QAlu::* INCxFn)(const bitCapInt &, bitLenInt, bitLenInt, bitLenInt)
Definition: qunit.hpp:693
void Flush1Eigenstate(bitLenInt i)
Definition: qunit.hpp:1130
QInterfacePtr MakeEngine(bitLenInt length, const bitCapInt &perm)
Definition: qunit.cpp:132
void SortUnit(QInterfacePtr unit, std::vector< QSortEntry > &bits, bitLenInt low, bitLenInt high)
Sort a container of bits, calling Swap() on each.
Definition: qunit.cpp:870
void ToPermBasisProb(bitLenInt qubit)
Definition: qunit.hpp:1158
virtual QInterfacePtr EntangleInCurrentBasis(std::vector< bitLenInt * >::iterator first, std::vector< bitLenInt * >::iterator last)
Definition: qunit.cpp:420
virtual bool CheckBitsPermutation(bitLenInt start, bitLenInt length=1)
Check if all qubits in the range have cached probabilities indicating that they are in permutation ba...
Definition: qunit.cpp:911
bool useTGadget
Definition: qunit.hpp:36
virtual void X(bitLenInt q)
Definition: qunit.hpp:386
virtual QInterfacePtr Entangle(std::vector< bitLenInt > bits)
Definition: qunit.cpp:532
virtual bitLenInt Allocate(bitLenInt length)
Allocate new "length" count of |0> state qubits at end of qubit index position.
Definition: qinterface.hpp:477
virtual void EitherISwap(bitLenInt qubit1, bitLenInt qubit2, bool isInverse)
Definition: qunit.cpp:1780
void RevertBasis1Qb(bitLenInt i)
Definition: qunit.hpp:926
virtual QInterfacePtr Decompose(bitLenInt start, bitLenInt length)
Schmidt decompose a length of qubits.
Definition: qunit.hpp:275
virtual void IS(bitLenInt qubit)
Inverse S gate.
Definition: qinterface.hpp:1041
virtual void S(bitLenInt qubit)
S gate.
Definition: qinterface.hpp:1034
virtual real1_f CProbRdm(bitLenInt control, bitLenInt target)
Definition: qunit.hpp:207
real1_f separabilityThreshold
Definition: qunit.hpp:44
void ToPermBasisProb()
Definition: qunit.hpp:1173
void TransformYInvert(const complex &topRight, const complex &bottomLeft, complex *mtrxOut)
Definition: qunit.hpp:858
virtual real1_f ProbBase(bitLenInt qubit)
Definition: qunit.cpp:963
virtual void GetQuantumState(complex *outputState)
Get the pure quantum state representation.
Definition: qunit.hpp:225
virtual void UniformlyControlledSingleBit(const std::vector< bitLenInt > &controls, bitLenInt qubit, const complex *mtrxs)
Apply a "uniformly controlled" arbitrary single bit unitary transformation.
Definition: qinterface.hpp:634
virtual bitCapInt ForceMReg(bitLenInt start, bitLenInt length, const bitCapInt &result, bool doForce=true, bool doApply=true)
Act as if is a measurement was applied, except force the (usually random) result.
Definition: qinterface.cpp:213
virtual bitLenInt Compose(QInterfacePtr toCopy)
Combine another QInterface with this one, after the last bit index of this one.
Definition: qinterface.hpp:371
virtual bool ForceM(bitLenInt qubit, bool result, bool doForce=true, bool doApply=true)=0
Act as if is a measurement was applied, except force the (usually random) result.
real1_f roundingThreshold
Definition: qunit.hpp:45
virtual bool CheckBitsPlus(bitLenInt qubitIndex, bitLenInt length)
Definition: qunit.cpp:950
virtual bitLenInt Compose(QInterfacePtr toCopy)
Combine another QInterface with this one, after the last bit index of this one.
Definition: qunit.hpp:245
void ToPermBasisAllMeasure()
Definition: qunit.cpp:2795
complex phaseFactor
Definition: qunit.hpp:48
void CheckFidelity()
Definition: qunit.hpp:101
void INT(const bitCapInt &toMod, bitLenInt start, bitLenInt length, bitLenInt carryIndex, bool hasCarry, std::vector< bitLenInt > controlVec=std::vector< bitLenInt >())
Definition: qunit.cpp:2914
virtual void H(bitLenInt qubit)
Hadamard gate.
Definition: qinterface.hpp:920
virtual bool SeparateBit(bool value, bitLenInt qubit)
Definition: qunit.cpp:1337
bool isReactiveSeparate
Definition: qunit.hpp:35
void(QAlu::* CMULModFn)(const bitCapInt &, const bitCapInt &, bitLenInt, bitLenInt, bitLenInt, const std::vector< bitLenInt > &)
Definition: qunit.hpp:696
virtual void SetTInjection(bool useGadget)
Set the option to use T-injection gadgets (off by default)
Definition: qunit.hpp:174
void TransformXInvert(const complex &topRight, const complex &bottomLeft, complex *mtrxOut)
Definition: qunit.hpp:842
virtual QInterfacePtr EntangleRange(bitLenInt start, bitLenInt length, bool isForProb=false)
Definition: qunit.cpp:552
virtual bool TryDecompose(bitLenInt start, QInterfacePtr dest, real1_f error_tol=TRYDECOMPOSE_EPSILON)
Attempt to Decompose() a bit range.
Definition: qunit.hpp:290
virtual bool Detach(bitLenInt start, bitLenInt length, QUnitPtr dest, bool isTry=false, real1_f tol=TRYDECOMPOSE_EPSILON)
Definition: qunit.cpp:289
void ShardAI(bitLenInt qubit, real1_f azimuth, real1_f inclination)
Definition: qunit.hpp:1081
virtual void GetProbs(real1 *outputProbs)
Get the pure quantum state representation.
Definition: qunit.hpp:226
void ClampShard(bitLenInt qubit)
Definition: qunit.hpp:812
virtual void Decompose(bitLenInt start, QInterfacePtr dest)
Minimally decompose a set of contiguous bits from the separably composed unit, into "destination".
Definition: qunit.hpp:270
virtual bool M(bitLenInt q)
Definition: qunit.hpp:384
void TransformPhase(const complex &topLeft, const complex &bottomRight, complex *mtrxOut)
Definition: qunit.hpp:866
virtual void SetDevice(int64_t dID)
Set the device index, if more than one device is available.
Definition: qunit.cpp:3768
bitLenInt thresholdQubits
Definition: qunit.hpp:43
void DirtyShardIndexVector(std::vector< bitLenInt > bitIndices)
Definition: qunit.hpp:1209
bool INTSOptimize(const bitCapInt &toMod, bitLenInt start, bitLenInt length, bool isAdd, bitLenInt overflowIndex)
Check if overflow arithmetic can be optimized.
Definition: qunit.cpp:2856
void ConvertZToY(bitLenInt i)
Definition: qunit.hpp:1053
std::vector< QInterfaceEngine > engines
Definition: qunit.hpp:51
void RevertBasisY(bitLenInt i)
Definition: qunit.hpp:890
virtual bool GetReactiveSeparate()
Get reactive separation option.
Definition: qunit.hpp:187
bool TrimControls(const std::vector< bitLenInt > &controls, std::vector< bitLenInt > &controlVec, bitCapInt *perm)
Definition: qunit.cpp:2530
virtual void SetDeviceList(std::vector< int64_t > dIDs)
Set the device index list, if more than one device is available.
Definition: qunit.cpp:3780
virtual ~QUnit()
Definition: qunit.hpp:160
double logFidelity
Definition: qunit.hpp:46
QUnit(bitLenInt qBitCount, const bitCapInt &initState=ZERO_BCI, qrack_rand_gen_ptr rgp=nullptr, const complex &phaseFac=CMPLX_DEFAULT_ARG, bool doNorm=false, bool randomGlobalPhase=true, bool useHostMem=false, int64_t deviceId=-1, bool useHardwareRNG=true, bool ignored=false, real1_f norm_thresh=REAL1_EPSILON, std::vector< int64_t > devIDs={}, bitLenInt qubitThreshold=0U, real1_f separation_thresh=_qrack_qunit_sep_thresh)
Definition: qunit.hpp:150
void ToPermBasis(bitLenInt start, bitLenInt length)
Definition: qunit.hpp:1149
RevertAnti
Definition: qunit.hpp:1106
@ ONLY_ANTI
Definition: qunit.hpp:1106
@ CTRL_AND_ANTI
Definition: qunit.hpp:1106
@ ONLY_CTRL
Definition: qunit.hpp:1106
void RevertBasisToX1Qb(bitLenInt i)
Definition: qunit.hpp:941
void CMULModx(CMULModFn fn, const bitCapInt &toMod, const bitCapInt &modN, bitLenInt start, bitLenInt carryStart, bitLenInt length, std::vector< bitLenInt > controlVec)
Definition: qunit.cpp:3373
virtual void SetAmplitude(const bitCapInt &perm, const complex &amp)
Sets the representational amplitude of a full permutation.
Definition: qunit.hpp:229
void ApplyBuffer(PhaseShardPtr phaseShard, bitLenInt control, bitLenInt target, bool isAnti)
Definition: qunit.cpp:3913
virtual void Dispose(bitLenInt start, bitLenInt length)
Minimally decompose a set of contiguous bits from the separably composed unit, and discard the separa...
Definition: qunit.hpp:285
int64_t devID
Definition: qunit.hpp:47
double PayloadInfidelityFactor3(const complex *m)
Definition: qunit.hpp:80
void RevertBasis2Qb(bitLenInt i, RevertExclusivity exclusivity=INVERT_AND_PHASE, RevertControl controlExclusivity=CONTROLS_AND_TARGETS, RevertAnti antiExclusivity=CTRL_AND_ANTI, const std::set< bitLenInt > &exceptControlling={}, const std::set< bitLenInt > &exceptTargetedBy={}, bool dumpSkipped=false, bool skipOptimized=false)
Definition: qunit.cpp:4092
virtual bool TrySeparateClifford(bitLenInt qubit)
Definition: qunit.cpp:650
bool isCpu
Definition: qunit.hpp:38
bool freezeBasis2Qb
Definition: qunit.hpp:33
bool isSinglePage
Definition: qunit.hpp:39
virtual bitCapInt GetCachedPermutation(bitLenInt start, bitLenInt length)
Assuming all bits in the range are in cached |0>/|1> eigenstates, read the unsigned integer value of ...
Definition: qunit.cpp:928
bool(* ParallelUnitFn)(QInterfacePtr unit, real1_f param1, real1_f param2, real1_f param3, int64_t param4, std::vector< int64_t > param5)
Definition: qunit.hpp:786
virtual QInterfacePtr CloneBody(QUnitPtr copyPtr, bool isCopy)
Definition: qunit.cpp:3882
virtual int64_t GetDevice()
Get the device index.
Definition: qunit.hpp:191
void RevertBasisToY1Qb(bitLenInt i)
Definition: qunit.hpp:956
void DirtyShardRange(bitLenInt start, bitLenInt length)
Definition: qunit.hpp:1185
QInterfacePtr CMULEntangle(std::vector< bitLenInt > controlVec, bitLenInt start, bitLenInt carryStart, bitLenInt length, std::vector< bitLenInt > *controlsMapped)
Definition: qunit.cpp:3324
virtual void XBase(bitLenInt target)
Definition: qunit.hpp:640
bitLenInt aceQubits
Definition: qunit.hpp:42
void ElideCz(const bool &isAnti, const bitLenInt &control, const bitLenInt &target, const real1_f &pth, const real1_f &pc)
Definition: qunit.hpp:114
void ToPermBasisProb(bitLenInt start, bitLenInt length)
Definition: qunit.hpp:1163
virtual bitLenInt Compose(QInterfacePtr toCopy, bitLenInt start)
Compose() a QInterface peer, inserting its qubit into index order at start index.
Definition: qunit.hpp:266
void ToPermBasis(bitLenInt i)
Definition: qunit.hpp:1144
void TransformX2x2(const complex *mtrxIn, complex *mtrxOut)
Definition: qunit.hpp:834
virtual bool TryDecompose(bitLenInt start, QUnitPtr dest, real1_f error_tol=TRYDECOMPOSE_EPSILON)
Definition: qunit.hpp:294
virtual complex GetAmplitude(const bitCapInt &perm)
Get the representational amplitude of a full permutation.
Definition: qunit.cpp:244
virtual real1_f ACProbRdm(bitLenInt control, bitLenInt target)
Definition: qunit.hpp:215
virtual void SetPermutation(const bitCapInt &perm, const complex &phaseFac=CMPLX_DEFAULT_ARG)
Set to a specific permutation of all qubits.
Definition: qunit.cpp:142
bitLenInt FindShardIndex(QEngineShardPtr shard)
Definition: qunit.hpp:1244
RevertControl
Definition: qunit.hpp:1105
@ ONLY_TARGETS
Definition: qunit.hpp:1105
@ CONTROLS_AND_TARGETS
Definition: qunit.hpp:1105
@ ONLY_CONTROLS
Definition: qunit.hpp:1105
virtual QInterfacePtr EntangleAll(bool isForProb=false)
Definition: qunit.hpp:769
void ToPermBasisMeasure(bitLenInt qubit)
Definition: qunit.hpp:1174
bitCapInt GetIndexedEigenstate(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart, bitLenInt valueLength, const unsigned char *values)
Definition: qunit.cpp:3470
virtual void Copy(QInterfacePtr orig)
Definition: qunit.hpp:55
bool INTCOptimize(const bitCapInt &toMod, bitLenInt start, bitLenInt length, bool isAdd, bitLenInt carryIndex)
Check if carry arithmetic can be optimized.
Definition: qunit.cpp:2862
std::vector< bitLenInt > CMULEntangle(std::vector< bitLenInt > controlVec, bitLenInt start, const bitCapInt &carryStart, bitLenInt length)
virtual void GetQuantumStateOrProbs(complex *outputState, real1 *outputProbs)
Definition: qunit.cpp:204
virtual bitLenInt Compose(QUnitPtr toCopy)
Definition: qunit.hpp:244
virtual std::vector< int64_t > GetDeviceList()
Get the device index.
Definition: qunit.hpp:192
virtual void Decompose(bitLenInt start, QUnitPtr dest)
Definition: qunit.hpp:274
void INCxx(INCxxFn fn, const bitCapInt &toMod, bitLenInt start, bitLenInt length, bitLenInt flag1Index, bitLenInt flag2Index)
Definition: qunit.cpp:2827
void INCx(INCxFn fn, const bitCapInt &toMod, bitLenInt start, bitLenInt length, bitLenInt flagIndex)
Definition: qunit.cpp:2808
QUnit(std::vector< QInterfaceEngine > eng, bitLenInt qBitCount, const bitCapInt &initState=ZERO_BCI, qrack_rand_gen_ptr rgp=nullptr, const complex &phaseFac=CMPLX_DEFAULT_ARG, bool doNorm=false, bool randomGlobalPhase=true, bool useHostMem=false, int64_t deviceId=-1, bool useHardwareRNG=true, bool ignored=false, real1_f norm_thresh=REAL1_EPSILON, std::vector< int64_t > devIDs={}, bitLenInt qubitThreshold=0U, real1_f separation_thresh=_qrack_qunit_sep_thresh)
Definition: qunit.cpp:73
virtual void Copy(QUnitPtr orig)
Definition: qunit.hpp:56
virtual void SetConcurrency(uint32_t threadsPerEngine)
Set the number of threads in parallel for loops, per component QEngine.
Definition: qunit.hpp:162
void ConvertZToX(bitLenInt i)
Definition: qunit.hpp:971
bool isSparse
Definition: qunit.hpp:40
void CommuteH(bitLenInt bitIndex)
Definition: qunit.cpp:4148
virtual bool TrySeparate(const std::vector< bitLenInt > &qubits, real1_f error_tol)
Qrack::QUnit types maintain explicit separation of representations of qubits, which reduces memory us...
Definition: qinterface.hpp:2900
void ApplyBufferMap(bitLenInt bitIndex, ShardToPhaseMap bufferMap, RevertExclusivity exclusivity, bool isControl, bool isAnti, const std::set< bitLenInt > &exceptPartners, bool dumpSkipped)
Definition: qunit.cpp:4025
void(QAlu::* INCxxFn)(const bitCapInt &, bitLenInt, bitLenInt, bitLenInt, bitLenInt)
Definition: qunit.hpp:694
void TransformY2x2(const complex *mtrxIn, complex *mtrxOut)
Definition: qunit.hpp:850
virtual void Dispose(bitLenInt start, bitLenInt length, const bitCapInt &disposedPerm)
Dispose a a contiguous set of qubits that are already in a permutation eigenstate.
Definition: qunit.hpp:286
void ConvertXToY(bitLenInt i)
Definition: qunit.hpp:996
RevertExclusivity
Definition: qunit.hpp:1104
@ ONLY_INVERT
Definition: qunit.hpp:1104
@ ONLY_PHASE
Definition: qunit.hpp:1104
@ INVERT_AND_PHASE
Definition: qunit.hpp:1104
virtual bitLenInt Compose(QUnitPtr toCopy, bitLenInt start)
Definition: qunit.hpp:246
virtual real1_f ProbRdm(bitLenInt qubit)
Direct measure of bit probability to be in |1> state, treating all ancillary qubits as post-selected ...
Definition: qunit.hpp:194
void DirtyShardRangePhase(bitLenInt start, bitLenInt length)
Definition: qunit.hpp:1197
void Flush0Eigenstate(bitLenInt i)
Definition: qunit.hpp:1116
bool isBdt
Definition: qunit.hpp:37
QEngineShardMap shards
Definition: qunit.hpp:49
size_t aceMb
Definition: qunit.hpp:41
bool INTSCOptimize(const bitCapInt &toMod, bitLenInt start, bitLenInt length, bool isAdd, bitLenInt carryIndex, bitLenInt overflowIndex)
Check if arithmetic with both carry and overflow can be optimized.
Definition: qunit.cpp:2868
bool useHostRam
Definition: qunit.hpp:34
void EndEmulation(bitLenInt target)
Definition: qunit.hpp:1221
void(QAlu::* CMULFn)(const bitCapInt &, bitLenInt, bitLenInt, bitLenInt, const std::vector< bitLenInt > &)
Definition: qunit.hpp:695
virtual void SetQuantumState(const complex *inputState)
Set an arbitrary pure quantum state representation.
Definition: qunit.cpp:155
void RevertBasisX(bitLenInt i)
Definition: qunit.hpp:874
virtual void ZBase(bitLenInt target)
Definition: qunit.hpp:672
Half-precision floating-point type.
Definition: half.hpp:2222
virtual void MULModNOut(const bitCapInt &toMul, const bitCapInt &modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length)
Multiplication modulo N by integer, (out of place)
Definition: arithmetic.cpp:127
virtual bitCapInt IndexedLDA(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart, bitLenInt valueLength, const unsigned char *values, bool resetValue=true)
Set 8 bit register bits by a superposed index-offset-based read from classical memory.
Definition: qunit.cpp:3495
virtual void POWModNOut(const bitCapInt &base, const bitCapInt &modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length)
Raise a classical base to a quantum power, modulo N, (out of place)
Definition: qunit.cpp:3293
virtual void CMUL(const bitCapInt &toMul, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length, const std::vector< bitLenInt > &controls)
Controlled multiplication by integer.
Definition: qunit.cpp:3385
virtual void DECS(const bitCapInt &toSub, bitLenInt start, bitLenInt length, bitLenInt overflowIndex)
Subtract a classical integer from the register, with sign and without carry.
Definition: qinterface.hpp:2200
virtual void DECS(const bitCapInt &toSub, bitLenInt start, bitLenInt length, bitLenInt overflowIndex)
Add a classical integer to the register, with sign and without carry.
Definition: qunit.hpp:398
virtual bitCapInt IndexedADC(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart, bitLenInt valueLength, bitLenInt carryIndex, const unsigned char *values)
Add to entangled 8 bit register state with a superposed index-offset-based read from classical memory...
Definition: qunit.cpp:3531
virtual void INCDECBCDC(const bitCapInt &toSub, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Common driver method behind INCSC and DECSC (without overflow flag)
Definition: qunit.cpp:3216
virtual void INCDECC(const bitCapInt &toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Common driver method behind INCC and DECC.
Definition: arithmetic.cpp:53
virtual void CMULModNOut(const bitCapInt &toMul, const bitCapInt &modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length, const std::vector< bitLenInt > &controls)
Controlled multiplication modulo N by integer, (out of place)
Definition: qunit.hpp:426
virtual void CPhaseFlipIfLess(const bitCapInt &greaterPerm, bitLenInt start, bitLenInt length, bitLenInt flagIndex)
The 6502 uses its carry flag also as a greater-than/less-than flag, for the CMP operation.
Definition: qunit.cpp:3673
virtual void CINC(const bitCapInt &toAdd, bitLenInt inOutStart, bitLenInt length, const std::vector< bitLenInt > &controls)
Add integer (without sign, with controls)
Definition: arithmetic.cpp:79
virtual void INCBCD(const bitCapInt &toAdd, bitLenInt start, bitLenInt length)
Add classical BCD integer (without sign)
Definition: qunit.cpp:3194
virtual void Hash(bitLenInt start, bitLenInt length, const unsigned char *values)
Transform a length of qubit register via lookup through a hash table.
Definition: qunit.cpp:3633
virtual void INC(const bitCapInt &toAdd, bitLenInt start, bitLenInt length)
Add integer (without sign)
Definition: qunit.cpp:3094
virtual void DEC(const bitCapInt &toSub, bitLenInt start, bitLenInt length)
Subtract classical integer (without sign)
Definition: qinterface.hpp:2141
virtual void CDIV(const bitCapInt &toDiv, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length, const std::vector< bitLenInt > &controls)
Controlled division by power of integer.
Definition: qunit.cpp:3414
virtual void INCC(const bitCapInt &toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Add integer (without sign, with carry)
Definition: qunit.cpp:3100
virtual void DECBCD(const bitCapInt &toAdd, bitLenInt start, bitLenInt length)
Subtract classical BCD integer (without sign)
Definition: qunit.cpp:3205
virtual void MULModNOut(const bitCapInt &toMul, const bitCapInt &modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length)
Multiplication modulo N by integer, (out of place)
Definition: qunit.hpp:416
virtual void DECC(const bitCapInt &toSub, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Subtract integer (without sign, with carry)
Definition: qunit.cpp:3111
virtual void CPOWModNOut(const bitCapInt &base, const bitCapInt &modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length, const std::vector< bitLenInt > &controls)
Controlled, raise a classical base to a quantum power, modulo N, (out of place)
Definition: qunit.cpp:3443
virtual void DEC(const bitCapInt &toSub, bitLenInt start, bitLenInt length)
Add integer (without sign)
Definition: qunit.hpp:394
virtual void CINC(const bitCapInt &toAdd, bitLenInt inOutStart, bitLenInt length, const std::vector< bitLenInt > &controls)
Add integer (without sign, with controls)
Definition: qunit.hpp:402
virtual bitCapInt IndexedSBC(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart, bitLenInt valueLength, bitLenInt carryIndex, const unsigned char *values)
Subtract from an entangled 8 bit register state with a superposed index-offset-based read from classi...
Definition: qunit.cpp:3582
virtual void INCS(const bitCapInt &toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex)
Add a classical integer to the register, with sign and without carry.
Definition: qunit.cpp:3177
virtual void IMULModNOut(const bitCapInt &toMul, const bitCapInt &modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length)
Inverse of multiplication modulo N by integer, (out of place)
Definition: arithmetic.cpp:165
virtual void MUL(const bitCapInt &toMul, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length)
Multiply by integer.
Definition: qunit.cpp:3223
virtual void CDEC(const bitCapInt &toSub, bitLenInt inOutStart, bitLenInt length, const std::vector< bitLenInt > &controls)
Subtract classical integer (without sign, with controls)
Definition: qinterface.hpp:2181
virtual void CIMULModNOut(const bitCapInt &toMul, const bitCapInt &modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length, const std::vector< bitLenInt > &controls)
Inverse of controlled multiplication modulo N by integer, (out of place)
Definition: qunit.hpp:431
virtual void PhaseFlipIfLess(const bitCapInt &greaterPerm, bitLenInt start, bitLenInt length)
This is an expedient for an adaptive Grover's search for a function's global minimum.
Definition: qunit.cpp:3653
virtual void CMULModNOut(const bitCapInt &toMul, const bitCapInt &modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length, const std::vector< bitLenInt > &controls)
Controlled multiplication modulo N by integer, (out of place)
Definition: arithmetic.cpp:201
virtual void CIMULModNOut(const bitCapInt &toMul, const bitCapInt &modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length, const std::vector< bitLenInt > &controls)
Inverse of controlled multiplication modulo N by integer, (out of place)
Definition: arithmetic.cpp:240
virtual void IMULModNOut(const bitCapInt &toMul, const bitCapInt &modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length)
Inverse of multiplication modulo N by integer, (out of place)
Definition: qunit.hpp:421
virtual void INCDECC(const bitCapInt &toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Common driver method behind INCC and DECC (without sign, with carry)
Definition: qunit.hpp:412
virtual void INCDECSC(const bitCapInt &toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex, bitLenInt carryIndex)
Common driver method behind INCSC and DECSC (with overflow flag)
Definition: qunit.cpp:3182
virtual void DIV(const bitCapInt &toDiv, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length)
Divide by integer.
Definition: qunit.cpp:3257
virtual void CDEC(const bitCapInt &toSub, bitLenInt inOutStart, bitLenInt length, const std::vector< bitLenInt > &controls)
Subtract integer (without sign, with controls)
Definition: qunit.hpp:407
virtual void CSwap(const std::vector< bitLenInt > &controls, bitLenInt qubit1, bitLenInt qubit2)
Apply a swap with arbitrary control bits.
Definition: qunit.cpp:2500
virtual void MACPhase(const std::vector< bitLenInt > &controls, const complex &topLeft, const complex &bottomRight, bitLenInt target)
Apply a single bit transformation that only effects phase, with arbitrary (anti-)control bits.
Definition: qunit.hpp:332
virtual void CNOT(bitLenInt control, bitLenInt target)
Controlled NOT gate.
Definition: qinterface.hpp:716
virtual void IS(bitLenInt qubit)
Inverse S gate.
Definition: qinterface.hpp:1041
virtual void UCMtrx(const std::vector< bitLenInt > &controls, const complex *mtrx, bitLenInt target, const bitCapInt &controlPerm)
Apply an arbitrary single bit unitary transformation, with arbitrary control bits,...
Definition: qunit.cpp:2469
virtual void MACInvert(const std::vector< bitLenInt > &controls, const complex &topRight, const complex &bottomLeft, bitLenInt target)
Apply a single bit transformation that reverses bit probability and might effect phase,...
Definition: qunit.hpp:337
virtual void S(bitLenInt qubit)
S gate.
Definition: qinterface.hpp:1034
virtual void UniformlyControlledSingleBit(const std::vector< bitLenInt > &controls, bitLenInt qubit, const complex *mtrxs)
Apply a "uniformly controlled" arbitrary single bit unitary transformation.
Definition: qinterface.hpp:634
virtual bool ForceM(bitLenInt qubit, bool result, bool doForce=true, bool doApply=true)=0
Act as if is a measurement was applied, except force the (usually random) result.
virtual void H(bitLenInt qubit)
Hadamard gate.
Definition: qinterface.hpp:920
virtual void MCPhase(const std::vector< bitLenInt > &controls, const complex &topLeft, const complex &bottomRight, bitLenInt target)
Apply a single bit transformation that only effects phase, with arbitrary control bits.
Definition: qunit.hpp:318
virtual bitCapInt HighestProbAll()
Get highest probability permutation.
Definition: qunit.cpp:1488
virtual void AntiCSqrtSwap(const std::vector< bitLenInt > &controls, bitLenInt qubit1, bitLenInt qubit2)
Apply a square root of swap with arbitrary (anti) control bits.
Definition: qunit.cpp:2515
virtual void CSqrtSwap(const std::vector< bitLenInt > &controls, bitLenInt qubit1, bitLenInt qubit2)
Apply a square root of swap with arbitrary control bits.
Definition: qunit.cpp:2510
virtual void X(bitLenInt qubit)
X gate.
Definition: qinterface.hpp:1091
virtual void ZMask(const bitCapInt &mask)
Masked Z gate.
Definition: qunit.hpp:313
virtual void AntiCNOT(bitLenInt control, bitLenInt target)
Anti controlled NOT gate.
Definition: qinterface.hpp:727
virtual void AntiCSwap(const std::vector< bitLenInt > &controls, bitLenInt qubit1, bitLenInt qubit2)
Apply a swap with arbitrary (anti) control bits.
Definition: qunit.cpp:2505
virtual void AntiCISqrtSwap(const std::vector< bitLenInt > &controls, bitLenInt qubit1, bitLenInt qubit2)
Apply an inverse square root of swap with arbitrary (anti) control bits.
Definition: qunit.cpp:2525
virtual void UCInvert(const std::vector< bitLenInt > &controls, const complex &topRight, const complex &bottomLeft, bitLenInt target, const bitCapInt &controlPerm)
Apply a single bit transformation that reverses bit probability and might effect phase,...
Definition: qunit.cpp:2352
virtual void CUniformParityRZ(const std::vector< bitLenInt > &controls, const bitCapInt &mask, real1_f angle)
If the controls are set and the target qubit set parity is odd, this applies a phase factor of .
Definition: qunit.cpp:1229
virtual void U(bitLenInt target, real1_f theta, real1_f phi, real1_f lambda)
General unitary gate.
Definition: rotational.cpp:18
virtual void MCInvert(const std::vector< bitLenInt > &controls, const complex &topRight, const complex &bottomLeft, bitLenInt target)
Apply a single bit transformation that reverses bit probability and might effect phase,...
Definition: qunit.hpp:325
virtual void Phase(const complex &topLeft, const complex &bottomRight, bitLenInt qubitIndex)
Apply a single bit transformation that only effects phase.
Definition: qunit.cpp:2172
virtual void Invert(const complex &topRight, const complex &bottomLeft, bitLenInt qubitIndex)
Apply a single bit transformation that reverses bit probability and might effect phase.
Definition: qunit.cpp:2232
virtual void Mtrx(const complex *mtrx, bitLenInt qubit)
Apply an arbitrary single bit unitary transformation.
Definition: qunit.cpp:2414
virtual void MCMtrx(const std::vector< bitLenInt > &controls, const complex *mtrx, bitLenInt target)
Apply an arbitrary single bit unitary transformation, with arbitrary control bits.
Definition: qunit.hpp:347
virtual void MACMtrx(const std::vector< bitLenInt > &controls, const complex *mtrx, bitLenInt target)
Apply an arbitrary single bit unitary transformation, with arbitrary (anti-)control bits.
Definition: qunit.hpp:353
virtual bool M(bitLenInt qubit)
Measurement gate.
Definition: qinterface.hpp:1020
virtual std::map< bitCapInt, int > MultiShotMeasureMask(const std::vector< bitCapInt > &qPowers, unsigned shots)
Statistical measure of masked permutation probability.
Definition: qunit.cpp:1570
virtual bitCapInt MAll()
Measure permutation state of all coherent bits.
Definition: qunit.cpp:1521
virtual void UCPhase(const std::vector< bitLenInt > &controls, const complex &topLeft, const complex &bottomRight, bitLenInt target, const bitCapInt &controlPerm)
Apply a single bit transformation that only effects phase, with arbitrary control bits,...
Definition: qunit.cpp:2284
virtual void PhaseParity(real1 radians, const bitCapInt &mask)
Definition: qunit.cpp:1030
virtual void CISqrtSwap(const std::vector< bitLenInt > &controls, bitLenInt qubit1, bitLenInt qubit2)
Apply an inverse square root of swap with arbitrary control bits.
Definition: qunit.cpp:2520
virtual void SetReg(bitLenInt start, bitLenInt length, const bitCapInt &value)
Set register bits to given permutation.
Definition: qunit.cpp:1771
virtual bitCapInt ForceMReg(bitLenInt start, bitLenInt length, const bitCapInt &result, bool doForce=true, bool doApply=true)
Act as if is a measurement was applied, except force the (usually random) result.
Definition: qinterface.cpp:213
virtual void Swap(bitLenInt qubit1, bitLenInt qubit2)
Swap values of two bits in register.
Definition: qunit.hpp:479
virtual void SqrtSwap(bitLenInt qubit1, bitLenInt qubit2)
Square root of Swap gate.
Definition: qunit.cpp:1844
virtual void IISwap(bitLenInt qubit1, bitLenInt qubit2)
Inverse ISwap - Swap values of two bits in register, and apply phase factor of -i if bits are differe...
Definition: qunit.hpp:497
virtual void ISqrtSwap(bitLenInt qubit1, bitLenInt qubit2)
Inverse square root of Swap gate.
Definition: qunit.cpp:1878
virtual void ISwap(bitLenInt qubit1, bitLenInt qubit2)
Swap values of two bits in register, and apply phase factor of i if bits are different.
Definition: qunit.hpp:496
virtual void SetNcrp(real1_f ncrp)
Set the "Near-clifford rounding parameter" value, (between 0 and 1)
Definition: qunit.hpp:618
virtual real1_f VarianceBitsFactorized(const std::vector< bitLenInt > &bits, const std::vector< bitCapInt > &perms, const bitCapInt &offset=ZERO_BCI)
Get expectation value of bits, given an array of qubit weights.
Definition: qunit.hpp:553
virtual real1_f ExpectationBitsFactorizedRdm(bool roundRz, const std::vector< bitLenInt > &bits, const std::vector< bitCapInt > &perms, const bitCapInt &offset=ZERO_BCI)
Get (reduced density matrix) expectation value of bits, given an array of qubit weights.
Definition: qunit.hpp:548
virtual bool TrySeparate(const std::vector< bitLenInt > &qubits, real1_f error_tol)
Qrack::QUnit types maintain explicit separation of representations of qubits, which reduces memory us...
Definition: qunit.hpp:590
virtual bool isClifford()
Returns "true" if current state is identifiably within the Clifford set, or "false" if it is not or c...
Definition: qinterface.hpp:2874
virtual void UpdateRunningNorm(real1_f norm_thresh=REAL1_DEFAULT_ARG)
Force a calculation of the norm of the state vector, in order to make it unit length before the next ...
Definition: qunit.cpp:3731
virtual real1_f ProbParity(const bitCapInt &mask)
Overall probability of any odd permutation of the masked set of bits.
Definition: qunit.cpp:1106
virtual QInterfacePtr Copy()
Copy this QInterface.
Definition: qunit.cpp:3873
virtual QInterfacePtr Copy()
Copy this QInterface.
Definition: qinterface.hpp:2992
virtual real1_f SumSqrDiff(QInterfacePtr toCompare)
Calculates (1 - <\psi_e|\psi_c>) between states |\psi_c> and |\psi_e>.
Definition: qunit.hpp:538
virtual bool isFinished()
Returns "false" if asynchronous work is still running, and "true" if all previously dispatched asynch...
Definition: qunit.cpp:3762
virtual void SetSparseAceMaxMb(size_t mb)
Set the (sparse-simulation) "automatic circuit elision" (ACE) maximum memory megabytes.
Definition: qunit.hpp:630
virtual real1_f ExpectationBitsFactorized(const std::vector< bitLenInt > &bits, const std::vector< bitCapInt > &perms, const bitCapInt &offset=ZERO_BCI)
Get expectation value of bits, given an array of qubit weights.
Definition: qunit.hpp:543
virtual bool isClifford(bitLenInt qubit)
Returns "true" if current qubit state is identifiably within the Clifford set, or "false" if it is no...
Definition: qunit.hpp:578
virtual QInterfacePtr Clone()
Clone this QInterface.
Definition: qunit.cpp:3865
virtual real1_f ProbAllRdm(bool roundRz, const bitCapInt &perm)
Direct measure of full permutation probability, treating all ancillary qubits as post-selected T gate...
Definition: qunit.hpp:519
virtual void NormalizeState(real1_f nrm=REAL1_DEFAULT_ARG, real1_f norm_thresh=REAL1_DEFAULT_ARG, real1_f phaseArg=ZERO_R1_F)
Apply the normalization factor found by UpdateRunningNorm() or on the fly by a single bit gate.
Definition: qunit.cpp:3742
virtual real1_f VarianceBitsFactorizedRdm(bool roundRz, const std::vector< bitLenInt > &bits, const std::vector< bitCapInt > &perms, const bitCapInt &offset=ZERO_BCI)
Get (reduced density matrix) expectation value of bits, given an array of qubit weights.
Definition: qunit.hpp:558
virtual double GetUnitaryFidelity()
When "Schmidt-decomposition rounding parameter" ("SDRP") is being used, starting from initial 1....
Definition: qunit.cpp:3699
virtual void SetSdrp(real1_f sdrp)
Set the "Schmidt decomposition rounding parameter" value, (between 0 and 1)
Definition: qunit.hpp:613
virtual real1_f ProbAll(const bitCapInt &perm)
Direct measure of full permutation probability.
Definition: qunit.hpp:518
virtual real1_f Prob(bitLenInt qubit)
Direct measure of bit probability to be in |1> state.
Definition: qunit.hpp:509
virtual void ResetUnitaryFidelity()
Reset the internal fidelity calculation tracker to 1.0.
Definition: qunit.hpp:612
virtual void SetAceMaxQubits(bitLenInt qb)
Set the "automatic circuit elision" (ACE) maximum entangled subsystem qubit count.
Definition: qunit.hpp:629
virtual void Dump()
If asynchronous work is still running, let the simulator know that it can be aborted.
Definition: qunit.hpp:568
virtual bool TrySeparate(const std::vector< bitLenInt > &qubits, real1_f error_tol)
Qrack::QUnit types maintain explicit separation of representations of qubits, which reduces memory us...
Definition: qinterface.hpp:2900
virtual void Finish()
If asynchronous work is still running, block until it finishes.
Definition: qunit.cpp:3753
virtual bool ForceMParity(const bitCapInt &mask, bool result, bool doForce=true)
Act as if is a measurement of parity of the masked set of qubits was applied, except force the (usual...
Definition: qunit.cpp:1164
GLOSSARY: bitLenInt - "bit-length integer" - unsigned integer ID of qubit position in register bitCap...
Definition: complex16x2simd.hpp:25
void ThrowIfQbIdArrayIsBad(const std::vector< bitLenInt > &controls, const bitLenInt &qubitCount, std::string message)
Definition: qrack_functions.hpp:185
QRACK_CONST real1_f FP_NORM_EPSILON_F
Definition: qrack_types.hpp:269
QRACK_CONST real1 SQRT1_2_R1
Definition: qrack_types.hpp:188
@ QINTERFACE_STABILIZER_HYBRID
Create a QStabilizerHybrid, switching between a QStabilizer and a QHybrid as efficient.
Definition: qinterface.hpp:77
std::shared_ptr< QUnit > QUnitPtr
Definition: qunit.hpp:24
std::shared_ptr< QInterface > QInterfacePtr
Definition: qinterface.hpp:29
const real1_f _qrack_qunit_sep_thresh
Definition: qrack_functions.hpp:249
QRACK_CONST real1_f TRYDECOMPOSE_EPSILON
Definition: qrack_types.hpp:270
QRACK_CONST real1 HALF_R1
Definition: qrack_types.hpp:192
std::shared_ptr< PhaseShard > PhaseShardPtr
Definition: qengineshard.hpp:46
half_float::half real1
Definition: qrack_types.hpp:102
std::complex< real1 > complex
Definition: qrack_types.hpp:136
QRACK_CONST real1 FP_NORM_EPSILON
Definition: qrack_types.hpp:268
bitCapInt pow2(const bitLenInt &p)
Definition: qrack_functions.hpp:143
double norm(const complex2 &c)
Definition: complex16x2simd.hpp:122
QRACK_CONST real1 REAL1_EPSILON
Definition: qrack_types.hpp:208
QRACK_CONST complex ONE_CMPLX
Definition: qrack_types.hpp:262
QRACK_CONST real1 ONE_R1
Definition: qrack_types.hpp:193
QRACK_CONST real1 ZERO_R1
Definition: qrack_types.hpp:191
float real1_f
Definition: qrack_types.hpp:103
QRACK_CONST complex CMPLX_DEFAULT_ARG
Definition: qrack_types.hpp:267
QRACK_CONST complex I_CMPLX
Definition: qrack_types.hpp:264
std::map< QEngineShardPtr, PhaseShardPtr > ShardToPhaseMap
Definition: qengineshard.hpp:47
@ PauliX
Pauli X operator. Corresponds to Q# constant "PauliX.".
Definition: pauli.hpp:23
@ PauliY
Pauli Y operator. Corresponds to Q# constant "PauliY.".
Definition: pauli.hpp:25
@ PauliZ
Pauli Z operator. Corresponds to Q# constant "PauliZ.".
Definition: pauli.hpp:27
const double FIDELITY_MIN
Definition: qrack_types.hpp:271
QRACK_CONST real1 PI_R1
Definition: qrack_types.hpp:186
const bitCapInt ONE_BCI
Definition: qrack_types.hpp:137
const bitCapInt ZERO_BCI
Definition: qrack_types.hpp:138
HALF_CONSTEXPR half abs(half arg)
Absolute value.
Definition: half.hpp:2975
half sin(half arg)
Sine function.
Definition: half.hpp:3885
half log(half arg)
Natural logarithm.
Definition: half.hpp:3318
half cos(half arg)
Cosine function.
Definition: half.hpp:3922
#define REAL1_DEFAULT_ARG
Definition: qrack_types.hpp:185
#define QRACK_CONST
Definition: qrack_types.hpp:182
#define bitLenInt
Definition: qrack_types.hpp:42
#define ZERO_R1_F
Definition: qrack_types.hpp:168
#define qrack_rand_gen_ptr
Definition: qrack_types.hpp:164
#define bitCapInt
Definition: qrack_types.hpp:66
#define ONE_R1_F
Definition: qrack_types.hpp:171
#define IS_NORM_0(c)
Definition: qrack_types.hpp:29
Definition: qunit.hpp:798
bool operator<(const QSortEntry &rhs)
Definition: qunit.hpp:801
bitLenInt mapped
Definition: qunit.hpp:800
bool operator>(const QSortEntry &rhs)
Definition: qunit.hpp:802
bitLenInt bit
Definition: qunit.hpp:799