Qrack  9.13
General classical-emulating-quantum development framework
qunitstatevector.hpp
Go to the documentation of this file.
1 //
3 // (C) Daniel Strano and the Qrack contributors 2017-2023. All rights reserved.
4 //
5 // This is a multithreaded, universal quantum register simulation, allowing
6 // (nonphysical) register cloning and direct measurement of probability and
7 // phase, to leverage what advantages classical emulation of qubits can have.
8 //
9 // Licensed under the GNU Lesser General Public License V3.
10 // See LICENSE.md in the project root or https://www.gnu.org/licenses/lgpl-3.0.en.html
11 // for details.
12 
13 #pragma once
14 
15 namespace Qrack {
16 
17 struct QUnitStateVector;
18 typedef std::shared_ptr<QUnitStateVector> QUnitStateVectorPtr;
19 
20 struct IdOffset {
23 
25  {
26  // Intentionally left blank
27  }
28 
30  : id(i)
31  , offset(o)
32  {
33  // Intentionally left blank
34  }
35 };
36 
39  std::map<bitLenInt, IdOffset> idMap;
40  std::vector<std::map<bitCapInt, complex>> amps;
41 
43  const complex& p, const std::map<bitLenInt, IdOffset>& i, const std::vector<std::map<bitCapInt, complex>>& a)
44  : phaseOffset(p)
45  , idMap(i)
46  , amps(a)
47  {
48  // Intentionally left blank
49  }
50 
51  complex get(const bitCapInt& p)
52  {
53  if (p >= pow2(idMap.size())) {
54  throw std::invalid_argument("QUnitStateVector::get() argument out-of-bounds!");
55  }
56 
57  std::map<bitLenInt, bitCapInt> perms;
58  for (auto qid = idMap.begin(); qid != idMap.end(); ++qid) {
59  const size_t i = std::distance(idMap.begin(), qid);
60  if (bi_and_1(p >> i)) {
61  bi_or_ip(&(perms[qid->second.offset]), pow2(qid->second.id));
62  }
63  }
64 
65  complex result = phaseOffset;
66  for (size_t i = 0U; i < amps.size(); ++i) {
67  const auto& found = amps[i].find(perms[i]);
68  if (found == amps[i].end()) {
69  result = ZERO_CMPLX;
70  break;
71  }
72  result *= found->second;
73  if ((2 * norm(result)) <= REAL1_EPSILON) {
74  result = ZERO_CMPLX;
75  break;
76  }
77  }
78 
79  return result;
80  }
81 };
82 
83 } // namespace Qrack
void bi_or_ip(BigInteger *left, const BigInteger &right)
Definition: big_integer.hpp:429
int bi_and_1(const BigInteger &left)
Definition: big_integer.hpp:400
GLOSSARY: bitLenInt - "bit-length integer" - unsigned integer ID of qubit position in register bitCap...
Definition: complex16x2simd.hpp:25
void U(quid sid, bitLenInt q, real1_f theta, real1_f phi, real1_f lambda)
(External API) 3-parameter unitary gate
Definition: wasm_api.cpp:1143
std::complex< real1 > complex
Definition: qrack_types.hpp:128
std::shared_ptr< QUnitStateVector > QUnitStateVectorPtr
Definition: qunitstatevector.hpp:17
bitCapInt pow2(const bitLenInt &p)
Definition: qrack_functions.hpp:136
double norm(const complex2 &c)
Definition: complex16x2simd.hpp:101
QRACK_CONST real1 REAL1_EPSILON
Definition: qrack_types.hpp:200
QRACK_CONST complex ZERO_CMPLX
Definition: qrack_types.hpp:253
#define bitLenInt
Definition: qrack_types.hpp:38
#define bitCapInt
Definition: qrack_types.hpp:62
Definition: qunitstatevector.hpp:20
IdOffset()
Definition: qunitstatevector.hpp:24
IdOffset(bitLenInt i, bitLenInt o)
Definition: qunitstatevector.hpp:29
bitLenInt offset
Definition: qunitstatevector.hpp:22
bitLenInt id
Definition: qunitstatevector.hpp:21
Definition: qunitstatevector.hpp:37
complex phaseOffset
Definition: qunitstatevector.hpp:38
QUnitStateVector(const complex &p, const std::map< bitLenInt, IdOffset > &i, const std::vector< std::map< bitCapInt, complex >> &a)
Definition: qunitstatevector.hpp:42
std::vector< std::map< bitCapInt, complex > > amps
Definition: qunitstatevector.hpp:40
std::map< bitLenInt, IdOffset > idMap
Definition: qunitstatevector.hpp:39
complex get(const bitCapInt &p)
Definition: qunitstatevector.hpp:51