Qrack  9.0
General classical-emulating-quantum development framework
qbdt_node_interface.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 
20 
21 #include <mutex>
22 
23 #if ENABLE_COMPLEX_X2
24 #if FPPOW == 5
26 #elif FPPOW == 6
28 #endif
29 #endif
30 
31 namespace Qrack {
32 
33 class QBdtNodeInterface;
34 typedef std::shared_ptr<QBdtNodeInterface> QBdtNodeInterfacePtr;
35 
37 protected:
38  static size_t SelectBit(bitCapInt perm, bitLenInt bit) { return (size_t)((perm >> bit) & 1U); }
39  static void _par_for_qbdt(const bitCapInt end, BdtFunc fn);
40 
41 public:
42 #if ENABLE_COMPLEX_X2
43  virtual void PushStateVector(const complex2& mtrxCol1, const complex2& mtrxCol2, const complex2& mtrxColShuff1,
44  const complex2& mtrxColShuff2, QBdtNodeInterfacePtr& b0, QBdtNodeInterfacePtr& b1, bitLenInt depth,
45  bitLenInt parDepth = 1U)
46 #else
48  bitLenInt depth, bitLenInt parDepth = 1U)
49 #endif
50  {
51  throw std::out_of_range("QBdtNodeInterface::PushStateVector() not implemented! (You probably set "
52  "QRACK_QBDT_SEPARABILITY_THRESHOLD too high.)");
53  }
54 
57  std::mutex mtx;
58 
60  : scale(ONE_CMPLX)
61  {
62  branches[0U] = NULL;
63  branches[1U] = NULL;
64  }
65 
67  : scale(scl)
68  {
69  branches[0U] = NULL;
70  branches[1U] = NULL;
71  }
72 
74  : scale(scl)
75  {
76  branches[0U] = b[0U];
77  branches[1U] = b[1U];
78  }
79 
81  {
82  // Virtual destructor for inheritance
83  }
84 
85  virtual void InsertAtDepth(QBdtNodeInterfacePtr b, bitLenInt depth, const bitLenInt& size, bitLenInt parDepth = 1U)
86  {
87  throw std::out_of_range("QBdtNodeInterface::InsertAtDepth() not implemented! (You probably set "
88  "QRACK_QBDT_SEPARABILITY_THRESHOLD too high.)");
89  }
90 
92  bitLenInt depth, const bitLenInt& size, bitLenInt parDepth = 1U);
93 
94  virtual void SetZero()
95  {
96  scale = ZERO_CMPLX;
97 
98  if (!branches[0U]) {
99  return;
100  }
101 
102  if (true) {
104  std::lock_guard<std::mutex> lock(b0->mtx);
105  branches[0U] = NULL;
106  }
107 
108  if (true) {
110  std::lock_guard<std::mutex> lock(b1->mtx);
111  branches[1U] = NULL;
112  }
113  }
114 
115  virtual bool isEqual(QBdtNodeInterfacePtr r);
116 
117  virtual bool isEqualUnder(QBdtNodeInterfacePtr r);
118 
119  virtual bool isEqualBranch(QBdtNodeInterfacePtr r, const bool& b);
120 
122  {
123  throw std::out_of_range("QBdtNodeInterface::ShallowClone() not implemented! (You probably set "
124  "QRACK_QBDT_SEPARABILITY_THRESHOLD too high.)");
125  }
126 
127  virtual void PopStateVector(bitLenInt depth = 1U, bitLenInt parDepth = 1U)
128  {
129  throw std::out_of_range("QBdtNodeInterface::PopStateVector() not implemented! (You probably set "
130  "QRACK_QBDT_SEPARABILITY_THRESHOLD too high.)");
131  }
132 
133  virtual void Branch(bitLenInt depth = 1U, bitLenInt parDepth = 1U)
134  {
135  throw std::out_of_range("QBdtNodeInterface::Branch() not implemented! (You probably set "
136  "QRACK_QBDT_SEPARABILITY_THRESHOLD too high.)");
137  }
138 
139  virtual void Prune(bitLenInt depth = 1U, bitLenInt parDepth = 1U)
140  {
141  throw std::out_of_range("QBdtNodeInterface::Prune() not implemented! (You probably set "
142  "QRACK_QBDT_SEPARABILITY_THRESHOLD too high.)");
143  }
144 
145  virtual void Normalize(bitLenInt depth = 1U)
146  {
147  throw std::out_of_range("QBdtNodeInterface::Normalize() not implemented! (You probably set "
148  "QRACK_QBDT_SEPARABILITY_THRESHOLD too high.)");
149  }
150 
151 #if ENABLE_COMPLEX_X2
152  virtual void Apply2x2(const complex2& mtrxCol1, const complex2& mtrxCol2, const complex2& mtrxColShuff1,
153  const complex2& mtrxColShuff2, bitLenInt depth)
154 #else
155  virtual void Apply2x2(complex const* mtrx, bitLenInt depth)
156 #endif
157  {
158  throw std::out_of_range("QBdtNodeInterface::Apply2x2() not implemented! (You probably set "
159  "QRACK_QBDT_SEPARABILITY_THRESHOLD too high.)");
160  }
161 
162 #if ENABLE_COMPLEX_X2
163  virtual void PushSpecial(const complex2& mtrxCol1, const complex2& mtrxCol2, const complex2& mtrxColShuff1,
164  const complex2& mtrxColShuff2, QBdtNodeInterfacePtr& b1)
165 #else
166  virtual void PushSpecial(complex const* mtrx, QBdtNodeInterfacePtr& b1)
167 #endif
168  {
169  throw std::out_of_range("QBdtNodeInterface::PushSpecial() not implemented! (You probably called "
170  "PushStateVector() past terminal depth.)");
171  }
172 };
173 
176 } // namespace Qrack
Definition: qbdt_node_interface.hpp:36
virtual void Prune(bitLenInt depth=1U, bitLenInt parDepth=1U)
Definition: qbdt_node_interface.hpp:139
virtual void Normalize(bitLenInt depth=1U)
Definition: qbdt_node_interface.hpp:145
virtual bool isEqualUnder(QBdtNodeInterfacePtr r)
Definition: node_interface.cpp:70
std::mutex mtx
Definition: qbdt_node_interface.hpp:57
virtual void Apply2x2(complex const *mtrx, bitLenInt depth)
Definition: qbdt_node_interface.hpp:155
static void _par_for_qbdt(const bitCapInt end, BdtFunc fn)
Definition: node_interface.cpp:222
virtual bool isEqual(QBdtNodeInterfacePtr r)
Definition: node_interface.cpp:61
virtual ~QBdtNodeInterface()
Definition: qbdt_node_interface.hpp:80
QBdtNodeInterface(complex scl)
Definition: qbdt_node_interface.hpp:66
virtual void Branch(bitLenInt depth=1U, bitLenInt parDepth=1U)
Definition: qbdt_node_interface.hpp:133
virtual QBdtNodeInterfacePtr ShallowClone()
Definition: qbdt_node_interface.hpp:121
virtual void InsertAtDepth(QBdtNodeInterfacePtr b, bitLenInt depth, const bitLenInt &size, bitLenInt parDepth=1U)
Definition: qbdt_node_interface.hpp:85
virtual void PushSpecial(complex const *mtrx, QBdtNodeInterfacePtr &b1)
Definition: qbdt_node_interface.hpp:166
virtual void PushStateVector(complex const *mtrx, QBdtNodeInterfacePtr &b0, QBdtNodeInterfacePtr &b1, bitLenInt depth, bitLenInt parDepth=1U)
Definition: qbdt_node_interface.hpp:47
virtual void SetZero()
Definition: qbdt_node_interface.hpp:94
QBdtNodeInterface()
Definition: qbdt_node_interface.hpp:59
QBdtNodeInterfacePtr branches[2U]
Definition: qbdt_node_interface.hpp:56
complex scale
Definition: qbdt_node_interface.hpp:55
virtual bool isEqualBranch(QBdtNodeInterfacePtr r, const bool &b)
Definition: node_interface.cpp:79
virtual QBdtNodeInterfacePtr RemoveSeparableAtDepth(bitLenInt depth, const bitLenInt &size, bitLenInt parDepth=1U)
Definition: node_interface.cpp:120
static size_t SelectBit(bitCapInt perm, bitLenInt bit)
Definition: qbdt_node_interface.hpp:38
QBdtNodeInterface(complex scl, QBdtNodeInterfacePtr *b)
Definition: qbdt_node_interface.hpp:73
virtual void PopStateVector(bitLenInt depth=1U, bitLenInt parDepth=1U)
Definition: qbdt_node_interface.hpp:127
Definition: complex16x2simd.hpp:25
std::complex< half_float::half > complex
Definition: qrack_types.hpp:62
std::function< bitCapInt(const bitCapInt &)> BdtFunc
Definition: qrack_types.hpp:128
bool operator==(QBdtNodeInterfacePtr lhs, QBdtNodeInterfacePtr rhs)
Definition: node_interface.cpp:46
QRACK_CONST complex ONE_CMPLX
Definition: qrack_types.hpp:239
bool operator!=(QBdtNodeInterfacePtr lhs, QBdtNodeInterfacePtr rhs)
Definition: node_interface.cpp:59
std::shared_ptr< QBdtNodeInterface > QBdtNodeInterfacePtr
Definition: qbdt_node_interface.hpp:33
QRACK_CONST complex ZERO_CMPLX
Definition: qrack_types.hpp:240
MICROSOFT_QUANTUM_DECL void U(_In_ uintq sid, _In_ uintq q, _In_ double theta, _In_ double phi, _In_ double lambda)
(External API) 3-parameter unitary gate
Definition: pinvoke_api.cpp:1362
#define bitLenInt
Definition: qrack_types.hpp:44
#define bitCapInt
Definition: qrack_types.hpp:105
SIMD implementation of the double precision complex vector type of 2 complex numbers,...
Definition: complex16x2simd.hpp:30