Qrack  9.13
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 
23 #include <algorithm>
24 
25 #define QINTERFACE_TO_QALU(qReg) std::dynamic_pointer_cast<QAlu>(qReg)
26 #define QINTERFACE_TO_QPARITY(qReg) std::dynamic_pointer_cast<QParity>(qReg)
27 
28 namespace Qrack {
29 
30 class QBdt;
31 typedef std::shared_ptr<QBdt> QBdtPtr;
32 
33 #if ENABLE_ALU
34 class QBdt : public QAlu, public QParity, public QInterface {
35 #else
36 class QBdt : public QParity, public QInterface {
37 #endif
38 protected:
40  int64_t devID;
43  std::vector<int64_t> deviceIDs;
44  std::vector<QInterfaceEngine> engines;
45  std::vector<MpsShardPtr> shards;
46 
47  void DumpBuffers()
48  {
49  for (size_t i = 0; i < shards.size(); ++i) {
50  shards[i] = NULL;
51  }
52  }
54  {
55  const MpsShardPtr shard = shards[t];
56  if (shard) {
57  shards[t] = NULL;
58  ApplySingle(shard->gate, t);
59  }
60  }
61  void FlushBuffers()
62  {
63  for (size_t i = 0U; i < shards.size(); ++i) {
64  FlushBuffer(i);
65  }
66  }
67  void FlushIfBlocked(bitLenInt target, const std::vector<bitLenInt>& controls = std::vector<bitLenInt>())
68  {
69  FlushIfBlocked(controls);
70  FlushBuffer(target);
71  }
72  void FlushIfBlocked(const std::vector<bitLenInt>& controls)
73  {
74  for (const bitLenInt& control : controls) {
75  const MpsShardPtr shard = shards[control];
76  if (shard && !shard->IsPhase()) {
77  shards[control] = NULL;
78  ApplySingle(shard->gate, control);
79  }
80  }
81  }
83  {
84  for (size_t i = 0U; i < shards.size(); ++i) {
85  const MpsShardPtr shard = shards[i];
86  if (shard && !shard->IsPhase()) {
87  shards[i] = NULL;
88  ApplySingle(shard->gate, i);
89  }
90  }
91  }
92 
93  QEnginePtr MakeQEngine(bitLenInt qbCount, const bitCapInt& perm = ZERO_BCI);
94 
95  template <typename Fn> void GetTraversal(Fn getLambda)
96  {
97  FlushBuffers();
98 
99  _par_for(maxQPower, [&](const bitCapInt& i, const unsigned& cpu) {
100  QBdtNodeInterfacePtr leaf = root;
101  complex scale = leaf->scale;
102  for (bitLenInt j = 0U; j < qubitCount; ++j) {
103  leaf = leaf->branches[SelectBit(i, j)];
104  if (!leaf) {
105  break;
106  }
107  scale *= leaf->scale;
108  }
109 
110  getLambda((bitCapIntOcl)i, scale);
111  });
112  }
113  template <typename Fn> void SetTraversal(Fn setLambda)
114  {
115  DumpBuffers();
116 
117  root = std::make_shared<QBdtNode>();
118 #if ENABLE_QBDT_CPU_PARALLEL && ENABLE_PTHREAD
119  if (true) {
120  std::lock_guard<std::mutex> lock(root->mtx);
121  root->Branch(qubitCount);
122  }
123 #else
124  root->Branch(qubitCount);
125 #endif
126 
127  _par_for(maxQPower, [&](const bitCapInt& i, const unsigned& cpu) {
128  QBdtNodeInterfacePtr leaf = root;
129  for (bitLenInt j = 0U; j < qubitCount; ++j) {
130  leaf = leaf->branches[SelectBit(i, j)];
131  }
132 
133  setLambda((bitCapIntOcl)i, leaf);
134  });
135 
136  root->PopStateVector(qubitCount);
137  root->Prune(qubitCount);
138  }
139  template <typename Fn> void ExecuteAsStateVector(Fn operation)
140  {
142  GetQuantumState(qReg);
143  operation(qReg);
144  SetQuantumState(qReg);
145  }
146 
147  template <typename Fn> bitCapInt BitCapIntAsStateVector(Fn operation)
148  {
150  GetQuantumState(qReg);
151  const bitCapInt toRet = operation(qReg);
152  SetQuantumState(qReg);
153 
154  return toRet;
155  }
156 
157  void par_for_qbdt(const bitCapInt& end, bitLenInt maxQubit, BdtFunc fn, bool branch = true);
158  void _par_for(const bitCapInt& end, ParallelFuncBdt fn);
159 
160  void DecomposeDispose(bitLenInt start, bitLenInt length, QBdtPtr dest);
161 
162  void ApplyControlledSingle(const complex* mtrx, std::vector<bitLenInt> controls, bitLenInt target, bool isAnti);
163 
164  static size_t SelectBit(const bitCapInt& perm, bitLenInt bit) { return (size_t)bi_and_1(perm >> bit); }
165 
166  static bitCapInt RemovePower(const bitCapInt& perm, bitCapInt power)
167  {
168  bi_decrement(&power, 1U);
169  return (perm & power) | ((perm >> 1U) & ~power);
170  }
171 
172  void ApplySingle(const complex* mtrx, bitLenInt target);
173 
174  void Init();
175 
176  bitCapInt MAllOptionalCollapse(bool isCollapsing);
177 
178  bitCapInt SampleClone(const std::vector<bitCapInt>& qPowers)
179  {
180  const bitCapInt rawSample = MAllOptionalCollapse(false);
181  bitCapInt sample = ZERO_BCI;
182  for (size_t i = 0U; i < qPowers.size(); ++i) {
183  if (bi_compare_0(rawSample & qPowers[i]) != 0) {
184  bi_or_ip(&sample, pow2(i));
185  }
186  }
187 
188  return sample;
189  }
190 
191  using QInterface::Copy;
192  void Copy(QInterfacePtr orig) { Copy(std::dynamic_pointer_cast<QBdt>(orig)); }
193  void Copy(QBdtPtr orig)
194  {
195  QInterface::Copy(orig);
196  bdtStride = orig->bdtStride;
197  devID = orig->devID;
198  root = orig->root;
199  bdtMaxQPower = orig->bdtMaxQPower;
200  deviceIDs = orig->deviceIDs;
201  engines = orig->engines;
202  shards = orig->shards;
203  }
204 
205 public:
206  QBdt(std::vector<QInterfaceEngine> eng, bitLenInt qBitCount, const bitCapInt& initState = ZERO_BCI,
207  qrack_rand_gen_ptr rgp = nullptr, const complex& phaseFac = CMPLX_DEFAULT_ARG, bool doNorm = false,
208  bool randomGlobalPhase = true, bool useHostMem = false, int64_t deviceId = -1, bool useHardwareRNG = true,
209  bool useSparseStateVec = false, real1_f norm_thresh = REAL1_EPSILON, std::vector<int64_t> ignored = {},
210  bitLenInt qubitThreshold = 0, real1_f separation_thresh = _qrack_qunit_sep_thresh);
211 
212  QBdt(bitLenInt qBitCount, const bitCapInt& initState = ZERO_BCI, qrack_rand_gen_ptr rgp = nullptr,
213  const complex& phaseFac = CMPLX_DEFAULT_ARG, bool doNorm = false, bool randomGlobalPhase = true,
214  bool useHostMem = false, int64_t deviceId = -1, bool useHardwareRNG = true, bool useSparseStateVec = false,
215  real1_f norm_thresh = REAL1_EPSILON, std::vector<int64_t> devList = {}, bitLenInt qubitThreshold = 0U,
216  real1_f separation_thresh = _qrack_qunit_sep_thresh)
217  : QBdt({ QINTERFACE_HYBRID }, qBitCount, initState, rgp, phaseFac, doNorm, randomGlobalPhase, useHostMem,
218  deviceId, useHardwareRNG, useSparseStateVec, norm_thresh, devList, qubitThreshold, separation_thresh)
219  {
220  }
221 
222  size_t CountBranches();
223 
224  bool isBinaryDecisionTree() { return true; };
225 
226  void SetDevice(int64_t dID) { devID = dID; }
227 
229  {
230  // Intentionally left blank.
231  }
232 
234  real1_f nrm = REAL1_DEFAULT_ARG, real1_f norm_thresh = REAL1_DEFAULT_ARG, real1_f phaseArg = ZERO_R1_F)
235  {
236  root->Normalize(qubitCount);
237  }
238 
239  real1_f SumSqrDiff(QInterfacePtr toCompare) { return SumSqrDiff(std::dynamic_pointer_cast<QBdt>(toCompare)); }
240  real1_f SumSqrDiff(QBdtPtr toCompare);
241 
242  void SetPermutation(const bitCapInt& initState, const complex& phaseFac = CMPLX_DEFAULT_ARG);
243 
245 
247  {
248  GetTraversal([state](bitCapIntOcl i, const complex& scale) { state[i] = scale; });
249  }
251  {
252  GetTraversal([eng](bitCapIntOcl i, const complex& scale) { eng->SetAmplitude(i, scale); });
253  }
254  void SetQuantumState(const complex* state)
255  {
256  SetTraversal([state](bitCapIntOcl i, QBdtNodeInterfacePtr leaf) { leaf->scale = state[i]; });
257  }
259  {
260  SetTraversal([eng](bitCapIntOcl i, QBdtNodeInterfacePtr leaf) { leaf->scale = eng->GetAmplitude(i); });
261  }
262  void GetProbs(real1* outputProbs)
263  {
264  GetTraversal([outputProbs](bitCapIntOcl i, const complex& scale) { outputProbs[i] = norm(scale); });
265  }
266 
267  complex GetAmplitude(const bitCapInt& perm);
268  void SetAmplitude(const bitCapInt& perm, const complex& amp)
269  {
270  ExecuteAsStateVector([&](QInterfacePtr eng) { eng->SetAmplitude(perm, amp); });
271  }
272 
277  bool IsSeparable(bitLenInt start);
278 
280  {
281  if (error_tol > TRYDECOMPOSE_EPSILON) {
282  return QInterface::TryDecompose(start, dest, error_tol);
283  }
284 
285  const bitLenInt length = dest->GetQubitCount();
286  const bitLenInt nStart = qubitCount - length;
287  const bitLenInt shift = nStart - start;
288  for (bitLenInt i = 0U; i < shift; ++i) {
289  Swap(start + i, qubitCount - (i + 1U));
290  }
291 
292  const bool isSeparable = IsSeparable(nStart);
293 
294  for (bitLenInt i = shift; i > 0U; --i) {
295  Swap(start + (i - 1U), qubitCount - i);
296  }
297 
298  if (isSeparable) {
299  Decompose(start, dest);
300  return true;
301  }
302 
303  return false;
304  }
305 
307  bool TrySeparate(const std::vector<bitLenInt>& _qubits, real1_f error_tol)
308  {
310  "QBdt::TrySeparate parameter qubit array values must be within allocated qubit bounds!");
311 
312  if (!_qubits.size() || (_qubits.size() == qubitCount)) {
313  return true;
314  }
315 
316  std::vector<bitLenInt> qubits(_qubits);
317  std::sort(qubits.begin(), qubits.end());
318  for (size_t i = 0U; i < qubits.size(); ++i) {
319  Swap(i, qubits[i]);
320  }
321  const bool result = IsSeparable(qubits.size());
322  for (bitLenInt i = qubits.size(); i > 0U; --i) {
323  Swap(i - 1U, qubits[i - 1U]);
324  }
325 
326  return result;
327  }
328  bool TrySeparate(bitLenInt qubit)
329  {
330  if (qubit >= qubitCount) {
331  throw std::invalid_argument("QBdt::TrySeparate argument out-of-bounds!");
332  }
333  if (qubitCount == 1U) {
334  return true;
335  }
336 
337  Swap(qubit, 0U);
338  const bool result = IsSeparable(1U);
339  Swap(qubit, 0U);
340 
341  return result;
342  }
343  bool TrySeparate(bitLenInt qubit1, bitLenInt qubit2)
344  {
345  if (qubit1 == qubit2) {
346  throw std::invalid_argument("QBdt::TrySeparate qubits must be distinct!");
347  }
348  if ((qubit1 >= qubitCount) || (qubit2 >= qubitCount)) {
349  throw std::invalid_argument("QBdt::TrySeparate argument out-of-bounds!");
350  }
351  if (qubitCount == 2U) {
352  return true;
353  }
354  if (qubit1 > qubit2) {
355  std::swap(qubit1, qubit2);
356  }
357 
358  Swap(qubit1, 0U);
359  Swap(qubit2, 1U);
360  const bool result = IsSeparable(2U);
361  Swap(qubit2, 1U);
362  Swap(qubit1, 0U);
363 
364  return result;
365  }
366 
367  using QInterface::Compose;
368  bitLenInt Compose(QBdtPtr toCopy, bitLenInt start);
370  {
371  return Compose(std::dynamic_pointer_cast<QBdt>(toCopy), start);
372  }
374  {
375  QBdtPtr d = std::dynamic_pointer_cast<QBdt>(dest);
376  DecomposeDispose(start, dest->GetQubitCount(), d);
377  }
379  void Dispose(bitLenInt start, bitLenInt length) { DecomposeDispose(start, length, NULL); }
380 
381  void Dispose(bitLenInt start, bitLenInt length, const bitCapInt& disposedPerm)
382  {
383  ForceMReg(start, length, disposedPerm);
384  DecomposeDispose(start, length, NULL);
385  }
386 
387  using QInterface::Allocate;
388  bitLenInt Allocate(bitLenInt start, bitLenInt length);
389 
390  real1_f Prob(bitLenInt qubitIndex);
391  real1_f ProbAll(const bitCapInt& fullRegister);
392 
393  bool ForceM(bitLenInt qubit, bool result, bool doForce = true, bool doApply = true);
394  bitCapInt MAll() { return MAllOptionalCollapse(true); }
395 
396  void Mtrx(const complex* mtrx, bitLenInt target);
397  void MCMtrx(const std::vector<bitLenInt>& controls, const complex* mtrx, bitLenInt target);
398  void MACMtrx(const std::vector<bitLenInt>& controls, const complex* mtrx, bitLenInt target);
399  void MCPhase(
400  const std::vector<bitLenInt>& controls, const complex& topLeft, const complex& bottomRight, bitLenInt target);
401  void MCInvert(
402  const std::vector<bitLenInt>& controls, const complex& topRight, const complex& bottomLeft, bitLenInt target);
403 
404  void FSim(real1_f theta, real1_f phi, bitLenInt qubitIndex1, bitLenInt qubitIndex2);
405 
406  void Swap(bitLenInt q1, bitLenInt q2)
407  {
408  if (q2 < q1) {
409  std::swap(q1, q2);
410  }
411  QInterface::Swap(q1, q2);
412  }
413  void ISwap(bitLenInt q1, bitLenInt q2)
414  {
415  if (q2 < q1) {
416  std::swap(q1, q2);
417  }
418  QInterface::ISwap(q1, q2);
419  }
421  {
422  if (q2 < q1) {
423  std::swap(q1, q2);
424  }
425  QInterface::IISwap(q1, q2);
426  }
428  {
429  if (q2 < q1) {
430  std::swap(q1, q2);
431  }
432  QInterface::SqrtSwap(q1, q2);
433  }
435  {
436  if (q2 < q1) {
437  std::swap(q1, q2);
438  }
439  QInterface::ISqrtSwap(q1, q2);
440  }
441  void CSwap(const std::vector<bitLenInt>& controls, bitLenInt q1, bitLenInt q2)
442  {
443  if (q2 < q1) {
444  std::swap(q1, q2);
445  }
446  QInterface::CSwap(controls, q1, q2);
447  }
448  void CSqrtSwap(const std::vector<bitLenInt>& controls, bitLenInt q1, bitLenInt q2)
449  {
450  if (q2 < q1) {
451  std::swap(q1, q2);
452  }
453  QInterface::CSqrtSwap(controls, q1, q2);
454  }
455  void CISqrtSwap(const std::vector<bitLenInt>& controls, bitLenInt q1, bitLenInt q2)
456  {
457  if (q2 < q1) {
458  std::swap(q1, q2);
459  }
460  QInterface::CISqrtSwap(controls, q1, q2);
461  }
462 
464  {
465  if (bi_compare_0(mask) == 0) {
466  return ZERO_R1_F;
467  }
468 
469  bitCapInt maskMin1 = mask;
470  bi_decrement(&maskMin1, 1U);
471  if (bi_compare_0(mask & maskMin1) == 0) {
472  return Prob(log2(mask));
473  }
474 
475  real1_f toRet;
476  ExecuteAsStateVector([&](QInterfacePtr eng) { toRet = QINTERFACE_TO_QPARITY(eng)->ProbParity(mask); });
477 
478  return toRet;
479  }
480  void CUniformParityRZ(const std::vector<bitLenInt>& controls, const bitCapInt& mask, real1_f angle)
481  {
483  [&](QInterfacePtr eng) { QINTERFACE_TO_QPARITY(eng)->CUniformParityRZ(controls, mask, angle); });
484  }
485  bool ForceMParity(const bitCapInt& mask, bool result, bool doForce = true)
486  {
487  // If no bits in mask:
488  if (bi_compare_0(mask) == 0) {
489  return false;
490  }
491 
492  // If only one bit in mask:
493  bitCapInt maskMin1 = mask;
494  bi_decrement(&maskMin1, 1U);
495  if (bi_compare_0(mask & maskMin1) == 0) {
496  return ForceM(log2(mask), result, doForce);
497  }
498 
499  bool toRet;
501  [&](QInterfacePtr eng) { toRet = QINTERFACE_TO_QPARITY(eng)->ForceMParity(mask, result, doForce); });
502 
503  return toRet;
504  }
505 
506 #if ENABLE_ALU
507  using QInterface::M;
508  bool M(bitLenInt q) { return QInterface::M(q); }
509  using QInterface::X;
510  void X(bitLenInt q) { QInterface::X(q); }
511  void INC(const bitCapInt& toAdd, bitLenInt start, bitLenInt length) { QInterface::INC(toAdd, start, length); }
512  void DEC(const bitCapInt& toSub, bitLenInt start, bitLenInt length) { QInterface::DEC(toSub, start, length); }
513  void INCC(const bitCapInt& toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
514  {
515  QInterface::INCC(toAdd, start, length, carryIndex);
516  }
517  void DECC(const bitCapInt& toSub, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
518  {
519  QInterface::DECC(toSub, start, length, carryIndex);
520  }
521  void INCS(const bitCapInt& toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex)
522  {
523  QInterface::INCS(toAdd, start, length, overflowIndex);
524  }
525  void DECS(const bitCapInt& toSub, bitLenInt start, bitLenInt length, bitLenInt overflowIndex)
526  {
527  QInterface::DECS(toSub, start, length, overflowIndex);
528  }
529  void CINC(const bitCapInt& toAdd, bitLenInt inOutStart, bitLenInt length, const std::vector<bitLenInt>& controls)
530  {
531  QInterface::CINC(toAdd, inOutStart, length, controls);
532  }
533  void CDEC(const bitCapInt& toSub, bitLenInt inOutStart, bitLenInt length, const std::vector<bitLenInt>& controls)
534  {
535  QInterface::CDEC(toSub, inOutStart, length, controls);
536  }
537  void INCDECC(const bitCapInt& toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
538  {
539  QInterface::INCDECC(toAdd, start, length, carryIndex);
540  }
542  const bitCapInt& toMul, const bitCapInt& modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length)
543  {
544  QInterface::MULModNOut(toMul, modN, inStart, outStart, length);
545  }
547  const bitCapInt& toMul, const bitCapInt& modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length)
548  {
549  QInterface::IMULModNOut(toMul, modN, inStart, outStart, length);
550  }
551  void CMULModNOut(const bitCapInt& toMul, const bitCapInt& modN, bitLenInt inStart, bitLenInt outStart,
552  bitLenInt length, const std::vector<bitLenInt>& controls)
553  {
554  QInterface::CMULModNOut(toMul, modN, inStart, outStart, length, controls);
555  }
556  void CIMULModNOut(const bitCapInt& toMul, const bitCapInt& modN, bitLenInt inStart, bitLenInt outStart,
557  bitLenInt length, const std::vector<bitLenInt>& controls)
558  {
559  QInterface::CIMULModNOut(toMul, modN, inStart, outStart, length, controls);
560  }
561  void PhaseFlipIfLess(const bitCapInt& greaterPerm, bitLenInt start, bitLenInt length)
562  {
564  [&](QInterfacePtr eng) { QINTERFACE_TO_QALU(eng)->PhaseFlipIfLess(greaterPerm, start, length); });
565  }
566  void CPhaseFlipIfLess(const bitCapInt& greaterPerm, bitLenInt start, bitLenInt length, bitLenInt flagIndex)
567  {
569  QINTERFACE_TO_QALU(eng)->CPhaseFlipIfLess(greaterPerm, start, length, flagIndex);
570  });
571  }
572  void INCDECSC(
573  const bitCapInt& toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex, bitLenInt carryIndex)
574  {
576  QINTERFACE_TO_QALU(eng)->INCDECSC(toAdd, start, length, overflowIndex, carryIndex);
577  });
578  }
579  void INCDECSC(const bitCapInt& toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
580  {
582  [&](QInterfacePtr eng) { QINTERFACE_TO_QALU(eng)->INCDECSC(toAdd, start, length, carryIndex); });
583  }
584 #if ENABLE_BCD
585  void INCBCD(const bitCapInt& toAdd, bitLenInt start, bitLenInt length)
586  {
587  ExecuteAsStateVector([&](QInterfacePtr eng) { QINTERFACE_TO_QALU(eng)->INCBCD(toAdd, start, length); });
588  }
589  void INCDECBCDC(const bitCapInt& toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
590  {
592  [&](QInterfacePtr eng) { QINTERFACE_TO_QALU(eng)->INCDECBCDC(toAdd, start, length, carryIndex); });
593  }
594 #endif
595  void MUL(const bitCapInt& toMul, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length)
596  {
598  [&](QInterfacePtr eng) { QINTERFACE_TO_QALU(eng)->MUL(toMul, inOutStart, carryStart, length); });
599  }
600  void DIV(const bitCapInt& toDiv, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length)
601  {
603  [&](QInterfacePtr eng) { QINTERFACE_TO_QALU(eng)->DIV(toDiv, inOutStart, carryStart, length); });
604  }
606  const bitCapInt& base, const bitCapInt& modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length)
607  {
609  [&](QInterfacePtr eng) { QINTERFACE_TO_QALU(eng)->POWModNOut(base, modN, inStart, outStart, length); });
610  }
611  void CMUL(const bitCapInt& toMul, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length,
612  const std::vector<bitLenInt>& controls)
613  {
615  [&](QInterfacePtr eng) { QINTERFACE_TO_QALU(eng)->CMUL(toMul, inOutStart, carryStart, length, controls); });
616  }
617  void CDIV(const bitCapInt& toDiv, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length,
618  const std::vector<bitLenInt>& controls)
619  {
621  [&](QInterfacePtr eng) { QINTERFACE_TO_QALU(eng)->CDIV(toDiv, inOutStart, carryStart, length, controls); });
622  }
623  void CPOWModNOut(const bitCapInt& base, const bitCapInt& modN, bitLenInt inStart, bitLenInt outStart,
624  bitLenInt length, const std::vector<bitLenInt>& controls)
625  {
627  QINTERFACE_TO_QALU(eng)->CPOWModNOut(base, modN, inStart, outStart, length, controls);
628  });
629  }
630  bitCapInt IndexedLDA(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart, bitLenInt valueLength,
631  const unsigned char* values, bool resetValue = true)
632  {
633  return BitCapIntAsStateVector([&](QInterfacePtr eng) {
634  return QINTERFACE_TO_QALU(eng)->IndexedLDA(
635  indexStart, indexLength, valueStart, valueLength, values, resetValue);
636  });
637  }
638  bitCapInt IndexedADC(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart, bitLenInt valueLength,
639  bitLenInt carryIndex, const unsigned char* values)
640  {
641  return BitCapIntAsStateVector([&](QInterfacePtr eng) {
642  return QINTERFACE_TO_QALU(eng)->IndexedADC(
643  indexStart, indexLength, valueStart, valueLength, carryIndex, values);
644  });
645  }
646  bitCapInt IndexedSBC(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart, bitLenInt valueLength,
647  bitLenInt carryIndex, const unsigned char* values)
648  {
649  return BitCapIntAsStateVector([&](QInterfacePtr eng) {
650  return QINTERFACE_TO_QALU(eng)->IndexedSBC(
651  indexStart, indexLength, valueStart, valueLength, carryIndex, values);
652  });
653  }
654  void Hash(bitLenInt start, bitLenInt length, const unsigned char* values)
655  {
656  ExecuteAsStateVector([&](QInterfacePtr eng) { QINTERFACE_TO_QALU(eng)->Hash(start, length, values); });
657  }
658 #endif
659 };
660 } // namespace Qrack
void bi_or_ip(BigInteger *left, const BigInteger &right)
Definition: big_integer.hpp:429
void bi_decrement(BigInteger *pBigInt, const BIG_INTEGER_WORD &value)
Definition: big_integer.hpp:229
int bi_and_1(const BigInteger &left)
Definition: big_integer.hpp:400
int bi_compare_0(const BigInteger &left)
Definition: big_integer.hpp:134
Definition: qalu.hpp:22
Definition: qbdt.hpp:34
void MCMtrx(const std::vector< bitLenInt > &controls, const complex *mtrx, bitLenInt target)
Apply an arbitrary single bit unitary transformation, with arbitrary control bits.
Definition: tree.cpp:703
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:623
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:638
void CINC(const bitCapInt &toAdd, bitLenInt inOutStart, bitLenInt length, const std::vector< bitLenInt > &controls)
Add integer (without sign, with controls)
Definition: qbdt.hpp:529
bool TrySeparate(bitLenInt qubit)
Single-qubit TrySeparate()
Definition: qbdt.hpp:328
void SetQuantumState(QInterfacePtr eng)
Definition: qbdt.hpp:258
bitCapInt SampleClone(const std::vector< bitCapInt > &qPowers)
Definition: qbdt.hpp:178
void DIV(const bitCapInt &toDiv, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length)
Divide by integer.
Definition: qbdt.hpp:600
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:233
void Copy(QBdtPtr orig)
Definition: qbdt.hpp:193
void INCC(const bitCapInt &toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Add integer (without sign, with carry)
Definition: qbdt.hpp:513
void ISqrtSwap(bitLenInt q1, bitLenInt q2)
Inverse square root of Swap gate.
Definition: qbdt.hpp:434
bool TrySeparate(bitLenInt qubit1, bitLenInt qubit2)
Two-qubit TrySeparate()
Definition: qbdt.hpp:343
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:572
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:413
virtual bitLenInt Allocate(bitLenInt length)
Allocate new "length" count of |0> state qubits at end of qubit index position.
Definition: qinterface.hpp:470
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:541
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:561
void ApplyControlledSingle(const complex *mtrx, std::vector< bitLenInt > controls, bitLenInt target, bool isAnti)
Definition: tree.cpp:607
void Copy(QInterfacePtr orig)
Definition: qbdt.hpp:192
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:381
void MUL(const bitCapInt &toMul, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length)
Multiply by integer.
Definition: qbdt.hpp:595
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:630
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:537
virtual bitLenInt Compose(QInterfacePtr toCopy)
Combine another QInterface with this one, after the last bit index of this one.
Definition: qinterface.hpp:364
bitCapInt bdtMaxQPower
Definition: qbdt.hpp:42
bool IsSeparable(bitLenInt start)
Inexpensive check for whether the QBdt is separable between low and high qubit indices at the biparti...
Definition: tree.cpp:293
real1_f Prob(bitLenInt qubitIndex)
Direct measure of bit probability to be in |1> state.
Definition: tree.cpp:364
size_t CountBranches()
Definition: tree.cpp:90
bool TryDecompose(bitLenInt start, QInterfacePtr dest, real1_f error_tol=TRYDECOMPOSE_EPSILON)
Attempt to Decompose() a bit range.
Definition: qbdt.hpp:279
void Init()
Definition: tree.cpp:40
int64_t devID
Definition: qbdt.hpp:40
bitCapInt MAll()
Measure permutation state of all coherent bits.
Definition: qbdt.hpp:394
void DecomposeDispose(bitLenInt start, bitLenInt length, QBdtPtr dest)
Definition: tree.cpp:262
void DumpBuffers()
Definition: qbdt.hpp:47
std::vector< MpsShardPtr > shards
Definition: qbdt.hpp:45
void Mtrx(const complex *mtrx, bitLenInt target)
Apply an arbitrary single bit unitary transformation.
Definition: tree.cpp:693
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:455
void INCDECBCDC(const bitCapInt &toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Common driver method behind INCSC and DECSC (without overflow flag)
Definition: qbdt.hpp:589
void SetAmplitude(const bitCapInt &perm, const complex &amp)
Sets the representational amplitude of a full permutation.
Definition: qbdt.hpp:268
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:307
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:763
std::vector< int64_t > deviceIDs
Definition: qbdt.hpp:43
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:480
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:379
void SetPermutation(const bitCapInt &initState, const complex &phaseFac=CMPLX_DEFAULT_ARG)
Set to a specific permutation of all qubits.
Definition: tree.cpp:117
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:794
void Swap(bitLenInt q1, bitLenInt q2)
Swap values of two bits in register.
Definition: qbdt.hpp:406
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:212
void SetDevice(int64_t dID)
Set the device index, if more than one device is available.
Definition: qbdt.hpp:226
void GetTraversal(Fn getLambda)
Definition: qbdt.hpp:95
void CSwap(const std::vector< bitLenInt > &controls, bitLenInt q1, bitLenInt q2)
Apply a swap with arbitrary control bits.
Definition: qbdt.hpp:441
void par_for_qbdt(const bitCapInt &end, bitLenInt maxQubit, BdtFunc fn, bool branch=true)
Definition: tree.cpp:65
void FlushBuffer(bitLenInt t)
Definition: qbdt.hpp:53
real1_f SumSqrDiff(QInterfacePtr toCompare)
Calculates (1 - <\psi_e|\psi_c>) between states |\psi_c> and |\psi_e>.
Definition: qbdt.hpp:239
void ApplySingle(const complex *mtrx, bitLenInt target)
Definition: tree.cpp:552
void SetTraversal(Fn setLambda)
Definition: qbdt.hpp:113
bitLenInt Compose(QInterfacePtr toCopy, bitLenInt start)
Compose() a QInterface peer, inserting its qubit into index order at start index.
Definition: qbdt.hpp:369
void FlushNonPhaseBuffers()
Definition: qbdt.hpp:82
void GetQuantumState(QInterfacePtr eng)
Definition: qbdt.hpp:250
bitCapInt BitCapIntAsStateVector(Fn operation)
Definition: qbdt.hpp:147
bool M(bitLenInt q)
Definition: qbdt.hpp:508
void INCBCD(const bitCapInt &toAdd, bitLenInt start, bitLenInt length)
Add classical BCD integer (without sign)
Definition: qbdt.hpp:585
bitCapInt MAllOptionalCollapse(bool isCollapsing)
Definition: tree.cpp:501
void SetQuantumState(const complex *state)
Set an arbitrary pure quantum state representation.
Definition: qbdt.hpp:254
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:546
void FlushBuffers()
Definition: qbdt.hpp:61
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: tree.cpp:425
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:654
void GetProbs(real1 *outputProbs)
Get the pure quantum state representation.
Definition: qbdt.hpp:262
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:228
QEnginePtr MakeQEngine(bitLenInt qbCount, const bitCapInt &perm=ZERO_BCI)
Definition: tree.cpp:59
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:420
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:734
void DECC(const bitCapInt &toSub, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Subtract classical integer (without sign, with carry)
Definition: qbdt.hpp:517
void SqrtSwap(bitLenInt q1, bitLenInt q2)
Square root of Swap gate.
Definition: qbdt.hpp:427
void INC(const bitCapInt &toAdd, bitLenInt start, bitLenInt length)
Add integer (without sign)
Definition: qbdt.hpp:511
complex GetAmplitude(const bitCapInt &perm)
Get the representational amplitude of a full permutation.
Definition: tree.cpp:197
void _par_for(const bitCapInt &end, ParallelFuncBdt fn)
Definition: tree.cpp:83
static bitCapInt RemovePower(const bitCapInt &perm, bitCapInt power)
Definition: qbdt.hpp:166
void FlushIfBlocked(const std::vector< bitLenInt > &controls)
Definition: qbdt.hpp:72
static size_t SelectBit(const bitCapInt &perm, bitLenInt bit)
Definition: qbdt.hpp:164
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:521
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:525
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:556
bool isBinaryDecisionTree()
Returns "true" if current state representation is definitely a binary decision tree,...
Definition: qbdt.hpp:224
void CSqrtSwap(const std::vector< bitLenInt > &controls, bitLenInt q1, bitLenInt q2)
Apply a square root of swap with arbitrary control bits.
Definition: qbdt.hpp:448
void Decompose(bitLenInt start, QInterfacePtr dest)
Minimally decompose a set of contiguous bits from the separably composed unit, into "destination".
Definition: qbdt.hpp:373
std::vector< QInterfaceEngine > engines
Definition: qbdt.hpp:44
real1_f ProbParity(const bitCapInt &mask)
Overall probability of any odd permutation of the masked set of bits.
Definition: qbdt.hpp:463
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:617
void INCDECSC(const bitCapInt &toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Common driver method behind INCSC and DECSC (without overflow flag)
Definition: qbdt.hpp:579
void ExecuteAsStateVector(Fn operation)
Definition: qbdt.hpp:139
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:566
void X(bitLenInt q)
Definition: qbdt.hpp:510
void GetQuantumState(complex *state)
Get the pure quantum state representation.
Definition: qbdt.hpp:246
bitLenInt bdtStride
Definition: qbdt.hpp:39
QInterfacePtr Clone()
Clone this QInterface.
Definition: tree.cpp:144
void DEC(const bitCapInt &toSub, bitLenInt start, bitLenInt length)
Add integer (without sign)
Definition: qbdt.hpp:512
void CMUL(const bitCapInt &toMul, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length, const std::vector< bitLenInt > &controls)
Controlled multiplication by integer.
Definition: qbdt.hpp:611
QBdtNodeInterfacePtr root
Definition: qbdt.hpp:41
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:485
void CDEC(const bitCapInt &toSub, bitLenInt inOutStart, bitLenInt length, const std::vector< bitLenInt > &controls)
Subtract integer (without sign, with controls)
Definition: qbdt.hpp:533
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: tree.cpp:718
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:646
real1_f ProbAll(const bitCapInt &fullRegister)
Direct measure of full permutation probability.
Definition: tree.cpp:407
void FlushIfBlocked(bitLenInt target, const std::vector< bitLenInt > &controls=std::vector< bitLenInt >())
Definition: qbdt.hpp:67
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:551
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:605
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:470
virtual bitLenInt Compose(QInterfacePtr toCopy)
Combine another QInterface with this one, after the last bit index of this one.
Definition: qinterface.hpp:364
bitLenInt qubitCount
Definition: qinterface.hpp:146
Definition: qparity.hpp:22
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:126
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:2193
virtual void INCDECC(const bitCapInt &toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Common driver method behind INCC and DECC.
Definition: arithmetic.cpp:52
virtual void CINC(const bitCapInt &toAdd, bitLenInt inOutStart, bitLenInt length, const std::vector< bitLenInt > &controls)
Add integer (without sign, with controls)
Definition: arithmetic.cpp:78
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:2182
virtual void DECC(const bitCapInt &toSub, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Subtract classical integer (without sign, with carry)
Definition: qinterface.hpp:2156
virtual void DEC(const bitCapInt &toSub, bitLenInt start, bitLenInt length)
Subtract classical integer (without sign)
Definition: qinterface.hpp:2134
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:164
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:2174
virtual void INCC(const bitCapInt &toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Add integer (without sign, with carry)
Definition: qinterface.hpp:2144
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:200
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:239
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:284
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:334
virtual void X(bitLenInt qubit)
X gate.
Definition: qinterface.hpp:1084
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:1013
virtual void CSwap(const std::vector< bitLenInt > &controls, bitLenInt qubit1, bitLenInt qubit2)
Apply a swap with arbitrary control bits.
Definition: gates.cpp:248
virtual void ISqrtSwap(bitLenInt qubit1, bitLenInt qubit2)
Inverse square root of Swap gate.
Definition: gates.cpp:225
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:190
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:178
virtual void SqrtSwap(bitLenInt qubit1, bitLenInt qubit2)
Square root of Swap gate.
Definition: gates.cpp:202
virtual void Swap(bitLenInt qubit1, bitLenInt qubit2)
Swap values of two bits in register.
Definition: gates.cpp:167
virtual QInterfacePtr Copy()
Copy this QInterface.
Definition: qinterface.hpp:2965
virtual bool TryDecompose(bitLenInt start, QInterfacePtr dest, real1_f error_tol=TRYDECOMPOSE_EPSILON)
Attempt to Decompose() a bit range.
Definition: qinterface.cpp:832
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:2881
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:178
@ 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:151
std::shared_ptr< QInterface > QInterfacePtr
Definition: qinterface.hpp:29
const real1_f _qrack_qunit_sep_thresh
Definition: qrack_functions.hpp:235
QRACK_CONST real1_f TRYDECOMPOSE_EPSILON
Definition: qrack_types.hpp:260
std::shared_ptr< QBdt > QBdtPtr
Definition: qbdt.hpp:30
std::function< bitCapInt(const bitCapInt &)> BdtFunc
Definition: qrack_types.hpp:138
std::complex< real1 > complex
Definition: qrack_types.hpp:128
bitCapInt pow2(const bitLenInt &p)
Definition: qrack_functions.hpp:136
std::function< void(const bitCapInt &, const unsigned &cpu)> ParallelFuncBdt
Definition: qrack_types.hpp:139
double norm(const complex2 &c)
Definition: complex16x2simd.hpp:101
QRACK_CONST real1 REAL1_EPSILON
Definition: qrack_types.hpp:200
float real1_f
Definition: qrack_types.hpp:95
QRACK_CONST complex CMPLX_DEFAULT_ARG
Definition: qrack_types.hpp:257
std::shared_ptr< MpsShard > MpsShardPtr
Definition: mpsshard.hpp:18
std::shared_ptr< QBdtNodeInterface > QBdtNodeInterfacePtr
Definition: qbdt_node_interface.hpp:33
const bitCapInt ZERO_BCI
Definition: qrack_types.hpp:130
bitLenInt log2(bitCapInt n)
Definition: qrack_functions.hpp:134
#define QINTERFACE_TO_QALU(qReg)
Definition: qbdt.hpp:25
#define QINTERFACE_TO_QPARITY(qReg)
Definition: qbdt.hpp:26
#define REAL1_DEFAULT_ARG
Definition: qrack_types.hpp:177
#define bitLenInt
Definition: qrack_types.hpp:38
#define ZERO_R1_F
Definition: qrack_types.hpp:160
#define qrack_rand_gen_ptr
Definition: qrack_types.hpp:156
#define bitCapInt
Definition: qrack_types.hpp:62
#define bitCapIntOcl
Definition: qrack_types.hpp:50