Qrack  1.7
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, 2018. 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 General Public License V3.
10 // See LICENSE.md in the project root or https://www.gnu.org/licenses/gpl-3.0.en.html
11 // for details.
12 
13 #pragma once
14 
15 #include <random>
16 
17 #include "qinterface.hpp"
18 
19 namespace Qrack {
20 
22 struct QEngineShard {
25 };
26 
27 class QUnit;
28 typedef std::shared_ptr<QUnit> QUnitPtr;
29 
30 class QUnit : public QInterface {
31 protected:
33  std::vector<QEngineShard> shards;
34 
35  std::shared_ptr<std::default_random_engine> rand_generator;
36 
37  virtual void SetQubitCount(bitLenInt qb)
38  {
39  shards.resize(qb);
41  }
42 
43 public:
44  QUnit(QInterfaceEngine eng, bitLenInt qBitCount, bitCapInt initState = 0,
45  std::shared_ptr<std::default_random_engine> rgp = nullptr);
46 
47  virtual void SetQuantumState(complex* inputState);
48  virtual void SetPermutation(bitCapInt perm) { SetReg(0, qubitCount, perm); }
49  using QInterface::Cohere;
50  virtual bitLenInt Cohere(QInterfacePtr toCopy);
51  virtual void Decohere(bitLenInt start, bitLenInt length, QInterfacePtr dest);
52  virtual void Dispose(bitLenInt start, bitLenInt length);
53 
59  virtual void ApplySingleBit(const complex* mtrx, bool doCalcNorm, bitLenInt qubit);
60  virtual void CCNOT(bitLenInt control1, bitLenInt control2, bitLenInt target);
61  virtual void AntiCCNOT(bitLenInt control1, bitLenInt control2, bitLenInt target);
62  virtual void CNOT(bitLenInt control, bitLenInt target);
63  virtual void AntiCNOT(bitLenInt control, bitLenInt target);
64  virtual void H(bitLenInt qubit);
65  virtual bool M(bitLenInt qubit);
66  virtual void X(bitLenInt qubit);
67  virtual void Y(bitLenInt qubit);
68  virtual void Z(bitLenInt qubit);
69  virtual void CY(bitLenInt control, bitLenInt target);
70  virtual void CZ(bitLenInt control, bitLenInt target);
71 
83  virtual void AND(bitLenInt inputBit1, bitLenInt inputBit2, bitLenInt outputBit);
84  virtual void AND(bitLenInt inputBit1, bitLenInt inputBit2, bitLenInt outputBit, bitLenInt length);
85  virtual void OR(bitLenInt inputBit1, bitLenInt inputBit2, bitLenInt outputBit);
86  virtual void OR(bitLenInt inputBit1, bitLenInt inputBit2, bitLenInt outputBit, bitLenInt length);
87  virtual void XOR(bitLenInt inputBit1, bitLenInt inputBit2, bitLenInt outputBit);
88  virtual void XOR(bitLenInt inputBit1, bitLenInt inputBit2, bitLenInt outputBit, bitLenInt length);
89  virtual void CLAND(bitLenInt inputQBit, bool inputClassicalBit, bitLenInt outputBit);
90  virtual void CLAND(bitLenInt qInputStart, bitCapInt classicalInput, bitLenInt outputStart, bitLenInt length);
91  virtual void CLOR(bitLenInt inputQBit, bool inputClassicalBit, bitLenInt outputBit);
92  virtual void CLOR(bitLenInt qInputStart, bitCapInt classicalInput, bitLenInt outputStart, bitLenInt length);
93  virtual void CLXOR(bitLenInt inputQBit, bool inputClassicalBit, bitLenInt outputBit);
94  virtual void CLXOR(bitLenInt qInputStart, bitCapInt classicalInput, bitLenInt outputStart, bitLenInt length);
95 
107  virtual void RT(real1 radians, bitLenInt qubit);
108  virtual void RX(real1 radians, bitLenInt qubit);
109  virtual void RY(real1 radians, bitLenInt qubit);
110  virtual void RZ(real1 radians, bitLenInt qubit);
111  virtual void Exp(real1 radians, bitLenInt qubit);
112  virtual void ExpX(real1 radians, bitLenInt qubit);
113  virtual void ExpY(real1 radians, bitLenInt qubit);
114  virtual void ExpZ(real1 radians, bitLenInt qubit);
115  virtual void CRX(real1 radians, bitLenInt control, bitLenInt target);
116  virtual void CRY(real1 radians, bitLenInt control, bitLenInt target);
117  virtual void CRZ(real1 radians, bitLenInt control, bitLenInt target);
118  virtual void CRT(real1 radians, bitLenInt control, bitLenInt target);
119 
128  virtual void INC(bitCapInt toAdd, bitLenInt start, bitLenInt length);
129  virtual void INCC(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex);
130  virtual void INCS(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex);
131  virtual void INCSC(
132  bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex, bitLenInt carryIndex);
133  virtual void INCSC(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex);
134  virtual void INCBCD(bitCapInt toAdd, bitLenInt start, bitLenInt length);
135  virtual void INCBCDC(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex);
136  virtual void DEC(bitCapInt toSub, bitLenInt start, bitLenInt length);
137  virtual void DECC(bitCapInt toSub, bitLenInt start, bitLenInt length, bitLenInt carryIndex);
138  virtual void DECS(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex);
139  virtual void DECSC(
140  bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex, bitLenInt carryIndex);
141  virtual void DECSC(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex);
142  virtual void DECBCD(bitCapInt toAdd, bitLenInt start, bitLenInt length);
143  virtual void DECBCDC(bitCapInt toSub, bitLenInt start, bitLenInt length, bitLenInt carryIndex);
144  virtual void MUL(
145  bitCapInt toMul, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length, bool clearCarry = false);
146  virtual void DIV(bitCapInt toDiv, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length);
147  virtual void CMUL(bitCapInt toMul, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt controlBit,
148  bitLenInt length, bool clearCarry = false);
149  virtual void CDIV(
150  bitCapInt toDiv, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt controlBit, bitLenInt length);
151 
160  virtual void ZeroPhaseFlip(bitLenInt start, bitLenInt length);
161  virtual void CPhaseFlipIfLess(bitCapInt greaterPerm, bitLenInt start, bitLenInt length, bitLenInt flagIndex);
162  virtual void PhaseFlip();
163  virtual void SetReg(bitLenInt start, bitLenInt length, bitCapInt value);
164  virtual bitCapInt MReg(bitLenInt start, bitLenInt length);
165  virtual bitCapInt IndexedLDA(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart,
166  bitLenInt valueLength, unsigned char* values);
167  virtual bitCapInt IndexedADC(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart,
168  bitLenInt valueLength, bitLenInt carryIndex, unsigned char* values);
169  virtual bitCapInt IndexedSBC(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart,
170  bitLenInt valueLength, bitLenInt carryIndex, unsigned char* values);
171  virtual void Swap(bitLenInt qubit1, bitLenInt qubit2);
172 
181  virtual void CopyState(QUnitPtr orig);
182  virtual void CopyState(QInterfacePtr orig);
183  virtual real1 Prob(bitLenInt qubit);
184  virtual real1 ProbAll(bitCapInt fullRegister);
185  virtual void SetBit(bitLenInt qubit1, bool value);
186 
189 protected:
190  typedef void (QInterface::*INCxFn)(bitCapInt, bitLenInt, bitLenInt, bitLenInt);
192  void INCx(INCxFn fn, bitCapInt toMod, bitLenInt start, bitLenInt length, bitLenInt flagIndex);
193  void INCxx(
194  INCxxFn fn, bitCapInt toMod, bitLenInt start, bitLenInt length, bitLenInt flag1Index, bitLenInt flag2Index);
195 
196  QInterfacePtr Entangle(std::initializer_list<bitLenInt*> bits);
197  QInterfacePtr EntangleRange(bitLenInt start, bitLenInt length);
198  QInterfacePtr EntangleRange(bitLenInt start, bitLenInt length, bitLenInt start2, bitLenInt length2);
199 
200  template <class It> QInterfacePtr EntangleIterator(It first, It last);
201 
202  template <typename F, typename... B> void EntangleAndCallMember(F fn, B... bits);
203  template <typename F, typename... B> void EntangleAndCall(F fn, B... bits);
204 
205  void OrderContiguous(QInterfacePtr unit);
206 
207  void Detach(bitLenInt start, bitLenInt length, QInterfacePtr dest);
208 
209  struct QSortEntry {
210  bitLenInt bit;
211  bitLenInt mapped;
212  bool operator<(const QSortEntry& rhs) { return mapped < rhs.mapped; }
213  bool operator>(const QSortEntry& rhs) { return mapped > rhs.mapped; }
214  };
215  void SortUnit(QInterfacePtr unit, std::vector<QSortEntry>& bits, bitLenInt low, bitLenInt high);
216 
217  void Apply2x2(bitCapInt offset1, bitCapInt offset2, const complex* mtrx, const bitLenInt bitCount,
218  const bitCapInt* qPowersSorted, bool doCalcNorm)
219  {
220  throw "Apply2x2 not implemented in interface";
221  }
222  void ApplyM(bitCapInt qPower, bool result, complex nrm) { throw "ApplyM not implemented in interface"; }
223  void NormalizeState(real1 nrm = -999.0) { throw "NormalizeState not implemented in interface"; }
224 
225  /* Debugging and diagnostic routines. */
226  void DumpShards();
227  QInterfacePtr GetUnit(bitLenInt bit) { return shards[bit].unit; }
228 };
229 
230 } // namespace Qrack
Definition: qunit.hpp:209
void NormalizeState(real1 nrm=-999.0)
Definition: qunit.hpp:223
virtual void SetQubitCount(bitLenInt qb)
Definition: qinterface.hpp:110
bitLenInt mapped
Definition: qunit.hpp:211
QInterfacePtr unit
Definition: qunit.hpp:23
#define real1
Definition: qinterface.hpp:36
std::shared_ptr< QUnit > QUnitPtr
Definition: qunit.hpp:27
std::shared_ptr< std::default_random_engine > rand_generator
Definition: qunit.hpp:35
virtual void SetQubitCount(bitLenInt qb)
Definition: qunit.hpp:37
void Apply2x2(bitCapInt offset1, bitCapInt offset2, const complex *mtrx, const bitLenInt bitCount, const bitCapInt *qPowersSorted, bool doCalcNorm)
Definition: qunit.hpp:217
QInterfaceEngine engine
Definition: qunit.hpp:32
bool operator<(const QSortEntry &rhs)
Definition: qunit.hpp:212
#define complex
Definition: qinterface.hpp:35
virtual bitLenInt Cohere(QInterfacePtr toCopy)=0
Combine another QInterface with this one, after the last bit index of this one.
std::vector< QEngineShard > shards
Definition: qunit.hpp:33
QInterfaceEngine
Enumerated list of supported engines.
Definition: qinterface.hpp:54
#define bitCapInt
Definition: qinterface.hpp:22
#define bitLenInt
Definition: qinterface.hpp:21
QInterfacePtr GetUnit(bitLenInt bit)
Definition: qunit.hpp:227
Associates a QInterface object with a set of bits.
Definition: qunit.hpp:22
A "Qrack::QInterface" is an abstract interface exposing qubit permutation state vector with methods t...
Definition: qinterface.hpp:99
void ApplyM(bitCapInt qPower, bool result, complex nrm)
Definition: qunit.hpp:222
bool operator>(const QSortEntry &rhs)
Definition: qunit.hpp:213
bitLenInt mapped
Definition: qunit.hpp:24
bitLenInt bit
Definition: qunit.hpp:210
std::shared_ptr< QInterface > QInterfacePtr
Definition: qinterface.hpp:46
Definition: qunit.hpp:30
virtual void SetPermutation(bitCapInt perm)
Set to a specific permutation.
Definition: qunit.hpp:48
Definition: complex16simd.hpp:21