Qrack  9.0
General classical-emulating-quantum development framework
qtensornetwork.hpp
Go to the documentation of this file.
1 //
3 // (C) Daniel Strano and the Qrack contributors 2017-2023. All rights reserved.
4 //
5 // QTensorNetwork is a gate-based QInterface descendant wrapping cuQuantum.
6 //
7 // Licensed under the GNU Lesser General Public License V3.
8 // See LICENSE.md in the project root or https://www.gnu.org/licenses/lgpl-3.0.en.html
9 // for details.
10 
11 #pragma once
12 
13 #include "qcircuit.hpp"
14 
15 namespace Qrack {
16 
17 class QTensorNetwork;
18 typedef std::shared_ptr<QTensorNetwork> QTensorNetworkPtr;
19 
20 // #if ENABLE_CUDA
21 // struct TensorMeta {
22 // std::vector<std::vector<int32_t>> modes;
23 // std::vector<std::vector<int64_t>> extents;
24 // };
25 // typedef std::vector<TensorMeta> TensorNetworkMeta;
26 // typedef std::shared_ptr<TensorNetworkMeta> TensorNetworkMetaPtr;
27 // #endif
28 
29 class QTensorNetwork : public QInterface {
30 protected:
31  bool useHostRam;
32  bool isSparse;
34  bool useTGadget;
36  int64_t devID;
39  std::vector<int64_t> deviceIDs;
40  std::vector<QInterfaceEngine> engines;
41  std::vector<QCircuitPtr> circuit;
42  std::vector<std::map<bitLenInt, bool>> measurements;
43 
44  QCircuitPtr GetCircuit(bitLenInt target, std::vector<bitLenInt> controls = std::vector<bitLenInt>())
45  {
46  for (size_t i = 0U; i < measurements.size(); ++i) {
47  size_t l = measurements.size() - (i + 1U);
48  std::map<bitLenInt, bool>& m = measurements[l];
49  ++l;
50 
51  if (m.find(target) != m.end()) {
52  if (circuit.size() == l) {
53  circuit.push_back(std::make_shared<QCircuit>());
54  }
55 
56  return circuit[l];
57  }
58 
59  for (size_t j = 0U; j < controls.size(); ++j) {
60  if (m.find(controls[j]) != m.end()) {
61  if (circuit.size() == l) {
62  circuit.push_back(std::make_shared<QCircuit>());
63  }
64 
65  return circuit[l];
66  }
67  }
68  }
69 
70  return circuit[0U];
71  }
72 
74  {
75  if (target >= qubitCount) {
76  throw std::invalid_argument("QTensorNetwork qubit index values must be within allocated qubit bounds!");
77  }
78  }
79 
80  void CheckQubitCount(bitLenInt target, const std::vector<bitLenInt>& controls)
81  {
82  CheckQubitCount(target);
84  controls, qubitCount, "QTensorNetwork qubit index values must be within allocated qubit bounds!");
85  }
86 
87  void RunMeasurmentLayer(size_t layerId)
88  {
89  const std::map<bitLenInt, bool>& mLayer = measurements[layerId];
90  std::vector<bitLenInt> bits;
91  bits.reserve(mLayer.size());
92  std::vector<bool> values;
93  values.reserve(mLayer.size());
94 
95  for (const auto& m : mLayer) {
96  bits.push_back(m.first);
97  values.push_back(m.second);
98  }
99 
100  layerStack->ForceM(bits, values);
101  }
102 
104  {
105 #if ENABLE_ENV_VARS
106  return getenv("QRACK_QTENSORNETWORK_THRESHOLD_QB")
107  ? (bitLenInt)std::stoi(std::string(getenv("QRACK_QTENSORNETWORK_THRESHOLD_QB")))
108  : 30U;
109 #else
110  return 30U;
111 #endif
112  }
113 
114  void MakeLayerStack(std::set<bitLenInt> qubits = std::set<bitLenInt>());
115 
116  template <typename Fn> void RunAsAmplitudes(Fn fn, const std::set<bitLenInt>& qubits = std::set<bitLenInt>())
117  {
118  if (!qubits.size()) {
119  MakeLayerStack();
120  return fn(layerStack);
121  }
122 
123  const bitLenInt maxQb = GetThresholdQb();
124  if (qubitCount <= maxQb) {
125  MakeLayerStack();
126  return fn(layerStack);
127  } else {
128  // #if ENABLE_CUDA
129  // TODO: Calculate result of measurement with cuTensorNetwork
130  // TensorNetworkMetaPtr network = MakeTensorNetwork();
131  // throw std::runtime_error("QTensorNetwork doesn't have cuTensorNetwork capabilities yet!");
132  // #else
133  MakeLayerStack(qubits);
135  layerStack = NULL;
136  return fn(ls);
137  // #endif
138  }
139  }
140 
141  // #if ENABLE_CUDA
142  // TensorNetworkMetaPtr MakeTensorNetwork() { return NULL; }
143  // #endif
144 
145 public:
146  QTensorNetwork(std::vector<QInterfaceEngine> eng, bitLenInt qBitCount, bitCapInt initState = 0,
147  qrack_rand_gen_ptr rgp = nullptr, complex phaseFac = CMPLX_DEFAULT_ARG, bool doNorm = false,
148  bool randomGlobalPhase = true, bool useHostMem = false, int64_t deviceId = -1, bool useHardwareRNG = true,
149  bool useSparseStateVec = false, real1_f norm_thresh = REAL1_EPSILON, std::vector<int64_t> ignored = {},
150  bitLenInt qubitThreshold = 0, real1_f separation_thresh = FP_NORM_EPSILON_F);
151 
152  QTensorNetwork(bitLenInt qBitCount, bitCapInt initState = 0U, qrack_rand_gen_ptr rgp = nullptr,
153  complex phaseFac = CMPLX_DEFAULT_ARG, bool doNorm = false, bool randomGlobalPhase = true,
154  bool useHostMem = false, int64_t deviceId = -1, bool useHardwareRNG = true, bool useSparseStateVec = false,
155  real1_f norm_thresh = REAL1_EPSILON, std::vector<int64_t> devList = {}, bitLenInt qubitThreshold = 0U,
156  real1_f separation_thresh = FP_NORM_EPSILON_F)
157  : QTensorNetwork({}, qBitCount, initState, rgp, phaseFac, doNorm, randomGlobalPhase, useHostMem, deviceId,
158  useHardwareRNG, useSparseStateVec, norm_thresh, devList, qubitThreshold, separation_thresh)
159  {
160  }
161 
162  virtual double GetUnitaryFidelity()
163  {
164  double toRet;
165  RunAsAmplitudes([&](QInterfacePtr ls) { toRet = ls->GetUnitaryFidelity(); });
166  return toRet;
167  }
168 
169  void SetDevice(int64_t dID) { devID = dID; }
170 
171  void Finish()
172  {
173  if (layerStack) {
174  layerStack->Finish();
175  }
176  };
177 
178  bool isFinished() { return !layerStack || layerStack->isFinished(); }
179 
180  void Dump()
181  {
182  if (layerStack) {
183  layerStack->Dump();
184  }
185  }
186 
188  {
189  if (layerStack) {
190  layerStack->UpdateRunningNorm(norm_thresh);
191  }
192  }
193 
195  real1_f nrm = REAL1_DEFAULT_ARG, real1_f norm_thresh = REAL1_DEFAULT_ARG, real1_f phaseArg = ZERO_R1_F)
196  {
197  if (layerStack) {
198  layerStack->NormalizeState(nrm, norm_thresh, phaseArg);
199  }
200  }
201 
203  {
204  return SumSqrDiff(std::dynamic_pointer_cast<QTensorNetwork>(toCompare));
205  }
207  {
208  real1_f toRet;
209  toCompare->MakeLayerStack();
210  RunAsAmplitudes([&](QInterfacePtr ls) { toRet = ls->SumSqrDiff(toCompare->layerStack); });
211  return toRet;
212  }
213 
214  void SetPermutation(bitCapInt initState, complex phaseFac = CMPLX_DEFAULT_ARG)
215  {
216  circuit.clear();
217  measurements.clear();
218  layerStack = NULL;
219 
220  circuit.push_back(std::make_shared<QCircuit>());
221 
222  for (bitLenInt i = 0U; i < qubitCount; ++i) {
223  if (initState & pow2(i)) {
224  X(i);
225  }
226  }
227 
228  if ((phaseFac == CMPLX_DEFAULT_ARG) && randGlobalPhase) {
229  real1_f angle = Rand() * 2 * (real1_f)PI_R1;
230  globalPhase = complex((real1)cos(angle), (real1)sin(angle));
231  }
232  }
233 
235 
237  {
238  RunAsAmplitudes([&](QInterfacePtr ls) { ls->GetQuantumState(state); });
239  }
240  void SetQuantumState(const complex* state)
241  {
242  throw std::domain_error("QTensorNetwork::SetQuantumState() not implemented!");
243  }
245  {
246  throw std::domain_error("QTensorNetwork::SetQuantumState() not implemented!");
247  }
248  void GetProbs(real1* outputProbs)
249  {
250  RunAsAmplitudes([&](QInterfacePtr ls) { ls->GetProbs(outputProbs); });
251  }
252 
254  {
255  complex toRet;
256  RunAsAmplitudes([&](QInterfacePtr ls) { toRet = ls->GetAmplitude(perm); });
257  return toRet;
258  }
260  {
261  throw std::domain_error("QTensorNetwork::SetAmplitude() not implemented!");
262  }
263 
264  using QInterface::Compose;
266  {
267  throw std::domain_error("QTensorNetwork::Compose() not implemented!");
268  }
270  {
271  throw std::domain_error("QTensorNetwork::Decompose() not implemented!");
272  }
274  {
275  throw std::domain_error("QTensorNetwork::Decompose() not implemented!");
276  }
277  void Dispose(bitLenInt start, bitLenInt length)
278  {
279  throw std::domain_error("QTensorNetwork::Dispose() not implemented!");
280  }
281  void Dispose(bitLenInt start, bitLenInt length, bitCapInt disposedPerm)
282  {
283  throw std::domain_error("QTensorNetwork::Dispose() not implemented!");
284  }
285 
286  using QInterface::Allocate;
288  {
289  if (start > qubitCount) {
290  throw std::invalid_argument("QTensorNetwork::Allocate() 'start' argument is out-of-bounds!");
291  }
292 
293  if (!length) {
294  return start;
295  }
296 
297  const bitLenInt movedQubits = qubitCount - start;
298  SetQubitCount(qubitCount + length);
299  if (!movedQubits) {
300  return start;
301  }
302 
303  for (bitLenInt i = 0U; i < movedQubits; ++i) {
304  const bitLenInt q = start + movedQubits - (i + 1U);
305  Swap(q, q + length);
306  }
307 
308  return start;
309  }
310 
312  {
313  real1_f toRet;
314  RunAsAmplitudes([&](QInterfacePtr ls) { toRet = ls->Prob(qubit); }, { qubit });
315  return toRet;
316  }
317  real1_f ProbAll(bitCapInt fullRegister)
318  {
319  real1_f toRet;
320  RunAsAmplitudes([&](QInterfacePtr ls) { toRet = ls->ProbAll(fullRegister); });
321  return toRet;
322  }
323 
324  bool ForceM(bitLenInt qubit, bool result, bool doForce = true, bool doApply = true);
325 
327  {
328  bitCapInt toRet = 0U;
329 
330  const bitLenInt maxQb = GetThresholdQb();
331  if (qubitCount <= maxQb) {
332  MakeLayerStack();
333  toRet = layerStack->MAll();
334  } else {
335  for (bitLenInt i = 0U; i < qubitCount; ++i) {
336  if (M(i)) {
337  toRet |= pow2(i);
338  }
339  }
340  }
341 
342  SetPermutation(toRet);
343 
344  return toRet;
345  }
346 
347  std::map<bitCapInt, int> MultiShotMeasureMask(const std::vector<bitCapInt>& qPowers, unsigned shots)
348  {
349  std::set<bitLenInt> qubits;
350  for (const bitCapInt& qPow : qPowers) {
351  qubits.insert(log2(qPow));
352  }
353  std::map<bitCapInt, int> toRet;
354  RunAsAmplitudes([&](QInterfacePtr ls) { toRet = ls->MultiShotMeasureMask(qPowers, shots); }, qubits);
355 
356  return toRet;
357  }
358  void MultiShotMeasureMask(const std::vector<bitCapInt>& qPowers, unsigned shots, unsigned long long* shotsArray)
359  {
360  std::set<bitLenInt> qubits;
361  for (const bitCapInt& qPow : qPowers) {
362  qubits.insert(log2(qPow));
363  }
364  RunAsAmplitudes([&](QInterfacePtr ls) { ls->MultiShotMeasureMask(qPowers, shots, shotsArray); }, qubits);
365  }
366 
367  void Mtrx(const complex* mtrx, bitLenInt target)
368  {
369  CheckQubitCount(target);
370  layerStack = NULL;
371  GetCircuit(target)->AppendGate(std::make_shared<QCircuitGate>(target, mtrx));
372  }
373  void MCMtrx(const std::vector<bitLenInt>& controls, const complex* mtrx, bitLenInt target)
374  {
375  CheckQubitCount(target, controls);
376  layerStack = NULL;
377  GetCircuit(target, controls)
378  ->AppendGate(std::make_shared<QCircuitGate>(
379  target, mtrx, std::set<bitLenInt>{ controls.begin(), controls.end() }, pow2(controls.size()) - 1U));
380  }
381  void MACMtrx(const std::vector<bitLenInt>& controls, const complex* mtrx, bitLenInt target)
382  {
383  CheckQubitCount(target, controls);
384  layerStack = NULL;
385  GetCircuit(target, controls)
386  ->AppendGate(std::make_shared<QCircuitGate>(
387  target, mtrx, std::set<bitLenInt>{ controls.begin(), controls.end() }, 0U));
388  }
389  void MCPhase(const std::vector<bitLenInt>& controls, complex topLeft, complex bottomRight, bitLenInt target)
390  {
391  CheckQubitCount(target, controls);
392  layerStack = NULL;
393  std::shared_ptr<complex> lMtrx(new complex[4U], std::default_delete<complex[]>());
394  lMtrx.get()[0U] = topLeft;
395  lMtrx.get()[1U] = ZERO_CMPLX;
396  lMtrx.get()[2U] = ZERO_CMPLX;
397  lMtrx.get()[3U] = bottomRight;
398  GetCircuit(target, controls)
399  ->AppendGate(std::make_shared<QCircuitGate>(target, lMtrx.get(),
400  std::set<bitLenInt>{ controls.begin(), controls.end() }, pow2(controls.size()) - 1U));
401  }
402  void MACPhase(const std::vector<bitLenInt>& controls, complex topLeft, complex bottomRight, bitLenInt target)
403  {
404  CheckQubitCount(target, controls);
405  layerStack = NULL;
406  std::shared_ptr<complex> lMtrx(new complex[4U], std::default_delete<complex[]>());
407  lMtrx.get()[0U] = topLeft;
408  lMtrx.get()[1U] = ZERO_CMPLX;
409  lMtrx.get()[2U] = ZERO_CMPLX;
410  lMtrx.get()[3U] = bottomRight;
411  GetCircuit(target, controls)
412  ->AppendGate(std::make_shared<QCircuitGate>(
413  target, lMtrx.get(), std::set<bitLenInt>{ controls.begin(), controls.end() }, 0U));
414  }
415  void MCInvert(const std::vector<bitLenInt>& controls, complex topRight, complex bottomLeft, bitLenInt target)
416  {
417  CheckQubitCount(target, controls);
418  layerStack = NULL;
419  std::shared_ptr<complex> lMtrx(new complex[4U], std::default_delete<complex[]>());
420  lMtrx.get()[0U] = ZERO_CMPLX;
421  lMtrx.get()[1U] = topRight;
422  lMtrx.get()[2U] = bottomLeft;
423  lMtrx.get()[3U] = ZERO_CMPLX;
424  GetCircuit(target, controls)
425  ->AppendGate(std::make_shared<QCircuitGate>(target, lMtrx.get(),
426  std::set<bitLenInt>{ controls.begin(), controls.end() }, pow2(controls.size()) - 1U));
427  }
428  void MACInvert(const std::vector<bitLenInt>& controls, complex topRight, complex bottomLeft, bitLenInt target)
429  {
430  CheckQubitCount(target, controls);
431  layerStack = NULL;
432  std::shared_ptr<complex> lMtrx(new complex[4U], std::default_delete<complex[]>());
433  lMtrx.get()[0U] = ZERO_CMPLX;
434  lMtrx.get()[1U] = topRight;
435  lMtrx.get()[2U] = bottomLeft;
436  lMtrx.get()[3U] = ZERO_CMPLX;
437  GetCircuit(target, controls)
438  ->AppendGate(std::make_shared<QCircuitGate>(
439  target, lMtrx.get(), std::set<bitLenInt>{ controls.begin(), controls.end() }, 0U));
440  }
441 
442  void FSim(real1_f theta, real1_f phi, bitLenInt qubit1, bitLenInt qubit2);
443 };
444 } // namespace Qrack
A "Qrack::QInterface" is an abstract interface exposing qubit permutation state vector with methods t...
Definition: qinterface.hpp:146
virtual bitLenInt Allocate(bitLenInt length)
Allocate new "length" count of |0> state qubits at end of qubit index position.
Definition: qinterface.hpp:434
virtual bitLenInt Compose(QInterfacePtr toCopy)
Combine another QInterface with this one, after the last bit index of this one.
Definition: qinterface.hpp:338
bool randGlobalPhase
Definition: qinterface.hpp:149
virtual void SetQubitCount(bitLenInt qb)
Definition: qinterface.hpp:159
bitLenInt qubitCount
Definition: qinterface.hpp:151
real1_f Rand()
Generate a random real number between 0 and 1.
Definition: qinterface.hpp:260
Definition: qtensornetwork.hpp:29
void GetProbs(real1 *outputProbs)
Get the pure quantum state representation.
Definition: qtensornetwork.hpp:248
bitLenInt GetThresholdQb()
Definition: qtensornetwork.hpp:103
bool useTGadget
Definition: qtensornetwork.hpp:34
void SetQuantumState(const complex *state)
Set an arbitrary pure quantum state representation.
Definition: qtensornetwork.hpp:240
void Decompose(bitLenInt start, QInterfacePtr dest)
Minimally decompose a set of contiguous bits from the separably composed unit, into "destination".
Definition: qtensornetwork.hpp:269
QTensorNetwork(std::vector< QInterfaceEngine > eng, bitLenInt qBitCount, bitCapInt initState=0, qrack_rand_gen_ptr rgp=nullptr, 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=FP_NORM_EPSILON_F)
Definition: qtensornetwork.cpp:20
bool isSparse
Definition: qtensornetwork.hpp:32
void MCMtrx(const std::vector< bitLenInt > &controls, const complex *mtrx, bitLenInt target)
Apply an arbitrary single bit unitary transformation, with arbitrary control bits.
Definition: qtensornetwork.hpp:373
bool useHostRam
Definition: qtensornetwork.hpp:31
QCircuitPtr GetCircuit(bitLenInt target, std::vector< bitLenInt > controls=std::vector< bitLenInt >())
Definition: qtensornetwork.hpp:44
void CheckQubitCount(bitLenInt target)
Definition: qtensornetwork.hpp:73
real1_f Prob(bitLenInt qubit)
Direct measure of bit probability to be in |1> state.
Definition: qtensornetwork.hpp:311
QInterfacePtr Clone()
Clone this QInterface.
Definition: qtensornetwork.cpp:113
void Mtrx(const complex *mtrx, bitLenInt target)
Apply an arbitrary single bit unitary transformation.
Definition: qtensornetwork.hpp:367
bool isReactiveSeparate
Definition: qtensornetwork.hpp:33
bitLenInt Allocate(bitLenInt start, bitLenInt length)
Allocate new "length" count of |0> state qubits at specified qubit index start position.
Definition: qtensornetwork.hpp:287
real1_f SumSqrDiff(QInterfacePtr toCompare)
Definition: qtensornetwork.hpp:202
bool isNearClifford
Definition: qtensornetwork.hpp:35
void MACInvert(const std::vector< bitLenInt > &controls, complex topRight, complex bottomLeft, bitLenInt target)
Apply a single bit transformation that reverses bit probability and might effect phase,...
Definition: qtensornetwork.hpp:428
void SetAmplitude(bitCapInt perm, complex amp)
Sets the representational amplitude of a full permutation.
Definition: qtensornetwork.hpp:259
QTensorNetwork(bitLenInt qBitCount, bitCapInt initState=0U, qrack_rand_gen_ptr rgp=nullptr, 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=FP_NORM_EPSILON_F)
Definition: qtensornetwork.hpp:152
std::map< bitCapInt, int > MultiShotMeasureMask(const std::vector< bitCapInt > &qPowers, unsigned shots)
Statistical measure of masked permutation probability.
Definition: qtensornetwork.hpp:347
void MACPhase(const std::vector< bitLenInt > &controls, complex topLeft, complex bottomRight, bitLenInt target)
Apply a single bit transformation that only effects phase, with arbitrary (anti-)control bits.
Definition: qtensornetwork.hpp:402
void FSim(real1_f theta, real1_f phi, bitLenInt qubit1, bitLenInt qubit2)
The 2-qubit "fSim" gate, (useful in the simulation of particles with fermionic statistics)
Definition: qtensornetwork.cpp:242
complex globalPhase
Definition: qtensornetwork.hpp:37
void GetQuantumState(complex *state)
Get the pure quantum state representation.
Definition: qtensornetwork.hpp:236
void MCPhase(const std::vector< bitLenInt > &controls, complex topLeft, complex bottomRight, bitLenInt target)
Apply a single bit transformation that only effects phase, with arbitrary control bits.
Definition: qtensornetwork.hpp:389
QInterfacePtr Decompose(bitLenInt start, bitLenInt length)
Schmidt decompose a length of qubits.
Definition: qtensornetwork.hpp:273
int64_t devID
Definition: qtensornetwork.hpp:36
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: qtensornetwork.hpp:194
void SetDevice(int64_t dID)
Set the device index, if more than one device is available.
Definition: qtensornetwork.hpp:169
void CheckQubitCount(bitLenInt target, const std::vector< bitLenInt > &controls)
Definition: qtensornetwork.hpp:80
void Dispose(bitLenInt start, bitLenInt length, bitCapInt disposedPerm)
Dispose a a contiguous set of qubits that are already in a permutation eigenstate.
Definition: qtensornetwork.hpp:281
void SetQuantumState(QInterfacePtr eng)
Definition: qtensornetwork.hpp:244
std::vector< std::map< bitLenInt, bool > > measurements
Definition: qtensornetwork.hpp:42
complex GetAmplitude(bitCapInt perm)
Get the representational amplitude of a full permutation.
Definition: qtensornetwork.hpp:253
void MultiShotMeasureMask(const std::vector< bitCapInt > &qPowers, unsigned shots, unsigned long long *shotsArray)
Statistical measure of masked permutation probability (returned as array)
Definition: qtensornetwork.hpp:358
bitLenInt Compose(QInterfacePtr toCopy, bitLenInt start)
Definition: qtensornetwork.hpp:265
void RunMeasurmentLayer(size_t layerId)
Definition: qtensornetwork.hpp:87
std::vector< int64_t > deviceIDs
Definition: qtensornetwork.hpp:39
void MakeLayerStack(std::set< bitLenInt > qubits=std::set< bitLenInt >())
Definition: qtensornetwork.cpp:60
void MCInvert(const std::vector< bitLenInt > &controls, complex topRight, complex bottomLeft, bitLenInt target)
Apply a single bit transformation that reverses bit probability and might effect phase,...
Definition: qtensornetwork.hpp:415
bitCapInt MAll()
Measure permutation state of all coherent bits.
Definition: qtensornetwork.hpp:326
QInterfacePtr layerStack
Definition: qtensornetwork.hpp:38
real1_f SumSqrDiff(QTensorNetworkPtr toCompare)
Definition: qtensornetwork.hpp:206
void Finish()
If asynchronous work is still running, block until it finishes.
Definition: qtensornetwork.hpp:171
bool isFinished()
Returns "false" if asynchronous work is still running, and "true" if all previously dispatched asynch...
Definition: qtensornetwork.hpp:178
void Dispose(bitLenInt start, bitLenInt length)
Minimally decompose a set of contiguous bits from the separably composed unit, and discard the separa...
Definition: qtensornetwork.hpp:277
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: qtensornetwork.hpp:381
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: qtensornetwork.cpp:134
std::vector< QInterfaceEngine > engines
Definition: qtensornetwork.hpp:40
virtual double GetUnitaryFidelity()
When "Schmidt-decomposition rounding parameter" ("SDRP") is being used, starting from initial 1....
Definition: qtensornetwork.hpp:162
std::vector< QCircuitPtr > circuit
Definition: qtensornetwork.hpp:41
real1_f ProbAll(bitCapInt fullRegister)
Direct measure of full permutation probability.
Definition: qtensornetwork.hpp:317
void SetPermutation(bitCapInt initState, complex phaseFac=CMPLX_DEFAULT_ARG)
Set to a specific permutation of all qubits.
Definition: qtensornetwork.hpp:214
void RunAsAmplitudes(Fn fn, const std::set< bitLenInt > &qubits=std::set< bitLenInt >())
Definition: qtensornetwork.hpp:116
void Dump()
If asynchronous work is still running, let the simulator know that it can be aborted.
Definition: qtensornetwork.hpp:180
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: qtensornetwork.hpp:187
Half-precision floating-point type.
Definition: half.hpp:2222
virtual bool M(bitLenInt qubitIndex)
Measurement gate.
Definition: qinterface.hpp:976
virtual void X(bitLenInt qubit)
X gate.
Definition: qinterface.hpp:1054
virtual void U(bitLenInt target, real1_f theta, real1_f phi, real1_f lambda)
General unitary gate.
Definition: rotational.cpp:18
virtual void Swap(bitLenInt qubitIndex1, bitLenInt qubitIndex2)
Swap values of two bits in register.
Definition: gates.cpp:153
Definition: complex16x2simd.hpp:25
void ThrowIfQbIdArrayIsBad(const std::vector< bitLenInt > &controls, const bitLenInt &qubitCount, std::string message)
Definition: qrack_functions.hpp:71
std::complex< half_float::half > complex
Definition: qrack_types.hpp:62
std::shared_ptr< QInterface > QInterfacePtr
Definition: qinterface.hpp:28
constexpr real1_f ZERO_R1_F
Definition: qrack_types.hpp:152
constexpr real1_f FP_NORM_EPSILON_F
Definition: qrack_types.hpp:245
bitCapInt pow2(const bitLenInt &p)
Definition: qrack_functions.hpp:22
std::shared_ptr< QTensorNetwork > QTensorNetworkPtr
Definition: qtensornetwork.hpp:17
const real1 REAL1_DEFAULT_ARG
Definition: qrack_types.hpp:155
const real1 PI_R1
Definition: qrack_types.hpp:158
float real1_f
Definition: qrack_types.hpp:64
QRACK_CONST complex CMPLX_DEFAULT_ARG
Definition: qrack_types.hpp:242
std::shared_ptr< QCircuit > QCircuitPtr
Definition: qcircuit.hpp:570
const real1 REAL1_EPSILON
Definition: qrack_types.hpp:157
QRACK_CONST complex ZERO_CMPLX
Definition: qrack_types.hpp:240
bitLenInt log2(bitCapInt n)
Definition: qrack_functions.hpp:26
half sin(half arg)
Sine function.
Definition: half.hpp:3885
half cos(half arg)
Cosine function.
Definition: half.hpp:3922
#define bitLenInt
Definition: qrack_types.hpp:44
#define qrack_rand_gen_ptr
Definition: qrack_types.hpp:146
#define bitCapInt
Definition: qrack_types.hpp:105