Qrack  9.0
General classical-emulating-quantum development framework
qstabilizer.hpp
Go to the documentation of this file.
1 //
3 // (C) Daniel Strano and the Qrack contributors 2017-2023. All rights reserved.
4 //
5 // Adapted from:
6 //
7 // CHP: CNOT-Hadamard-Phase
8 // Stabilizer Quantum Computer Simulator
9 // by Scott Aaronson
10 // Last modified June 30, 2004
11 //
12 // Thanks to Simon Anders and Andrew Cross for bugfixes
13 //
14 // https://www.scottaaronson.com/chp/
15 //
16 // Daniel Strano and the Qrack contributers appreciate Scott Aaronson's open sharing of the CHP code, and we hope that
17 // vm6502q/qrack is one satisfactory framework by which CHP could be adapted to enter the C++ STL. Our project
18 // philosophy aims to raise the floor of decentralized quantum computing technology access across all modern platforms,
19 // for all people, not commercialization.
20 //
21 // Licensed under the GNU Lesser General Public License V3.
22 // See LICENSE.md in the project root or https://www.gnu.org/licenses/lgpl-3.0.en.html
23 // for details.
24 
25 #pragma once
26 
27 #include "qinterface.hpp"
28 
29 namespace Qrack {
30 
34 
35  AmplitudeEntry(const bitCapInt& p, const complex& a)
36  : permutation(p)
37  , amplitude(a)
38  {
39  }
40 };
41 
42 class QStabilizer;
43 typedef std::shared_ptr<QStabilizer> QStabilizerPtr;
44 
45 class QStabilizer : public QInterface {
46 protected:
47  unsigned rawRandBools;
52 
53  // Phase bits: 0 for +1, 1 for i, 2 for -1, 3 for -i. Normally either 0 or 2.
54  std::vector<uint8_t> r;
55  // Typedef for special type std::vector<bool> compatibility
56  typedef std::vector<bool> BoolVector;
57  // (2n+1)*n matrix for stabilizer/destabilizer x bits (there's one "scratch row" at the bottom)
58  std::vector<BoolVector> x;
59  // (2n+1)*n matrix for z bits
60  std::vector<BoolVector> z;
61 
62  typedef std::function<void(const bitLenInt&)> StabilizerParallelFunc;
63  typedef std::function<void(void)> DispatchFn;
64  void Dispatch(DispatchFn fn) { fn(); }
65 
66  void ParFor(StabilizerParallelFunc fn, std::vector<bitLenInt> qubits);
67 
68  void SetPhaseOffset(real1_f phaseArg)
69  {
70  phaseOffset = (real1)phaseArg;
71  const bool isNeg = phaseOffset < 0;
72  if (isNeg) {
74  }
75  phaseOffset -= (real1)(((size_t)(phaseOffset / (2 * PI_R1))) * (2 * PI_R1));
76  if (phaseOffset > PI_R1) {
77  phaseOffset -= 2 * PI_R1;
78  }
79  if (isNeg) {
81  }
82  }
83 
84 public:
85  QStabilizer(bitLenInt n, bitCapInt perm = 0U, qrack_rand_gen_ptr rgp = nullptr,
86  complex phaseFac = CMPLX_DEFAULT_ARG, bool doNorm = false, bool randomGlobalPhase = true, bool ignored2 = false,
87  int64_t ignored3 = -1, bool useHardwareRNG = true, bool ignored4 = false, real1_f ignored5 = REAL1_EPSILON,
88  std::vector<int64_t> ignored6 = {}, bitLenInt ignored7 = 0U, real1_f ignored8 = FP_NORM_EPSILON_F);
89 
90  ~QStabilizer() { Dump(); }
91 
94 
95  bool isClifford() { return true; };
96  bool isClifford(bitLenInt qubit) { return true; };
97 
99 
101 
103  complex GetPhaseOffset() { return std::polar(ONE_R1, phaseOffset); }
104 
105  void SetPermutation(bitCapInt perm, complex phaseFac = CMPLX_DEFAULT_ARG);
106 
107  void SetRandomSeed(uint32_t seed)
108  {
109  if (rand_generator != NULL) {
110  rand_generator->seed(seed);
111  }
112  }
113 
114  void SetDevice(int64_t dID) {}
115 
116  bool Rand()
117  {
118  if (hardware_rand_generator != NULL) {
119  if (!rawRandBoolsRemaining) {
121  rawRandBoolsRemaining = sizeof(unsigned) * bitsInByte;
122  }
124 
125  return (bool)((rawRandBools >> rawRandBoolsRemaining) & 1U);
126  } else {
127  return (bool)rand_distribution(*rand_generator);
128  }
129  }
130 
131  void Clear()
132  {
133  x.clear();
134  z.clear();
135  r.clear();
137  qubitCount = 0U;
138  maxQPower = 1U;
139  }
140 
141 protected:
143  void rowcopy(const bitLenInt& i, const bitLenInt& k)
144  {
145  if (i == k) {
146  return;
147  }
148 
149  x[i] = x[k];
150  z[i] = z[k];
151  r[i] = r[k];
152  }
154  void rowswap(const bitLenInt& i, const bitLenInt& k)
155  {
156  if (i == k) {
157  return;
158  }
159 
160  std::swap(x[k], x[i]);
161  std::swap(z[k], z[i]);
162  std::swap(r[k], r[i]);
163  }
165  void rowset(const bitLenInt& i, bitLenInt b)
166  {
167  std::fill(x[i].begin(), x[i].end(), false);
168  std::fill(z[i].begin(), z[i].end(), false);
169  r[i] = 0;
170 
171  if (b < qubitCount) {
172  x[i][b] = true;
173  } else {
174  b -= qubitCount;
175  z[i][b] = true;
176  }
177  }
179  void rowmult(const bitLenInt& i, const bitLenInt& k)
180  {
181  r[i] = clifford(i, k);
182  for (bitLenInt j = 0U; j < qubitCount; ++j) {
183  x[i][j] = x[i][j] ^ x[k][j];
184  z[i][j] = z[i][j] ^ z[k][j];
185  }
186  }
188  uint8_t clifford(const bitLenInt& i, const bitLenInt& k);
189 
195  void seed(const bitLenInt& g);
196 
198  AmplitudeEntry getBasisAmp(const real1_f& nrm);
199 
201  void setBasisState(const real1_f& nrm, complex* stateVec);
202 
204  void setBasisState(const real1_f& nrm, QInterfacePtr eng);
205 
207  void setBasisState(const real1_f& nrm, std::map<bitCapInt, complex>& stateMap);
208 
210  void setBasisProb(const real1_f& nrm, real1* outputProbs);
211 
213  real1_f getExpectation(const real1_f& nrm, const std::vector<bitCapInt>& bitPowers,
214  const std::vector<bitCapInt>& perms, bitCapInt offset);
215 
218  const real1_f& nrm, const std::vector<bitCapInt>& bitPowers, const std::vector<real1_f>& weights);
219 
220  void DecomposeDispose(const bitLenInt start, const bitLenInt length, QStabilizerPtr toCopy);
221 
223  QStabilizerPtr toCompare, real1_f error_tol = TRYDECOMPOSE_EPSILON, bool isDiscrete = false);
224 
225 public:
233 
234  bitCapInt PermCount() { return pow2(gaussian()); }
235 
236  void SetQuantumState(const complex* inputState);
238  {
239  throw std::domain_error("QStabilizer::SetAmplitude() not implemented!");
240  }
241 
242  void SetRandGlobalPhase(bool isRand) { randGlobalPhase = isRand; }
243 
245  void CNOT(bitLenInt control, bitLenInt target);
247  void CY(bitLenInt control, bitLenInt target);
249  void CZ(bitLenInt control, bitLenInt target);
251  void AntiCNOT(bitLenInt control, bitLenInt target);
253  void AntiCY(bitLenInt control, bitLenInt target);
255  void AntiCZ(bitLenInt control, bitLenInt target);
257  using QInterface::H;
258  void H(bitLenInt qubitIndex);
260  using QInterface::X;
261  void X(bitLenInt qubitIndex);
263  void Y(bitLenInt qubitIndex);
265  void Z(bitLenInt qubitIndex);
267  void S(bitLenInt qubitIndex);
269  void IS(bitLenInt qubitIndex);
270  // Swap two bits
271  void Swap(bitLenInt qubitIndex1, bitLenInt qubitIndex2);
272  // Swap two bits and apply a phase factor of i if they are different
273  void ISwap(bitLenInt qubitIndex1, bitLenInt qubitIndex2);
274  // Swap two bits and apply a phase factor of -i if they are different
275  void IISwap(bitLenInt qubitIndex1, bitLenInt qubitIndex2);
276 
278  bool ForceM(bitLenInt t, bool result, bool doForce = true, bool doApply = true);
279 
281  void GetQuantumState(complex* stateVec);
282 
284  void GetQuantumState(QInterfacePtr eng);
285 
287  std::map<bitCapInt, complex> GetQuantumState();
288 
290  void GetProbs(real1* outputProbs);
291 
294 
296  std::vector<complex> GetAmplitudes(std::vector<bitCapInt> perms);
297 
300 
303 
306  const std::vector<bitLenInt>& bits, const std::vector<bitCapInt>& perms, bitCapInt offset = 0U);
307 
309  real1_f ExpectationFloatsFactorized(const std::vector<bitLenInt>& bits, const std::vector<real1_f>& weights);
310 
313  real1_f ProbPermRdm(bitCapInt perm, bitLenInt ancillaeStart);
314 
316  real1_f ProbMask(bitCapInt mask, bitCapInt permutation);
317 
321  bool IsSeparableZ(const bitLenInt& target);
325  bool IsSeparableX(const bitLenInt& target);
329  bool IsSeparableY(const bitLenInt& target);
337  uint8_t IsSeparable(const bitLenInt& target);
338 
339  using QInterface::Compose;
340  bitLenInt Compose(QInterfacePtr toCopy) { return Compose(std::dynamic_pointer_cast<QStabilizer>(toCopy)); }
341  bitLenInt Compose(QStabilizerPtr toCopy) { return Compose(toCopy, qubitCount); }
343  {
344  return Compose(std::dynamic_pointer_cast<QStabilizer>(toCopy), start);
345  }
346  bitLenInt Compose(QStabilizerPtr toCopy, bitLenInt start);
348  {
349  DecomposeDispose(start, dest->GetQubitCount(), std::dynamic_pointer_cast<QStabilizer>(dest));
350  }
352  void Dispose(bitLenInt start, bitLenInt length) { DecomposeDispose(start, length, (QStabilizerPtr)NULL); }
353  void Dispose(bitLenInt start, bitLenInt length, bitCapInt ignored)
354  {
355  DecomposeDispose(start, length, (QStabilizerPtr)NULL);
356  }
357  bool CanDecomposeDispose(const bitLenInt start, const bitLenInt length);
358  using QInterface::Allocate;
360  {
361  if (!length) {
362  return start;
363  }
364 
365  if (start > qubitCount) {
366  throw std::out_of_range("QStabilizer::Allocate() cannot start past end of register!");
367  }
368 
369  if (!qubitCount) {
370  SetQubitCount(length);
371  SetPermutation(0U);
372  return 0U;
373  }
374 
375  QStabilizerPtr nQubits = std::make_shared<QStabilizer>(length, 0U, rand_generator, CMPLX_DEFAULT_ARG, false,
376  randGlobalPhase, false, -1, hardware_rand_generator != NULL);
377  return Compose(nQubits, start);
378  }
379 
381  real1_f nrm = REAL1_DEFAULT_ARG, real1_f norm_thresh = REAL1_DEFAULT_ARG, real1_f phaseArg = ZERO_R1_F)
382  {
383  if (!randGlobalPhase) {
384  SetPhaseOffset(phaseOffset + (real1)phaseArg);
385  }
386  }
388  {
389  // Intentionally left blank
390  }
391 
393  {
394  return ApproxCompareHelper(std::dynamic_pointer_cast<QStabilizer>(toCompare));
395  }
397  {
398  return ApproxCompare(std::dynamic_pointer_cast<QStabilizer>(toCompare), error_tol);
399  }
401  {
402  return error_tol >= ApproxCompareHelper(toCompare, error_tol, true);
403  }
405  {
406  return GlobalPhaseCompare(std::dynamic_pointer_cast<QStabilizer>(toCompare), error_tol);
407  }
409  {
410  const AmplitudeEntry thisAmpEntry = GetAnyAmplitude();
411  real1 argDiff = (real1)abs(
412  (std::arg(thisAmpEntry.amplitude) - std::arg(toCompare->GetAmplitude(thisAmpEntry.permutation))) /
413  (2 * PI_R1));
414  argDiff -= (real1)(size_t)argDiff;
415  if (argDiff > (ONE_R1 / 2)) {
416  argDiff -= ONE_R1;
417  }
418  if (FP_NORM_EPSILON >= abs(argDiff)) {
419  return false;
420  }
421  return error_tol >= ApproxCompareHelper(toCompare, error_tol, true);
422  }
423 
424  real1_f Prob(bitLenInt qubit);
425 
426  void Mtrx(const complex* mtrx, bitLenInt target);
427  void Phase(complex topLeft, complex bottomRight, bitLenInt target);
428  void Invert(complex topRight, complex bottomLeft, bitLenInt target);
429  void MCPhase(const std::vector<bitLenInt>& controls, complex topLeft, complex bottomRight, bitLenInt target);
430  void MACPhase(const std::vector<bitLenInt>& controls, complex topLeft, complex bottomRight, bitLenInt target);
431  void MCInvert(const std::vector<bitLenInt>& controls, complex topRight, complex bottomLeft, bitLenInt target);
432  void MACInvert(const std::vector<bitLenInt>& controls, complex topRight, complex bottomLeft, bitLenInt target);
433  void MCMtrx(const std::vector<bitLenInt>& controls, const complex* mtrx, bitLenInt target)
434  {
435  if (IS_NORM_0(mtrx[1U]) && IS_NORM_0(mtrx[2U])) {
436  MCPhase(controls, mtrx[0U], mtrx[3U], target);
437  return;
438  }
439 
440  if (IS_NORM_0(mtrx[0U]) && IS_NORM_0(mtrx[3U])) {
441  MCInvert(controls, mtrx[1U], mtrx[2U], target);
442  return;
443  }
444 
445  throw std::domain_error("QStabilizer::MCMtrx() not implemented for non-Clifford/Pauli cases!");
446  }
447  void MACMtrx(const std::vector<bitLenInt>& controls, const complex* mtrx, bitLenInt target)
448  {
449  if (IS_NORM_0(mtrx[1U]) && IS_NORM_0(mtrx[2U])) {
450  MACPhase(controls, mtrx[0U], mtrx[3U], target);
451  return;
452  }
453 
454  if (IS_NORM_0(mtrx[0U]) && IS_NORM_0(mtrx[3U])) {
455  MACInvert(controls, mtrx[1U], mtrx[2U], target);
456  return;
457  }
458 
459  throw std::domain_error("QStabilizer::MACMtrx() not implemented for non-Clifford/Pauli cases!");
460  }
461  void FSim(real1_f theta, real1_f phi, bitLenInt qubit1, bitLenInt qubit2);
462 
463  bool TrySeparate(const std::vector<bitLenInt>& qubits, real1_f ignored);
464  bool TrySeparate(bitLenInt qubit) { return CanDecomposeDispose(qubit, 1U); }
465  bool TrySeparate(bitLenInt qubit1, bitLenInt qubit2)
466  {
467  if (qubit2 < qubit1) {
468  std::swap(qubit1, qubit2);
469  }
470 
471  Swap(qubit1, 0U);
472  Swap(qubit2, 1U);
473 
474  const bool toRet = CanDecomposeDispose(0U, 2U);
475 
476  Swap(qubit2, 1U);
477  Swap(qubit1, 0U);
478 
479  return toRet;
480  }
481 
482  friend std::ostream& operator<<(std::ostream& os, const QStabilizerPtr s);
483  friend std::istream& operator>>(std::istream& is, const QStabilizerPtr s);
484 };
485 } // namespace Qrack
A "Qrack::QInterface" is an abstract interface exposing qubit permutation state vector with methods t...
Definition: qinterface.hpp:146
bitCapInt maxQPower
Definition: qinterface.hpp:154
virtual bitLenInt Allocate(bitLenInt length)
Allocate new "length" count of |0> state qubits at end of qubit index position.
Definition: qinterface.hpp:434
std::shared_ptr< RdRandom > hardware_rand_generator
Definition: qinterface.hpp:157
virtual bitLenInt Compose(QInterfacePtr toCopy)
Combine another QInterface with this one, after the last bit index of this one.
Definition: qinterface.hpp:338
qrack_rand_gen_ptr rand_generator
Definition: qinterface.hpp:155
bool randGlobalPhase
Definition: qinterface.hpp:149
virtual void SetQubitCount(bitLenInt qb)
Definition: qinterface.hpp:159
std::uniform_real_distribution< real1_s > rand_distribution
Definition: qinterface.hpp:156
bitLenInt qubitCount
Definition: qinterface.hpp:151
Definition: qstabilizer.hpp:45
bitCapInt PermCount()
Definition: qstabilizer.hpp:234
void seed(const bitLenInt &g)
Finds a Pauli operator P such that the basis state P|0...0> occurs with nonzero amplitude in q,...
Definition: qstabilizer.cpp:240
void S(bitLenInt qubitIndex)
Apply a phase gate (|0>->|0>, |1>->i|1>, or "S") to qubit b.
Definition: qstabilizer.cpp:1170
bool TrySeparate(bitLenInt qubit1, bitLenInt qubit2)
Two-qubit TrySeparate()
Definition: qstabilizer.hpp:465
bool CanDecomposeDispose(const bitLenInt start, const bitLenInt length)
Definition: qstabilizer.cpp:1497
void Decompose(bitLenInt start, QInterfacePtr dest)
Minimally decompose a set of contiguous bits from the separably composed unit, into "destination".
Definition: qstabilizer.hpp:347
real1_f ExpectationFloatsFactorized(const std::vector< bitLenInt > &bits, const std::vector< real1_f > &weights)
Get expectation qubits, interpreting each permutation as a floating-point value.
Definition: qstabilizer.cpp:648
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: qstabilizer.cpp:2112
bool GlobalPhaseCompare(QStabilizerPtr toCompare, real1_f error_tol=TRYDECOMPOSE_EPSILON)
Definition: qstabilizer.hpp:408
std::vector< uint8_t > r
Definition: qstabilizer.hpp:54
void CZ(bitLenInt control, bitLenInt target)
Apply a CZ gate with control and target.
Definition: qstabilizer.cpp:882
void ParFor(StabilizerParallelFunc fn, std::vector< bitLenInt > qubits)
Definition: qstabilizer.cpp:58
void setBasisState(const real1_f &nrm, complex *stateVec)
Returns the result of applying the Pauli operator in the "scratch space" of q to |0....
Definition: qstabilizer.cpp:305
real1_f ProbMask(bitCapInt mask, bitCapInt permutation)
Direct measure of masked permutation probability.
Definition: qstabilizer.cpp:730
friend std::ostream & operator<<(std::ostream &os, const QStabilizerPtr s)
Definition: qstabilizer.cpp:2272
void SetQuantumState(const complex *inputState)
Set an arbitrary pure quantum state representation.
Definition: qstabilizer.cpp:1723
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: qstabilizer.cpp:1978
bool TrySeparate(const std::vector< bitLenInt > &qubits, real1_f ignored)
Qrack::QUnit types maintain explicit separation of representations of qubits, which reduces memory us...
Definition: qstabilizer.cpp:2253
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: qstabilizer.hpp:380
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: qstabilizer.cpp:2045
void AntiCY(bitLenInt control, bitLenInt target)
Apply an (anti-)CY gate with control and target.
Definition: qstabilizer.cpp:850
void ISwap(bitLenInt qubitIndex1, bitLenInt qubitIndex2)
Swap values of two bits in register, and apply phase factor of i if bits are different.
Definition: qstabilizer.cpp:969
bool Rand()
Definition: qstabilizer.hpp:116
friend std::istream & operator>>(std::istream &is, const QStabilizerPtr s)
Definition: qstabilizer.cpp:2295
real1_f ProbPermRdm(bitCapInt perm, bitLenInt ancillaeStart)
Under assumption of a QStabilizerHybrid ancillary buffer, trace out the permutation probability of th...
Definition: qstabilizer.cpp:688
QStabilizerPtr CloneEmpty()
void SetDevice(int64_t dID)
Set the device index, if more than one device is available.
Definition: qstabilizer.hpp:114
void SetRandGlobalPhase(bool isRand)
Definition: qstabilizer.hpp:242
void SetPhaseOffset(real1_f phaseArg)
Definition: qstabilizer.hpp:68
unsigned rawRandBoolsRemaining
Definition: qstabilizer.hpp:48
void rowmult(const bitLenInt &i, const bitLenInt &k)
Left-multiply row i by row k - does not change the logical state.
Definition: qstabilizer.hpp:179
unsigned rawRandBools
Definition: qstabilizer.hpp:47
void AntiCNOT(bitLenInt control, bitLenInt target)
Apply an (anti-)CNOT gate with control and target.
Definition: qstabilizer.cpp:790
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: qstabilizer.hpp:387
virtual bitLenInt Compose(QInterfacePtr toCopy)
Combine another QInterface with this one, after the last bit index of this one.
Definition: qinterface.hpp:338
void IS(bitLenInt qubitIndex)
Apply an inverse phase gate (|0>->|0>, |1>->-i|1>, or "S adjoint") to qubit b.
Definition: qstabilizer.cpp:1200
void MCMtrx(const std::vector< bitLenInt > &controls, const complex *mtrx, bitLenInt target)
Apply an arbitrary single bit unitary transformation, with arbitrary control bits.
Definition: qstabilizer.hpp:433
void Y(bitLenInt qubitIndex)
Apply a Pauli Y gate to target.
Definition: qstabilizer.cpp:1124
void rowset(const bitLenInt &i, bitLenInt b)
Sets row i equal to the bth observable (X_1,...X_n,Z_1,...,Z_n)
Definition: qstabilizer.hpp:165
virtual void H(bitLenInt qubit)
Apply a Hadamard gate to target.
Definition: qinterface.hpp:876
bool ForceM(bitLenInt t, bool result, bool doForce=true, bool doApply=true)
Measure qubit t.
Definition: qstabilizer.cpp:1303
bitLenInt gaussian()
Do Gaussian elimination to put the stabilizer generators in the following form: At the top,...
Definition: qstabilizer.cpp:177
bool IsSeparableY(const bitLenInt &target)
Returns "true" if target qubit is a Y basis eigenstate.
Definition: qstabilizer.cpp:1269
AmplitudeEntry GetQubitAmplitude(bitLenInt t, bool m)
Get any single basis state amplitude where qubit "t" has value "m".
Definition: qstabilizer.cpp:573
real1_f Prob(bitLenInt qubit)
Direct measure of bit probability to be in |1> state.
Definition: qstabilizer.cpp:1740
real1_f SumSqrDiff(QInterfacePtr toCompare)
Definition: qstabilizer.hpp:392
bitLenInt Compose(QStabilizerPtr toCopy)
Definition: qstabilizer.hpp:341
std::function< void(void)> DispatchFn
Definition: qstabilizer.hpp:63
void Z(bitLenInt qubitIndex)
Apply a phase gate (|0>->|0>, |1>->-|1>, or "Z") to qubit b.
Definition: qstabilizer.cpp:1145
bitLenInt maxStateMapCacheQubitCount
Definition: qstabilizer.hpp:50
AmplitudeEntry getBasisAmp(const real1_f &nrm)
Helper for setBasisState() and setBasisProb()
Definition: qstabilizer.cpp:271
real1_f ApproxCompareHelper(QStabilizerPtr toCompare, real1_f error_tol=TRYDECOMPOSE_EPSILON, bool isDiscrete=false)
Definition: qstabilizer.cpp:1622
void DecomposeDispose(const bitLenInt start, const bitLenInt length, QStabilizerPtr toCopy)
Definition: qstabilizer.cpp:1549
void SetRandomSeed(uint32_t seed)
Definition: qstabilizer.hpp:107
real1_f ExpectationBitsFactorized(const std::vector< bitLenInt > &bits, const std::vector< bitCapInt > &perms, bitCapInt offset=0U)
Get expectation qubits, interpreting each permutation as an unsigned integer.
Definition: qstabilizer.cpp:609
void Mtrx(const complex *mtrx, bitLenInt target)
Apply an arbitrary single bit unitary transformation.
Definition: qstabilizer.cpp:1750
real1 phaseOffset
Definition: qstabilizer.hpp:49
virtual void X(bitLenInt qubit)
Apply an X (or NOT) gate to target.
Definition: qinterface.hpp:1054
QInterfacePtr Clone()
Clone this QInterface.
Definition: qstabilizer.cpp:74
real1_f getExpectation(const real1_f &nrm, const std::vector< bitCapInt > &bitPowers, const std::vector< bitCapInt > &perms, bitCapInt offset)
Returns the (partial) expectation value from a state vector amplitude.
Definition: qstabilizer.cpp:332
std::vector< bool > BoolVector
Definition: qstabilizer.hpp:56
std::function< void(const bitLenInt &)> StabilizerParallelFunc
Definition: qstabilizer.hpp:62
void SetPermutation(bitCapInt perm, complex phaseFac=CMPLX_DEFAULT_ARG)
Set to a specific permutation of all qubits.
Definition: qstabilizer.cpp:90
bool IsSeparableZ(const bitLenInt &target)
Returns "true" if target qubit is a Z basis eigenstate.
Definition: qstabilizer.cpp:1232
uint8_t IsSeparable(const bitLenInt &target)
Returns: 0 if target qubit is not separable 1 if target qubit is a Z basis eigenstate 2 if target qub...
Definition: qstabilizer.cpp:1285
bool IsSeparableX(const bitLenInt &target)
Returns "true" if target qubit is an X basis eigenstate.
Definition: qstabilizer.cpp:1257
void AntiCZ(bitLenInt control, bitLenInt target)
Apply an (anti-)CZ gate with control and target.
Definition: qstabilizer.cpp:916
bitCapInt GetMaxQPower()
Get the maximum number of basis states, namely for qubits.
Definition: qstabilizer.hpp:100
void Phase(complex topLeft, complex bottomRight, bitLenInt target)
Apply a single bit transformation that only effects phase.
Definition: qstabilizer.cpp:1899
void CNOT(bitLenInt control, bitLenInt target)
Apply a CNOT gate with control and target.
Definition: qstabilizer.cpp:762
std::map< bitCapInt, complex > GetQuantumState()
Convert the state to sparse ket notation.
Definition: qstabilizer.cpp:421
std::vector< BoolVector > x
Definition: qstabilizer.hpp:58
void ResetPhaseOffset()
Definition: qstabilizer.hpp:102
complex GetPhaseOffset()
Definition: qstabilizer.hpp:103
std::vector< complex > GetAmplitudes(std::vector< bitCapInt > perms)
Get a single basis state amplitude.
Definition: qstabilizer.cpp:514
bitLenInt Compose(QInterfacePtr toCopy, bitLenInt start)
Definition: qstabilizer.hpp:342
bool GlobalPhaseCompare(QInterfacePtr toCompare, real1_f error_tol=TRYDECOMPOSE_EPSILON)
Definition: qstabilizer.hpp:404
bool ApproxCompare(QInterfacePtr toCompare, real1_f error_tol=TRYDECOMPOSE_EPSILON)
Compare state vectors approximately, component by component, to determine whether this state vector i...
Definition: qstabilizer.hpp:396
void rowswap(const bitLenInt &i, const bitLenInt &k)
Swaps row i and row k - does not change the logical state.
Definition: qstabilizer.hpp:154
void GetProbs(real1 *outputProbs)
Get all probabilities corresponding to ket notation.
Definition: qstabilizer.cpp:451
bitLenInt Allocate(bitLenInt start, bitLenInt length)
Allocate new "length" count of |0> state qubits at specified qubit index start position.
Definition: qstabilizer.hpp:359
bool isClifford()
Returns "true" if current state is identifiably within the Clifford set, or "false" if it is not or c...
Definition: qstabilizer.hpp:95
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: qstabilizer.cpp:2234
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: qstabilizer.cpp:2173
void CY(bitLenInt control, bitLenInt target)
Apply a CY gate with control and target.
Definition: qstabilizer.cpp:818
bitLenInt Compose(QInterfacePtr toCopy)
Combine another QInterface with this one, after the last bit index of this one.
Definition: qstabilizer.hpp:340
bool ApproxCompare(QStabilizerPtr toCompare, real1_f error_tol=TRYDECOMPOSE_EPSILON)
Definition: qstabilizer.hpp:400
void IISwap(bitLenInt qubitIndex1, bitLenInt qubitIndex2)
Inverse ISwap - Swap values of two bits in register, and apply phase factor of -i if bits are differe...
Definition: qstabilizer.cpp:1008
bool isUnitarityBroken
Definition: qstabilizer.hpp:51
std::vector< BoolVector > z
Definition: qstabilizer.hpp:60
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: qstabilizer.hpp:447
uint8_t clifford(const bitLenInt &i, const bitLenInt &k)
Return the phase (0,1,2,3) when row i is LEFT-multiplied by row k.
Definition: qstabilizer.cpp:132
bitLenInt GetQubitCount()
Get the count of bits in this register.
Definition: qstabilizer.hpp:98
bool TrySeparate(bitLenInt qubit)
Single-qubit TrySeparate()
Definition: qstabilizer.hpp:464
void SetAmplitude(bitCapInt perm, complex amp)
Sets the representational amplitude of a full permutation.
Definition: qstabilizer.hpp:237
void Dispose(bitLenInt start, bitLenInt length, bitCapInt ignored)
Dispose a a contiguous set of qubits that are already in a permutation eigenstate.
Definition: qstabilizer.hpp:353
void Invert(complex topRight, complex bottomLeft, bitLenInt target)
Apply a single bit transformation that reverses bit probability and might effect phase.
Definition: qstabilizer.cpp:1937
AmplitudeEntry GetAnyAmplitude()
Get any single basis state amplitude.
Definition: qstabilizer.cpp:560
void Dispose(bitLenInt start, bitLenInt length)
Minimally decompose a set of contiguous bits from the separably composed unit, and discard the separa...
Definition: qstabilizer.hpp:352
void Swap(bitLenInt qubitIndex1, bitLenInt qubitIndex2)
Swap values of two bits in register.
Definition: qstabilizer.cpp:949
void setBasisProb(const real1_f &nrm, real1 *outputProbs)
Returns the probability from applying the Pauli operator in the "scratch space" of q to |0....
Definition: qstabilizer.cpp:326
void rowcopy(const bitLenInt &i, const bitLenInt &k)
Sets row i equal to row k.
Definition: qstabilizer.hpp:143
QStabilizer(bitLenInt n, bitCapInt perm=0U, qrack_rand_gen_ptr rgp=nullptr, complex phaseFac=CMPLX_DEFAULT_ARG, bool doNorm=false, bool randomGlobalPhase=true, bool ignored2=false, int64_t ignored3=-1, bool useHardwareRNG=true, bool ignored4=false, real1_f ignored5=REAL1_EPSILON, std::vector< int64_t > ignored6={}, bitLenInt ignored7=0U, real1_f ignored8=FP_NORM_EPSILON_F)
Definition: qstabilizer.cpp:39
~QStabilizer()
Definition: qstabilizer.hpp:90
bool isClifford(bitLenInt qubit)
Returns "true" if current qubit state is identifiably within the Clifford set, or "false" if it is no...
Definition: qstabilizer.hpp:96
complex GetAmplitude(bitCapInt perm)
Get a single basis state amplitude.
Definition: qstabilizer.cpp:480
void Dispatch(DispatchFn fn)
Definition: qstabilizer.hpp:64
void Clear()
Definition: qstabilizer.hpp:131
Half-precision floating-point type.
Definition: half.hpp:2222
virtual void H(bitLenInt qubit)
Hadamard gate.
Definition: qinterface.hpp:876
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 Dump()
If asynchronous work is still running, let the simulator know that it can be aborted.
Definition: qinterface.hpp:2588
Definition: complex16x2simd.hpp:25
std::complex< half_float::half > complex
Definition: qrack_types.hpp:62
std::shared_ptr< QInterface > QInterfacePtr
Definition: qinterface.hpp:28
QRACK_CONST real1_f TRYDECOMPOSE_EPSILON
Definition: qrack_types.hpp:244
constexpr real1_f ZERO_R1_F
Definition: qrack_types.hpp:152
constexpr real1_f FP_NORM_EPSILON_F
Definition: qrack_types.hpp:245
const real1 ONE_R1
Definition: qrack_types.hpp:153
half_float::half real1
Definition: qrack_types.hpp:63
QRACK_CONST real1 FP_NORM_EPSILON
Definition: qrack_types.hpp:243
bitCapInt pow2(const bitLenInt &p)
Definition: qrack_functions.hpp:22
const real1 REAL1_DEFAULT_ARG
Definition: qrack_types.hpp:155
const real1 PI_R1
Definition: qrack_types.hpp:158
const real1 ZERO_R1
Definition: qrack_types.hpp:151
float real1_f
Definition: qrack_types.hpp:64
QRACK_CONST complex CMPLX_DEFAULT_ARG
Definition: qrack_types.hpp:242
std::shared_ptr< QStabilizer > QStabilizerPtr
Definition: qstabilizer.hpp:42
const real1 REAL1_EPSILON
Definition: qrack_types.hpp:157
HALF_CONSTEXPR half abs(half arg)
Absolute value.
Definition: half.hpp:2975
#define bitsInByte
Definition: qrack_types.hpp:144
#define bitLenInt
Definition: qrack_types.hpp:44
#define qrack_rand_gen_ptr
Definition: qrack_types.hpp:146
#define bitCapInt
Definition: qrack_types.hpp:105
#define IS_NORM_0(c)
Definition: qrack_types.hpp:27
Definition: qstabilizer.hpp:31
bitCapInt permutation
Definition: qstabilizer.hpp:32
complex amplitude
Definition: qstabilizer.hpp:33
AmplitudeEntry(const bitCapInt &p, const complex &a)
Definition: qstabilizer.hpp:35