Qrack  10.0
General classical-emulating-quantum development framework
qbdt.hpp
Go to the documentation of this file.
1 //
3 // (C) Daniel Strano and the Qrack contributors 2017-2023. All rights reserved.
4 //
5 // QBinaryDecision tree is an alternative approach to quantum state representation, as
6 // opposed to state vector representation. This is a compressed form that can be
7 // operated directly on while compressed. Inspiration for the Qrack implementation was
8 // taken from JKQ DDSIM, maintained by the Institute for Integrated Circuits at the
9 // Johannes Kepler University Linz:
10 //
11 // https://github.com/iic-jku/ddsim
12 //
13 // Licensed under the GNU Lesser General Public License V3.
14 // See LICENSE.md in the project root or https://www.gnu.org/licenses/lgpl-3.0.en.html
15 // for details.
16 
17 #pragma once
18 
19 #include "mpsshard.hpp"
20 #include "qbdt_node.hpp"
21 #include "qengine.hpp"
22 #include "qengine_gpu_util.hpp"
23 
24 #include <algorithm>
25 
26 #define QINTERFACE_TO_QALU(qReg) std::dynamic_pointer_cast<QAlu>(qReg)
27 #define QINTERFACE_TO_QPARITY(qReg) std::dynamic_pointer_cast<QParity>(qReg)
28 
29 namespace Qrack {
30 
31 class QBdt;
32 typedef std::shared_ptr<QBdt> QBdtPtr;
33 
34 typedef std::function<void(const bitCapInt&, const unsigned& cpu)> ParallelFuncBdt;
35 
36 #if ENABLE_ALU
37 class QBdt : public QAlu, public QParity, public QInterface {
38 #else
39 class QBdt : public QParity, public QInterface {
40 #endif
41 protected:
43  int64_t devID;
46  std::vector<int64_t> deviceIDs;
47  std::vector<QInterfaceEngine> engines;
48 
49  QEnginePtr MakeQEngine(bitLenInt qbCount, const bitCapInt& perm = ZERO_BCI);
50 
51  template <typename Fn> void GetTraversal(Fn getLambda)
52  {
53  _par_for(maxQPower, [&](const bitCapInt& i, const unsigned& cpu) {
55  complex scale = leaf->scale;
56  for (bitLenInt j = 0U; j < qubitCount; ++j) {
57  leaf = leaf->branches[SelectBit(i, j)];
58  if (!leaf) {
59  break;
60  }
61  scale *= leaf->scale;
62  }
63 
64  getLambda((bitCapIntOcl)i, scale);
65  });
66  }
67  template <typename Fn> void SetTraversal(Fn setLambda)
68  {
70  throw bad_alloc("RAM limits exceeded in QBdt::SetTraversal()");
71  }
72 
73  root = std::make_shared<QBdtNode>();
74 #if ENABLE_QBDT_CPU_PARALLEL && ENABLE_PTHREAD
75  if (true) {
76  std::lock_guard<std::mutex> lock(root->mtx);
77  root->Branch(qubitCount);
78  }
79 #else
80  root->Branch(qubitCount);
81 #endif
82 
83  _par_for(maxQPower, [&](const bitCapInt& i, const unsigned& cpu) {
85  for (bitLenInt j = 0U; j < qubitCount; ++j) {
86  leaf = leaf->branches[SelectBit(i, j)];
87  }
88 
89  setLambda((bitCapIntOcl)i, leaf);
90  });
91 
92  root->PopStateVector(qubitCount);
93  root->Prune(qubitCount);
94  }
95  template <typename Fn> void ExecuteAsStateVector(Fn operation)
96  {
98  GetQuantumState(qReg);
99  operation(qReg);
100  SetQuantumState(qReg);
101  }
102 
103  template <typename Fn> bitCapInt BitCapIntAsStateVector(Fn operation)
104  {
106  GetQuantumState(qReg);
107  const bitCapInt toRet = operation(qReg);
108  SetQuantumState(qReg);
109  return toRet;
110  }
111 
112  template <typename Fn> bool BoolAsStateVector(Fn operation)
113  {
115  GetQuantumState(qReg);
116  const bool toRet = operation(qReg);
117  SetQuantumState(qReg);
118  return toRet;
119  }
120 
121  void par_for_qbdt(const bitCapInt& end, bitLenInt maxQubit, BdtFunc fn, bool branch = true);
122  void _par_for(const bitCapInt& end, ParallelFuncBdt fn);
123 
124  void DecomposeDispose(bitLenInt start, bitLenInt length, QBdtPtr dest);
125 
126  void ApplyControlledSingle(const complex mtrx[4U], std::vector<bitLenInt> controls, bitLenInt target, bool isAnti);
127 
128  static size_t SelectBit(const bitCapInt& perm, bitLenInt bit) { return (size_t)bi_and_1(perm >> bit); }
129 
130  static bitCapInt RemovePower(const bitCapInt& perm, bitCapInt power)
131  {
132  bi_decrement(&power, 1U);
133  return (perm & power) | ((perm >> 1U) & ~power);
134  }
135 
136  void ApplySingle(const complex mtrx[4U], bitLenInt target);
137 
138  void Init();
139 
140  bitCapInt MAllOptionalCollapse(bool isCollapsing);
141 
142  bitCapInt SampleClone(const std::vector<bitCapInt>& qPowers)
143  {
144  const bitCapInt rawSample = MAllOptionalCollapse(false);
145  bitCapInt sample = ZERO_BCI;
146  for (size_t i = 0U; i < qPowers.size(); ++i) {
147  if (bi_compare_0(rawSample & qPowers[i]) != 0) {
148  bi_or_ip(&sample, pow2(i));
149  }
150  }
151  return sample;
152  }
153 
154  using QInterface::Copy;
155  void Copy(QInterfacePtr orig) { Copy(std::dynamic_pointer_cast<QBdt>(orig)); }
156  void Copy(QBdtPtr orig)
157  {
158  QInterface::Copy(orig);
159  bdtStride = orig->bdtStride;
160  devID = orig->devID;
161  root = orig->root;
162  bdtMaxQPower = orig->bdtMaxQPower;
163  deviceIDs = orig->deviceIDs;
164  engines = orig->engines;
165  }
166 
167 public:
168  QBdt(std::vector<QInterfaceEngine> eng, bitLenInt qBitCount, const bitCapInt& initState = ZERO_BCI,
169  qrack_rand_gen_ptr rgp = nullptr, const complex& phaseFac = CMPLX_DEFAULT_ARG, bool doNorm = false,
170  bool randomGlobalPhase = true, bool useHostMem = false, int64_t deviceId = -1, bool useHardwareRNG = true,
171  bool useSparseStateVec = false, real1_f norm_thresh = REAL1_EPSILON, std::vector<int64_t> ignored = {},
172  bitLenInt qubitThreshold = 0, real1_f separation_thresh = _qrack_qunit_sep_thresh);
173 
174  QBdt(bitLenInt qBitCount, const bitCapInt& initState = ZERO_BCI, qrack_rand_gen_ptr rgp = nullptr,
175  const complex& phaseFac = CMPLX_DEFAULT_ARG, bool doNorm = false, bool randomGlobalPhase = true,
176  bool useHostMem = false, int64_t deviceId = -1, bool useHardwareRNG = true, bool useSparseStateVec = false,
177  real1_f norm_thresh = REAL1_EPSILON, std::vector<int64_t> devList = {}, bitLenInt qubitThreshold = 0U,
178  real1_f separation_thresh = _qrack_qunit_sep_thresh)
179  : QBdt({ QINTERFACE_HYBRID }, qBitCount, initState, rgp, phaseFac, doNorm, randomGlobalPhase, useHostMem,
180  deviceId, useHardwareRNG, useSparseStateVec, norm_thresh, devList, qubitThreshold, separation_thresh)
181  {
182  }
183 
184  size_t CountBranches();
185 
186  bool isBinaryDecisionTree() { return true; };
187 
188  void SetDevice(int64_t dID) { devID = dID; }
189  void SetDeviceList(std::vector<int64_t> dIDs) { deviceIDs = dIDs; }
190  int64_t GetDevice() { return devID; }
191  std::vector<int64_t> GetDeviceList() { return deviceIDs; }
192 
194  {
195  // Intentionally left blank.
196  }
197 
199  real1_f nrm = REAL1_DEFAULT_ARG, real1_f norm_thresh = REAL1_DEFAULT_ARG, real1_f phaseArg = ZERO_R1_F)
200  {
201  root->Normalize(qubitCount);
202  }
203 
204  real1_f SumSqrDiff(QInterfacePtr toCompare) { return SumSqrDiff(std::dynamic_pointer_cast<QBdt>(toCompare)); }
205  real1_f SumSqrDiff(QBdtPtr toCompare);
206 
207  void SetPermutation(const bitCapInt& initState, const complex& phaseFac = CMPLX_DEFAULT_ARG);
208 
210 
212  {
213  GetTraversal([state](bitCapIntOcl i, const complex& scale) { state[i] = scale; });
214  }
216  {
217  GetTraversal([eng](bitCapIntOcl i, const complex& scale) { eng->SetAmplitude(i, scale); });
218  }
219  void SetQuantumState(const complex* state)
220  {
221  SetTraversal([state](bitCapIntOcl i, QBdtNodeInterfacePtr leaf) { leaf->scale = state[i]; });
222  }
224  {
225  SetTraversal([eng](bitCapIntOcl i, QBdtNodeInterfacePtr leaf) { leaf->scale = eng->GetAmplitude(i); });
226  }
227  void GetProbs(real1* outputProbs)
228  {
229  GetTraversal([outputProbs](bitCapIntOcl i, const complex& scale) { outputProbs[i] = norm(scale); });
230  }
231 
232  complex GetAmplitude(const bitCapInt& perm);
233  void SetAmplitude(const bitCapInt& perm, const complex& amp)
234  {
235  ExecuteAsStateVector([&](QInterfacePtr eng) { eng->SetAmplitude(perm, amp); });
236  }
237 
242  bool IsSeparable(bitLenInt start);
243 
245  {
246  if (error_tol > TRYDECOMPOSE_EPSILON) {
247  return QInterface::TryDecompose(start, dest, error_tol);
248  }
249 
250  const bitLenInt length = dest->GetQubitCount();
251  const bitLenInt nStart = qubitCount - length;
252  const bitLenInt shift = nStart - start;
253  for (bitLenInt i = 0U; i < shift; ++i) {
254  Swap(start + i, qubitCount - (i + 1U));
255  }
256 
257  const bool isSeparable = IsSeparable(nStart);
258 
259  for (bitLenInt i = shift; i > 0U; --i) {
260  Swap(start + (i - 1U), qubitCount - i);
261  }
262 
263  if (isSeparable) {
264  Decompose(start, dest);
265  return true;
266  }
267 
268  return false;
269  }
270 
272  bool TrySeparate(const std::vector<bitLenInt>& _qubits, real1_f error_tol)
273  {
275  "QBdt::TrySeparate parameter qubit array values must be within allocated qubit bounds!");
276 
277  if (!_qubits.size() || (_qubits.size() == qubitCount)) {
278  return true;
279  }
280 
281  std::vector<bitLenInt> qubits(_qubits);
282  std::sort(qubits.begin(), qubits.end());
283  for (size_t i = 0U; i < qubits.size(); ++i) {
284  Swap(i, qubits[i]);
285  }
286  const bool result = IsSeparable(qubits.size());
287  for (bitLenInt i = qubits.size(); i > 0U; --i) {
288  Swap(i - 1U, qubits[i - 1U]);
289  }
290 
291  return result;
292  }
293  bool TrySeparate(bitLenInt qubit)
294  {
295  if (qubit >= qubitCount) {
296  throw std::invalid_argument("QBdt::TrySeparate argument out-of-bounds!");
297  }
298  if (qubitCount == 1U) {
299  return true;
300  }
301 
302  Swap(qubit, 0U);
303  const bool result = IsSeparable(1U);
304  Swap(qubit, 0U);
305 
306  return result;
307  }
308  bool TrySeparate(bitLenInt qubit1, bitLenInt qubit2)
309  {
310  if (qubit1 == qubit2) {
311  throw std::invalid_argument("QBdt::TrySeparate qubits must be distinct!");
312  }
313  if ((qubit1 >= qubitCount) || (qubit2 >= qubitCount)) {
314  throw std::invalid_argument("QBdt::TrySeparate argument out-of-bounds!");
315  }
316  if (qubitCount == 2U) {
317  return true;
318  }
319  if (qubit1 > qubit2) {
320  std::swap(qubit1, qubit2);
321  }
322 
323  Swap(qubit1, 0U);
324  Swap(qubit2, 1U);
325  const bool result = IsSeparable(2U);
326  Swap(qubit2, 1U);
327  Swap(qubit1, 0U);
328 
329  return result;
330  }
331 
332  using QInterface::Compose;
333  bitLenInt Compose(QBdtPtr toCopy, bitLenInt start);
335  {
336  return Compose(std::dynamic_pointer_cast<QBdt>(toCopy), start);
337  }
339  {
340  QBdtPtr d = std::dynamic_pointer_cast<QBdt>(dest);
341  DecomposeDispose(start, dest->GetQubitCount(), d);
342  }
344  void Dispose(bitLenInt start, bitLenInt length) { DecomposeDispose(start, length, nullptr); }
345 
346  void Dispose(bitLenInt start, bitLenInt length, const bitCapInt& disposedPerm)
347  {
348  ForceMReg(start, length, disposedPerm);
349  DecomposeDispose(start, length, nullptr);
350  }
351 
352  using QInterface::Allocate;
353  bitLenInt Allocate(bitLenInt start, bitLenInt length);
354 
355  real1_f Prob(bitLenInt qubitIndex);
356  real1_f ProbAll(const bitCapInt& fullRegister);
357 
358  bool ForceM(bitLenInt qubit, bool result, bool doForce = true, bool doApply = true)
359  {
360  return BoolAsStateVector([&](QInterfacePtr eng) { return eng->ForceM(qubit, result, doForce, doApply); });
361  }
362  bitCapInt MAll() { return MAllOptionalCollapse(true); }
363 
364  void Mtrx(const complex mtrx[4U], bitLenInt target);
365  void MCMtrx(const std::vector<bitLenInt>& controls, const complex mtrx[4U], bitLenInt target);
366  void MACMtrx(const std::vector<bitLenInt>& controls, const complex mtrx[4U], bitLenInt target);
367  void MCPhase(
368  const std::vector<bitLenInt>& controls, const complex& topLeft, const complex& bottomRight, bitLenInt target);
369  void MCInvert(
370  const std::vector<bitLenInt>& controls, const complex& topRight, const complex& bottomLeft, bitLenInt target);
371 
372  void FSim(real1_f theta, real1_f phi, bitLenInt qubitIndex1, bitLenInt qubitIndex2);
373 
374  void Swap(bitLenInt q1, bitLenInt q2)
375  {
376  if (q2 < q1) {
377  std::swap(q1, q2);
378  }
379  QInterface::Swap(q1, q2);
380  }
381  void ISwap(bitLenInt q1, bitLenInt q2)
382  {
383  if (q2 < q1) {
384  std::swap(q1, q2);
385  }
386  QInterface::ISwap(q1, q2);
387  }
389  {
390  if (q2 < q1) {
391  std::swap(q1, q2);
392  }
393  QInterface::IISwap(q1, q2);
394  }
396  {
397  if (q2 < q1) {
398  std::swap(q1, q2);
399  }
400  QInterface::SqrtSwap(q1, q2);
401  }
403  {
404  if (q2 < q1) {
405  std::swap(q1, q2);
406  }
407  QInterface::ISqrtSwap(q1, q2);
408  }
409  void CSwap(const std::vector<bitLenInt>& controls, bitLenInt q1, bitLenInt q2)
410  {
411  if (q2 < q1) {
412  std::swap(q1, q2);
413  }
414  QInterface::CSwap(controls, q1, q2);
415  }
416  void CSqrtSwap(const std::vector<bitLenInt>& controls, bitLenInt q1, bitLenInt q2)
417  {
418  if (q2 < q1) {
419  std::swap(q1, q2);
420  }
421  QInterface::CSqrtSwap(controls, q1, q2);
422  }
423  void CISqrtSwap(const std::vector<bitLenInt>& controls, bitLenInt q1, bitLenInt q2)
424  {
425  if (q2 < q1) {
426  std::swap(q1, q2);
427  }
428  QInterface::CISqrtSwap(controls, q1, q2);
429  }
430 
432  {
433  if (bi_compare_0(mask) == 0) {
434  return ZERO_R1_F;
435  }
436 
437  bitCapInt maskMin1 = mask;
438  bi_decrement(&maskMin1, 1U);
439  if (bi_compare_0(mask & maskMin1) == 0) {
440  return Prob(log2(mask));
441  }
442 
443  real1_f toRet;
444  ExecuteAsStateVector([&](QInterfacePtr eng) { toRet = QINTERFACE_TO_QPARITY(eng)->ProbParity(mask); });
445 
446  return toRet;
447  }
448  void CUniformParityRZ(const std::vector<bitLenInt>& controls, const bitCapInt& mask, real1_f angle)
449  {
451  [&](QInterfacePtr eng) { QINTERFACE_TO_QPARITY(eng)->CUniformParityRZ(controls, mask, angle); });
452  }
453  bool ForceMParity(const bitCapInt& mask, bool result, bool doForce = true)
454  {
455  // If no bits in mask:
456  if (bi_compare_0(mask) == 0) {
457  return false;
458  }
459 
460  // If only one bit in mask:
461  bitCapInt maskMin1 = mask;
462  bi_decrement(&maskMin1, 1U);
463  if (bi_compare_0(mask & maskMin1) == 0) {
464  return ForceM(log2(mask), result, doForce);
465  }
466 
467  bool toRet;
469  [&](QInterfacePtr eng) { toRet = QINTERFACE_TO_QPARITY(eng)->ForceMParity(mask, result, doForce); });
470 
471  return toRet;
472  }
473 
474 #if ENABLE_ALU
475  using QInterface::M;
476  bool M(bitLenInt q) { return QInterface::M(q); }
477  using QInterface::X;
478  void X(bitLenInt q) { QInterface::X(q); }
479  void INC(const bitCapInt& toAdd, bitLenInt start, bitLenInt length) { QInterface::INC(toAdd, start, length); }
480  void DEC(const bitCapInt& toSub, bitLenInt start, bitLenInt length) { QInterface::DEC(toSub, start, length); }
481  void INCC(const bitCapInt& toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
482  {
483  QInterface::INCC(toAdd, start, length, carryIndex);
484  }
485  void DECC(const bitCapInt& toSub, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
486  {
487  QInterface::DECC(toSub, start, length, carryIndex);
488  }
489  void INCS(const bitCapInt& toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex)
490  {
491  QInterface::INCS(toAdd, start, length, overflowIndex);
492  }
493  void DECS(const bitCapInt& toSub, bitLenInt start, bitLenInt length, bitLenInt overflowIndex)
494  {
495  QInterface::DECS(toSub, start, length, overflowIndex);
496  }
497  void CINC(const bitCapInt& toAdd, bitLenInt inOutStart, bitLenInt length, const std::vector<bitLenInt>& controls)
498  {
499  QInterface::CINC(toAdd, inOutStart, length, controls);
500  }
501  void CDEC(const bitCapInt& toSub, bitLenInt inOutStart, bitLenInt length, const std::vector<bitLenInt>& controls)
502  {
503  QInterface::CDEC(toSub, inOutStart, length, controls);
504  }
505  void INCDECC(const bitCapInt& toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
506  {
507  QInterface::INCDECC(toAdd, start, length, carryIndex);
508  }
510  const bitCapInt& toMul, const bitCapInt& modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length)
511  {
512  QInterface::MULModNOut(toMul, modN, inStart, outStart, length);
513  }
515  const bitCapInt& toMul, const bitCapInt& modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length)
516  {
517  QInterface::IMULModNOut(toMul, modN, inStart, outStart, length);
518  }
519  void CMULModNOut(const bitCapInt& toMul, const bitCapInt& modN, bitLenInt inStart, bitLenInt outStart,
520  bitLenInt length, const std::vector<bitLenInt>& controls)
521  {
522  QInterface::CMULModNOut(toMul, modN, inStart, outStart, length, controls);
523  }
524  void CIMULModNOut(const bitCapInt& toMul, const bitCapInt& modN, bitLenInt inStart, bitLenInt outStart,
525  bitLenInt length, const std::vector<bitLenInt>& controls)
526  {
527  QInterface::CIMULModNOut(toMul, modN, inStart, outStart, length, controls);
528  }
529  void PhaseFlipIfLess(const bitCapInt& greaterPerm, bitLenInt start, bitLenInt length)
530  {
532  [&](QInterfacePtr eng) { QINTERFACE_TO_QALU(eng)->PhaseFlipIfLess(greaterPerm, start, length); });
533  }
534  void CPhaseFlipIfLess(const bitCapInt& greaterPerm, bitLenInt start, bitLenInt length, bitLenInt flagIndex)
535  {
537  QINTERFACE_TO_QALU(eng)->CPhaseFlipIfLess(greaterPerm, start, length, flagIndex);
538  });
539  }
540  void INCDECSC(
541  const bitCapInt& toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex, bitLenInt carryIndex)
542  {
544  QINTERFACE_TO_QALU(eng)->INCDECSC(toAdd, start, length, overflowIndex, carryIndex);
545  });
546  }
547  void INCDECSC(const bitCapInt& toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
548  {
550  [&](QInterfacePtr eng) { QINTERFACE_TO_QALU(eng)->INCDECSC(toAdd, start, length, carryIndex); });
551  }
552 #if ENABLE_BCD
553  void INCBCD(const bitCapInt& toAdd, bitLenInt start, bitLenInt length)
554  {
555  ExecuteAsStateVector([&](QInterfacePtr eng) { QINTERFACE_TO_QALU(eng)->INCBCD(toAdd, start, length); });
556  }
557  void INCDECBCDC(const bitCapInt& toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
558  {
560  [&](QInterfacePtr eng) { QINTERFACE_TO_QALU(eng)->INCDECBCDC(toAdd, start, length, carryIndex); });
561  }
562 #endif
563  void MUL(const bitCapInt& toMul, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length)
564  {
566  [&](QInterfacePtr eng) { QINTERFACE_TO_QALU(eng)->MUL(toMul, inOutStart, carryStart, length); });
567  }
568  void DIV(const bitCapInt& toDiv, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length)
569  {
571  [&](QInterfacePtr eng) { QINTERFACE_TO_QALU(eng)->DIV(toDiv, inOutStart, carryStart, length); });
572  }
574  const bitCapInt& base, const bitCapInt& modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length)
575  {
577  [&](QInterfacePtr eng) { QINTERFACE_TO_QALU(eng)->POWModNOut(base, modN, inStart, outStart, length); });
578  }
579  void CMUL(const bitCapInt& toMul, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length,
580  const std::vector<bitLenInt>& controls)
581  {
583  [&](QInterfacePtr eng) { QINTERFACE_TO_QALU(eng)->CMUL(toMul, inOutStart, carryStart, length, controls); });
584  }
585  void CDIV(const bitCapInt& toDiv, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length,
586  const std::vector<bitLenInt>& controls)
587  {
589  [&](QInterfacePtr eng) { QINTERFACE_TO_QALU(eng)->CDIV(toDiv, inOutStart, carryStart, length, controls); });
590  }
591  void CPOWModNOut(const bitCapInt& base, const bitCapInt& modN, bitLenInt inStart, bitLenInt outStart,
592  bitLenInt length, const std::vector<bitLenInt>& controls)
593  {
595  QINTERFACE_TO_QALU(eng)->CPOWModNOut(base, modN, inStart, outStart, length, controls);
596  });
597  }
598  bitCapInt IndexedLDA(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart, bitLenInt valueLength,
599  const unsigned char* values, bool resetValue = true)
600  {
601  return BitCapIntAsStateVector([&](QInterfacePtr eng) {
602  return QINTERFACE_TO_QALU(eng)->IndexedLDA(
603  indexStart, indexLength, valueStart, valueLength, values, resetValue);
604  });
605  }
606  bitCapInt IndexedADC(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart, bitLenInt valueLength,
607  bitLenInt carryIndex, const unsigned char* values)
608  {
609  return BitCapIntAsStateVector([&](QInterfacePtr eng) {
610  return QINTERFACE_TO_QALU(eng)->IndexedADC(
611  indexStart, indexLength, valueStart, valueLength, carryIndex, values);
612  });
613  }
614  bitCapInt IndexedSBC(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart, bitLenInt valueLength,
615  bitLenInt carryIndex, const unsigned char* values)
616  {
617  return BitCapIntAsStateVector([&](QInterfacePtr eng) {
618  return QINTERFACE_TO_QALU(eng)->IndexedSBC(
619  indexStart, indexLength, valueStart, valueLength, carryIndex, values);
620  });
621  }
622  void Hash(bitLenInt start, bitLenInt length, const unsigned char* values)
623  {
624  ExecuteAsStateVector([&](QInterfacePtr eng) { QINTERFACE_TO_QALU(eng)->Hash(start, length, values); });
625  }
626 #endif
627 };
628 } // namespace Qrack
void bi_or_ip(BigInteger *left, const BigInteger &right)
Definition: big_integer.hpp:445
void bi_decrement(BigInteger *pBigInt, const BIG_INTEGER_WORD &value)
Definition: big_integer.hpp:238
int bi_and_1(const BigInteger &left)
Definition: big_integer.hpp:418
int bi_compare_0(const BigInteger &left)
Definition: big_integer.hpp:141
Definition: qalu.hpp:22
Definition: qbdt.hpp:37
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: qbdt.hpp:591
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: qbdt.hpp:606
void CINC(const bitCapInt &toAdd, bitLenInt inOutStart, bitLenInt length, const std::vector< bitLenInt > &controls)
Add integer (without sign, with controls)
Definition: qbdt.hpp:497
bool TrySeparate(bitLenInt qubit)
Single-qubit TrySeparate()
Definition: qbdt.hpp:293
void Mtrx(const complex mtrx[4U], bitLenInt target)
Apply an arbitrary single bit unitary transformation.
Definition: tree.cpp:591
void SetQuantumState(QInterfacePtr eng)
Definition: qbdt.hpp:223
bitCapInt SampleClone(const std::vector< bitCapInt > &qPowers)
Definition: qbdt.hpp:142
void DIV(const bitCapInt &toDiv, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length)
Divide by integer.
Definition: qbdt.hpp:568
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: qbdt.hpp:198
void Copy(QBdtPtr orig)
Definition: qbdt.hpp:156
bool BoolAsStateVector(Fn operation)
Definition: qbdt.hpp:112
void INCC(const bitCapInt &toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Add integer (without sign, with carry)
Definition: qbdt.hpp:481
void ISqrtSwap(bitLenInt q1, bitLenInt q2)
Inverse square root of Swap gate.
Definition: qbdt.hpp:402
bool TrySeparate(bitLenInt qubit1, bitLenInt qubit2)
Two-qubit TrySeparate()
Definition: qbdt.hpp:308
void INCDECSC(const bitCapInt &toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex, bitLenInt carryIndex)
Common driver method behind INCSC and DECSC (with overflow flag)
Definition: qbdt.hpp:540
void MCMtrx(const std::vector< bitLenInt > &controls, const complex mtrx[4U], bitLenInt target)
Apply an arbitrary single bit unitary transformation, with arbitrary control bits.
Definition: tree.cpp:593
void ISwap(bitLenInt q1, bitLenInt q2)
Swap values of two bits in register, and apply phase factor of i if bits are different.
Definition: qbdt.hpp:381
virtual bitLenInt Allocate(bitLenInt length)
Allocate new "length" count of |0> state qubits at end of qubit index position.
Definition: qinterface.hpp:488
void MULModNOut(const bitCapInt &toMul, const bitCapInt &modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length)
Multiplication modulo N by integer, (out of place)
Definition: qbdt.hpp:509
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: qbdt.hpp:529
void Copy(QInterfacePtr orig)
Definition: qbdt.hpp:155
void Dispose(bitLenInt start, bitLenInt length, const bitCapInt &disposedPerm)
Dispose a a contiguous set of qubits that are already in a permutation eigenstate.
Definition: qbdt.hpp:346
void MUL(const bitCapInt &toMul, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length)
Multiply by integer.
Definition: qbdt.hpp:563
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: qbdt.hpp:598
void INCDECC(const bitCapInt &toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Common driver method behind INCC and DECC (without sign, with carry)
Definition: qbdt.hpp:505
virtual bitLenInt Compose(QInterfacePtr toCopy)
Combine another QInterface with this one, after the last bit index of this one.
Definition: qinterface.hpp:382
bitCapInt bdtMaxQPower
Definition: qbdt.hpp:45
bool IsSeparable(bitLenInt start)
Inexpensive check for whether the QBdt is separable between low and high qubit indices at the biparti...
Definition: tree.cpp:276
real1_f Prob(bitLenInt qubitIndex)
Direct measure of bit probability to be in |1> state.
Definition: tree.cpp:350
size_t CountBranches()
Definition: tree.cpp:95
bool TryDecompose(bitLenInt start, QInterfacePtr dest, real1_f error_tol=TRYDECOMPOSE_EPSILON)
Attempt to Decompose() a bit range.
Definition: qbdt.hpp:244
void Init()
Definition: tree.cpp:39
int64_t devID
Definition: qbdt.hpp:43
bitCapInt MAll()
Measure permutation state of all coherent bits.
Definition: qbdt.hpp:362
void DecomposeDispose(bitLenInt start, bitLenInt length, QBdtPtr dest)
Definition: tree.cpp:248
void CISqrtSwap(const std::vector< bitLenInt > &controls, bitLenInt q1, bitLenInt q2)
Apply an inverse square root of swap with arbitrary control bits.
Definition: qbdt.hpp:423
void INCDECBCDC(const bitCapInt &toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Common driver method behind INCSC and DECSC (without overflow flag)
Definition: qbdt.hpp:557
void SetAmplitude(const bitCapInt &perm, const complex &amp)
Sets the representational amplitude of a full permutation.
Definition: qbdt.hpp:233
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: qbdt.hpp:272
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: tree.cpp:645
std::vector< int64_t > deviceIDs
Definition: qbdt.hpp:46
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: qbdt.hpp:448
void Dispose(bitLenInt start, bitLenInt length)
Minimally decompose a set of contiguous bits from the separably composed unit, and discard the separa...
Definition: qbdt.hpp:344
void SetPermutation(const bitCapInt &initState, const complex &phaseFac=CMPLX_DEFAULT_ARG)
Set to a specific permutation of all qubits.
Definition: tree.cpp:125
void FSim(real1_f theta, real1_f phi, bitLenInt qubitIndex1, bitLenInt qubitIndex2)
The 2-qubit "fSim" gate, (useful in the simulation of particles with fermionic statistics)
Definition: tree.cpp:669
void Swap(bitLenInt q1, bitLenInt q2)
Swap values of two bits in register.
Definition: qbdt.hpp:374
QBdt(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 useSparseStateVec=false, real1_f norm_thresh=REAL1_EPSILON, std::vector< int64_t > ignored={}, bitLenInt qubitThreshold=0, real1_f separation_thresh=_qrack_qunit_sep_thresh)
Definition: tree.cpp:24
QBdt(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 useSparseStateVec=false, real1_f norm_thresh=REAL1_EPSILON, std::vector< int64_t > devList={}, bitLenInt qubitThreshold=0U, real1_f separation_thresh=_qrack_qunit_sep_thresh)
Definition: qbdt.hpp:174
void SetDevice(int64_t dID)
Set the device index, if more than one device is available.
Definition: qbdt.hpp:188
void GetTraversal(Fn getLambda)
Definition: qbdt.hpp:51
void CSwap(const std::vector< bitLenInt > &controls, bitLenInt q1, bitLenInt q2)
Apply a swap with arbitrary control bits.
Definition: qbdt.hpp:409
void par_for_qbdt(const bitCapInt &end, bitLenInt maxQubit, BdtFunc fn, bool branch=true)
Definition: tree.cpp:64
real1_f SumSqrDiff(QInterfacePtr toCompare)
Calculates (1 - <\psi_e|\psi_c>) between states |\psi_c> and |\psi_e>.
Definition: qbdt.hpp:204
void SetTraversal(Fn setLambda)
Definition: qbdt.hpp:67
bitLenInt Compose(QInterfacePtr toCopy, bitLenInt start)
Compose() a QInterface peer, inserting its qubit into index order at start index.
Definition: qbdt.hpp:334
void GetQuantumState(QInterfacePtr eng)
Definition: qbdt.hpp:215
bitCapInt BitCapIntAsStateVector(Fn operation)
Definition: qbdt.hpp:103
bool M(bitLenInt q)
Definition: qbdt.hpp:476
void INCBCD(const bitCapInt &toAdd, bitLenInt start, bitLenInt length)
Add classical BCD integer (without sign)
Definition: qbdt.hpp:553
bitCapInt MAllOptionalCollapse(bool isCollapsing)
Definition: tree.cpp:403
void SetQuantumState(const complex *state)
Set an arbitrary pure quantum state representation.
Definition: qbdt.hpp:219
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: qbdt.hpp:514
bool ForceM(bitLenInt qubit, bool result, bool doForce=true, bool doApply=true)
Act as if is a measurement was applied, except force the (usually random) result.
Definition: qbdt.hpp:358
void Hash(bitLenInt start, bitLenInt length, const unsigned char *values)
Transform a length of qubit register via lookup through a hash table.
Definition: qbdt.hpp:622
void GetProbs(real1 *outputProbs)
Get the pure quantum state representation.
Definition: qbdt.hpp:227
void ApplySingle(const complex mtrx[4U], bitLenInt target)
Definition: tree.cpp:446
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: qbdt.hpp:193
QEnginePtr MakeQEngine(bitLenInt qbCount, const bitCapInt &perm=ZERO_BCI)
Definition: tree.cpp:58
void IISwap(bitLenInt q1, bitLenInt q2)
Inverse ISwap - Swap values of two bits in register, and apply phase factor of -i if bits are differe...
Definition: qbdt.hpp:388
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: tree.cpp:620
void DECC(const bitCapInt &toSub, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Subtract classical integer (without sign, with carry)
Definition: qbdt.hpp:485
void SqrtSwap(bitLenInt q1, bitLenInt q2)
Square root of Swap gate.
Definition: qbdt.hpp:395
void INC(const bitCapInt &toAdd, bitLenInt start, bitLenInt length)
Add integer (without sign)
Definition: qbdt.hpp:479
complex GetAmplitude(const bitCapInt &perm)
Get the representational amplitude of a full permutation.
Definition: tree.cpp:194
void _par_for(const bitCapInt &end, ParallelFuncBdt fn)
Definition: tree.cpp:88
static bitCapInt RemovePower(const bitCapInt &perm, bitCapInt power)
Definition: qbdt.hpp:130
std::vector< int64_t > GetDeviceList()
Get the device index.
Definition: qbdt.hpp:191
static size_t SelectBit(const bitCapInt &perm, bitLenInt bit)
Definition: qbdt.hpp:128
void INCS(const bitCapInt &toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex)
Add a classical integer to the register, with sign and without carry.
Definition: qbdt.hpp:489
void DECS(const bitCapInt &toSub, bitLenInt start, bitLenInt length, bitLenInt overflowIndex)
Add a classical integer to the register, with sign and without carry.
Definition: qbdt.hpp:493
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: qbdt.hpp:524
bool isBinaryDecisionTree()
Returns "true" if current state representation is definitely a binary decision tree,...
Definition: qbdt.hpp:186
void CSqrtSwap(const std::vector< bitLenInt > &controls, bitLenInt q1, bitLenInt q2)
Apply a square root of swap with arbitrary control bits.
Definition: qbdt.hpp:416
void Decompose(bitLenInt start, QInterfacePtr dest)
Minimally decompose a set of contiguous bits from the separably composed unit, into "destination".
Definition: qbdt.hpp:338
void ApplyControlledSingle(const complex mtrx[4U], std::vector< bitLenInt > controls, bitLenInt target, bool isAnti)
Definition: tree.cpp:504
std::vector< QInterfaceEngine > engines
Definition: qbdt.hpp:47
real1_f ProbParity(const bitCapInt &mask)
Overall probability of any odd permutation of the masked set of bits.
Definition: qbdt.hpp:431
void CDIV(const bitCapInt &toDiv, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length, const std::vector< bitLenInt > &controls)
Controlled division by power of integer.
Definition: qbdt.hpp:585
void INCDECSC(const bitCapInt &toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Common driver method behind INCSC and DECSC (without overflow flag)
Definition: qbdt.hpp:547
void ExecuteAsStateVector(Fn operation)
Definition: qbdt.hpp:95
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: qbdt.hpp:534
void X(bitLenInt q)
Definition: qbdt.hpp:478
void GetQuantumState(complex *state)
Get the pure quantum state representation.
Definition: qbdt.hpp:211
bitLenInt bdtStride
Definition: qbdt.hpp:42
QInterfacePtr Clone()
Clone this QInterface.
Definition: tree.cpp:150
void DEC(const bitCapInt &toSub, bitLenInt start, bitLenInt length)
Add integer (without sign)
Definition: qbdt.hpp:480
void CMUL(const bitCapInt &toMul, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length, const std::vector< bitLenInt > &controls)
Controlled multiplication by integer.
Definition: qbdt.hpp:579
QBdtNodeInterfacePtr root
Definition: qbdt.hpp:44
void MACMtrx(const std::vector< bitLenInt > &controls, const complex mtrx[4U], bitLenInt target)
Apply an arbitrary single bit unitary transformation, with arbitrary (anti-)control bits.
Definition: tree.cpp:606
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: qbdt.hpp:453
void CDEC(const bitCapInt &toSub, bitLenInt inOutStart, bitLenInt length, const std::vector< bitLenInt > &controls)
Subtract integer (without sign, with controls)
Definition: qbdt.hpp:501
void SetDeviceList(std::vector< int64_t > dIDs)
Set the device index list, if more than one device is available.
Definition: qbdt.hpp:189
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: qbdt.hpp:614
real1_f ProbAll(const bitCapInt &fullRegister)
Direct measure of full permutation probability.
Definition: tree.cpp:387
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: qbdt.hpp:519
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: qbdt.hpp:573
int64_t GetDevice()
Get the device index.
Definition: qbdt.hpp:190
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 bitLenInt Allocate(bitLenInt length)
Allocate new "length" count of |0> state qubits at end of qubit index position.
Definition: qinterface.hpp:488
virtual bitLenInt Compose(QInterfacePtr toCopy)
Combine another QInterface with this one, after the last bit index of this one.
Definition: qinterface.hpp:382
bitLenInt qubitCount
Definition: qinterface.hpp:146
Definition: qparity.hpp:22
Definition: qengine_gpu_util.hpp:21
Half-precision floating-point type.
Definition: half.hpp:2206
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 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:2225
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 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 INCS(const bitCapInt &toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex)
Add a classical integer to the register, with sign and without carry.
Definition: qinterface.hpp:2214
virtual void DECC(const bitCapInt &toSub, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Subtract classical integer (without sign, with carry)
Definition: qinterface.hpp:2188
virtual void DEC(const bitCapInt &toSub, bitLenInt start, bitLenInt length)
Subtract classical integer (without sign)
Definition: qinterface.hpp:2166
virtual void INC(const bitCapInt &toAdd, bitLenInt start, bitLenInt length)
Add integer (without sign)
Definition: arithmetic.cpp:20
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 CDEC(const bitCapInt &toSub, bitLenInt inOutStart, bitLenInt length, const std::vector< bitLenInt > &controls)
Subtract classical integer (without sign, with controls)
Definition: qinterface.hpp:2206
virtual void INCC(const bitCapInt &toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Add integer (without sign, with carry)
Definition: qinterface.hpp:2176
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 CSqrtSwap(const std::vector< bitLenInt > &controls, bitLenInt qubit1, bitLenInt qubit2)
Apply a square root of swap with arbitrary control bits.
Definition: gates.cpp:282
virtual void CISqrtSwap(const std::vector< bitLenInt > &controls, bitLenInt qubit1, bitLenInt qubit2)
Apply an inverse square root of swap with arbitrary control bits.
Definition: gates.cpp:331
virtual void X(bitLenInt qubit)
X gate.
Definition: qinterface.hpp:1116
virtual void U(bitLenInt target, real1_f theta, real1_f phi, real1_f lambda)
General unitary gate.
Definition: rotational.cpp:18
virtual bool M(bitLenInt qubit)
Measurement gate.
Definition: qinterface.hpp:1031
virtual void CSwap(const std::vector< bitLenInt > &controls, bitLenInt qubit1, bitLenInt qubit2)
Apply a swap with arbitrary control bits.
Definition: gates.cpp:247
virtual void ISqrtSwap(bitLenInt qubit1, bitLenInt qubit2)
Inverse square root of Swap gate.
Definition: gates.cpp:224
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:215
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: gates.cpp:189
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: gates.cpp:177
virtual void SqrtSwap(bitLenInt qubit1, bitLenInt qubit2)
Square root of Swap gate.
Definition: gates.cpp:201
virtual void Swap(bitLenInt qubit1, bitLenInt qubit2)
Swap values of two bits in register.
Definition: gates.cpp:166
virtual QInterfacePtr Copy()
Copy this QInterface.
Definition: qinterface.hpp:3058
virtual bool TryDecompose(bitLenInt start, QInterfacePtr dest, real1_f error_tol=TRYDECOMPOSE_EPSILON)
Attempt to Decompose() a bit range.
Definition: qinterface.cpp:836
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:2925
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:198
@ QINTERFACE_HYBRID
Create a QHybrid, switching between QEngineCPU and QEngineOCL as efficient.
Definition: qinterface.hpp:57
std::shared_ptr< QEngine > QEnginePtr
Definition: qrack_types.hpp:153
std::shared_ptr< QInterface > QInterfacePtr
Definition: qinterface.hpp:29
const real1_f _qrack_qunit_sep_thresh
Definition: qrack_functions.hpp:258
QRACK_CONST real1_f TRYDECOMPOSE_EPSILON
Definition: qrack_types.hpp:265
std::shared_ptr< QBdt > QBdtPtr
Definition: qbdt.hpp:31
std::function< bitCapInt(const bitCapInt &)> BdtFunc
Definition: qbdt_node_interface.hpp:37
std::complex< real1 > complex
Definition: qrack_types.hpp:140
const bitLenInt QRACK_MAX_CPU_QB_DEFAULT
Definition: qrack_functions.hpp:260
bitCapInt pow2(const bitLenInt &p)
Definition: qrack_functions.hpp:156
std::function< void(const bitCapInt &, const unsigned &cpu)> ParallelFuncBdt
Definition: qbdt.hpp:34
double norm(const complex2 &c)
Definition: complex16x2simd.hpp:122
QRACK_CONST real1 REAL1_EPSILON
Definition: qrack_types.hpp:203
float real1_f
Definition: qrack_types.hpp:107
QRACK_CONST complex CMPLX_DEFAULT_ARG
Definition: qrack_types.hpp:262
std::shared_ptr< QBdtNodeInterface > QBdtNodeInterfacePtr
Definition: qbdt_node_interface.hpp:34
const bitCapInt ZERO_BCI
Definition: qrack_types.hpp:142
bitLenInt log2(bitCapInt n)
Definition: qrack_functions.hpp:154
#define QINTERFACE_TO_QALU(qReg)
Definition: qbdt.hpp:26
#define QINTERFACE_TO_QPARITY(qReg)
Definition: qbdt.hpp:27
#define REAL1_DEFAULT_ARG
Definition: qrack_types.hpp:179
#define bitLenInt
Definition: qrack_types.hpp:41
#define ZERO_R1_F
Definition: qrack_types.hpp:162
#define qrack_rand_gen_ptr
Definition: qrack_types.hpp:158
#define bitCapInt
Definition: qrack_types.hpp:65
#define bitCapIntOcl
Definition: qrack_types.hpp:53