QInterface¶
Defined in qinterface.hpp.
This provides a basic interface with a wideranging set of functionality

class QInterface : public Qrack::ParallelFor¶
A “Qrack::QInterface” is an abstract interface exposing qubit permutation state vector with methods to operate on it as by gates and registerlike instructions.
See README.md for an overview of the algorithms Qrack employs.
Subclassed by Qrack::QBdt, Qrack::QBdtHybrid, Qrack::QEngine, Qrack::QStabilizer, Qrack::QStabilizerHybrid, Qrack::QTensorNetwork, Qrack::QUnit, Qrack::QUnitClifford
Creating a QInterface¶
These are the primary implementations of a QInterface
:

enum Qrack::QInterfaceEngine¶
Enumerated list of supported engines.
Use QINTERFACE_OPTIMAL for the best supported engine.
Values:

enumerator QINTERFACE_CPU¶
Create a QEngineCPU leveraging only local CPU and memory resources.

enumerator QINTERFACE_OPENCL¶
Create a QEngineOCL, leveraging OpenCL hardware to increase the speed of certain calculations.

enumerator QINTERFACE_CUDA¶
Create a QEngineCUDA, leveraging CUDA hardware to increase the speed of certain calculations.

enumerator QINTERFACE_HYBRID¶
Create a QHybrid, switching between QEngineCPU and QEngineOCL as efficient.

enumerator QINTERFACE_BDT¶
Create a QBinaryDecisionTree, (CPUbased).

enumerator QINTERFACE_BDT_HYBRID¶
Create a QBinaryDecisionTree, (CPUbased).

enumerator QINTERFACE_STABILIZER¶
Create a QStabilizer, limited to Clifford/Pauli operations, but efficient.

enumerator QINTERFACE_STABILIZER_HYBRID¶
Create a QStabilizerHybrid, switching between a QStabilizer and a QHybrid as efficient.

enumerator QINTERFACE_QPAGER¶
Create a QPager, which breaks up the work of a QEngine into equally sized “pages.”.

enumerator QINTERFACE_QUNIT¶
Create a QUnit, which utilizes other QInterface classes to minimize the amount of work that’s needed for any given operation based on the entanglement of the bits involved.
This, combined with QINTERFACE_OPTIMAL, is the recommended object to use as a library consumer.

enumerator QINTERFACE_QUNIT_MULTI¶
Create a QUnitMulti, which distributes the explicitly separated “shards” of a QUnit across available OpenCL devices.

enumerator QINTERFACE_QUNIT_CLIFFORD¶
Cliffordspecialized QUnit.

enumerator QINTERFACE_TENSOR_NETWORK¶
Circuitsimplification layer, with (optional) recourse to cuTensorNetwork.

enumerator QINTERFACE_OPTIMAL_SCHROEDINGER¶

enumerator QINTERFACE_OPTIMAL_BASE¶

enumerator QINTERFACE_OPTIMAL¶

enumerator QINTERFACE_OPTIMAL_MULTI¶

enumerator QINTERFACE_MAX¶

enumerator QINTERFACE_CPU¶
These enums can be passed to an allocator to create a QInterface
of that specified implementation type:

template<typename ...Ts>
QInterfacePtr Qrack::CreateQuantumInterface(std::vector<QInterfaceEngine> engines, Ts... args)¶
Constructors¶

Qrack::QInterface::QInterface(bitLenInt n, qrack_rand_gen_ptr rgp = nullptr, bool doNorm = false, bool useHardwareRNG = true, bool randomGlobalPhase = true, real1_f norm_thresh = REAL1_EPSILON)¶

inline Qrack::QInterface::QInterface()¶
Default constructor, primarily for protected internal use.
Copying¶

virtual QInterfacePtr Qrack::QInterface::Clone() = 0¶
Clone this QInterface.
Members¶

StateVectorPtr Qrack::QEngineCPU::stateVec¶
Configuration Methods¶

inline virtual bitLenInt Qrack::QInterface::GetQubitCount()¶
Get the count of bits in this register.

inline virtual bitCapInt Qrack::QInterface::GetMaxQPower()¶
Get the maximum number of basis states, namely \( 2^n \) for \( n \) qubits.

inline virtual bool Qrack::QInterface::isBinaryDecisionTree()¶
Returns “true” if current state representation is definitely a binary decision tree, “false” if it is definitely not, or “true” if it cannot be determined.

inline virtual bool Qrack::QInterface::isClifford()¶
Returns “true” if current state is identifiably within the Clifford set, or “false” if it is not or cannot be determined.

inline virtual bool Qrack::QInterface::isClifford(bitLenInt qubit)¶
Returns “true” if current qubit state is identifiably within the Clifford set, or “false” if it is not or cannot be determined.

inline virtual void Qrack::QInterface::SetReactiveSeparate(bool isAggSep)¶
Set reactive separation option (on by default if available)
If reactive separation is available, as in Qrack::QUnit, then turning this option on attempts to moreaggresively recover separability of subsystems. It can either hurt or help performance, though it commonly helps.

inline virtual bool Qrack::QInterface::GetReactiveSeparate()¶
Get reactive separation option.
If reactive separation is available, as in Qrack::QUnit, then turning this option on attempts to moreaggresively recover separability of subsystems. It can either hurt or help performance, though it commonly helps.

virtual void Qrack::QInterface::SetDevice(int64_t dID) = 0¶
Set the device index, if more than one device is available.

inline virtual int64_t Qrack::QInterface::GetDevice()¶
Get the device index.
(“1” is default).

inline bitCapIntOcl Qrack::QInterface::GetMaxSize()¶
Get maximum number of amplitudes that can be allocated on current device.
State Manipulation Methods¶

virtual void Qrack::QInterface::SetPermutation(bitCapInt perm, complex phaseFac = CMPLX_DEFAULT_ARG)¶
Set to a specific permutation of all qubits.

virtual void Qrack::QInterface::SetQuantumState(const complex *inputState) = 0¶
Set an arbitrary pure quantum state representation.
Warning
PSEUDOQUANTUM

inline virtual bitLenInt Qrack::QInterface::Compose(QInterfacePtr toCopy)¶
Combine another QInterface with this one, after the last bit index of this one.
“Compose” combines the quantum description of state of two independent QInterface objects into one object, containing the full permutation basis of the full object. The “inputState” bits are added after the last qubit index of the QInterface
to which we “Compose.” Informally, “Compose” is equivalent to “just setting another group of qubits down
next to the first” without interacting them. Schroedinger’s equation can form a description of state for two independent subsystems at once or “separable quantum subsystems” without interacting them. Once the description of state of the independent systems is combined, we can interact them, and we can describe their entanglements to each other, in which case they are no longer independent. A full entangled description of quantum state is not possible for two independent quantum subsystems until we “Compose” them.
“Compose” multiplies the probabilities of the indepedent permutation states of the two subsystems to find the probabilites of the entire set of combined permutations, by simple combinatorial reasoning. If the probablity of the “lefthand” subsystem being in 00> is 1/4, and the probablity of the “righthand” subsystem being in 101> is 1/8, than the probability of the combined 00101> permutation state is 1/32, and so on for all permutations of the new combined state.
If the programmer doesn’t want to “cheat” quantum mechanically, then the original copy of the state which is duplicated into the larger QInterface should be “thrown away” to satisfy “no clone theorem.” This is not semantically enforced in Qrack, because optimization of an emulator might be acheived by “cloning” “underthehood” while only exposing a quantum mechanically consistent API or instruction set.
Returns the quantum bit offset that the QInterface was appended at, such that bit 5 in toCopy is equal to offset+5 in this object.

virtual bitLenInt Qrack::QInterface::Compose(QInterfacePtr toCopy, bitLenInt start)¶

virtual QInterfacePtr Qrack::QInterface::Decompose(bitLenInt start, bitLenInt length) = 0¶
Schmidt decompose a length of qubits.

virtual void Qrack::QInterface::Decompose(bitLenInt start, QInterfacePtr dest) = 0¶
Minimally decompose a set of contiguous bits from the separably composed unit, into “destination”.
Minimally decompose a set of contigious bits from the separably composed unit. The length of this separable unit is reduced by the length of bits decomposed, and the bits removed are output in the destination QInterface pointer. The destination object must be initialized to the correct number of bits, in 0 permutation state. For quantum mechanical accuracy, the bit set removed and the bit set left behind should be quantum mechanically “separable.”
Like how “Compose” is like “just setting another group of qubits down
next to the first,”
then “Decompose” is like “just moving a few qubits
away from the rest.” Schroedinger’s equation does not require bits to be explicitly interacted in order to describe their permutation basis, and the descriptions of state of
separable subsystems, those which are not entangled with other subsystems, are just as easily removed from the description of state. (This is equivalent to a “Schmidt decomposition.”)If we have for example 5 qubits, and we wish to separate into “left” and “right” subsystems of 3 and 2 qubits, we sum probabilities of one permutation of the “left” three over ALL permutations of the “right” two, for all permutations, and vice versa, like so:
\( P(1000>xy>) = P(1000 00>) + P(1000 10>) + P(1000 01>) + P(1000 11>). \)
If the subsystems are not “separable,” i.e. if they are entangled, this operation is not wellmotivated, and its output is not necessarily defined. (The summing of probabilities over permutations of subsytems will be performed as described above, but this is not quantum mechanically meaningful.) To ensure that the subsystem is “separable,” i.e. that it has no entanglements to other subsystems in the QInterface, it can be measured with M(), or else all qubits other than the subsystem can be measured.

virtual void Qrack::QInterface::Dispose(bitLenInt start, bitLenInt length) = 0¶
Minimally decompose a set of contiguous bits from the separably composed unit, and discard the separable bits from index “start” for “length.”.
Minimally decompose a set of contigious bits from the separably composed unit. The length of this separable unit is reduced by the length of bits decomposed, and the bits removed are output in the destination QInterface pointer. The destination object must be initialized to the correct number of bits, in 0 permutation state. For quantum mechanical accuracy, the bit set removed and the bit set left behind should be quantum mechanically “separable.”
Like how “Compose” is like “just setting another group of qubits down
next to the first,”
then “Decompose” is like “just moving a few qubits
away from the rest.” Schroedinger’s equation does not require bits to be explicitly interacted in order to describe their permutation basis, and the descriptions of state of
separable subsystems, those which are not entangled with other subsystems, are just as easily removed from the description of state. (This is equivalent to a “Schmidt decomposition.”)If we have for example 5 qubits, and we wish to separate into “left” and “right” subsystems of 3 and 2 qubits, we sum probabilities of one permutation of the “left” three over ALL permutations of the “right” two, for all permutations, and vice versa, like so:
\( P(1000>xy>) = P(1000 00>) + P(1000 10>) + P(1000 01>) + P(1000 11>). \)
If the subsystems are not “separable,” i.e. if they are entangled, this operation is not wellmotivated, and its output is not necessarily defined. (The summing of probabilities over permutations of subsytems will be performed as described above, but this is not quantum mechanically meaningful.) To ensure that the subsystem is “separable,” i.e. that it has no entanglements to other subsystems in the QInterface, it can be measured with M(), or else all qubits other than the subsystem can be measured.

virtual void Qrack::QInterface::Dispose(bitLenInt start, bitLenInt length, bitCapInt disposedPerm) = 0¶
Dispose a a contiguous set of qubits that are already in a permutation eigenstate.

virtual real1_f Qrack::QInterface::Prob(bitLenInt qubitIndex) = 0¶
Direct measure of bit probability to be in 1> state.
Warning
PSEUDOQUANTUM

inline virtual real1_f Qrack::QInterface::ProbAll(bitCapInt fullRegister)¶
Direct measure of full permutation probability.
Warning
PSEUDOQUANTUM

virtual real1_f Qrack::QInterface::ProbReg(bitLenInt start, bitLenInt length, bitCapInt permutation)¶
Direct measure of register permutation probability.
Returns probability of permutation of the register.
Warning
PSEUDOQUANTUM

virtual real1_f Qrack::QInterface::ProbMask(bitCapInt mask, bitCapInt permutation)¶
Direct measure of masked permutation probability.
Returns probability of permutation of the mask.
“mask” masks the bits to check the probability of. “permutation” sets the 0 or 1 value for each bit in the mask. Bits which are set in the mask can be set to 0 or 1 in the permutation, while reset bits in the mask should be 0 in the permutation.
Warning
PSEUDOQUANTUM

virtual void Qrack::QInterface::ProbMaskAll(bitCapInt mask, real1 *probsArray)¶
Direct measure of masked permutation probability.
“mask” masks the bits to check the probability of. The probabilities of all permutations of the masked bits, from left/low to right/high are returned in the “probsArray” argument.
Warning
PSEUDOQUANTUM

virtual void Qrack::QInterface::ProbBitsAll(const std::vector<bitLenInt> &bits, real1 *probsArray)¶
Direct measure of listed permutation probability.
The probabilities of all included permutations of bits, with bits valued from low to high as the order of the “bits” array parameter argument, are returned in the “probsArray” parameter.
Warning
PSEUDOQUANTUM

virtual void Qrack::QInterface::GetProbs(real1 *outputProbs) = 0¶
Get the pure quantum state representation.
Warning
PSEUDOQUANTUM

inline virtual real1_f Qrack::QInterface::ExpectationBitsAll(const std::vector<bitLenInt> &bits, bitCapInt offset = 0U)¶
Get permutation expectation value of bits.
The permutation expectation value of all included bits is returned, with bits valued from low to high as the order of the “bits” array parameter argument.
Warning
PSEUDOQUANTUM

virtual void Qrack::QInterface::Swap(bitLenInt qubitIndex1, bitLenInt qubitIndex2)¶
Swap values of two bits in register.
Warning
doxygenfunction: Unable to resolve function “Qrack::QInterface::Swap” with arguments (bitLenInt, bitLenInt, bitLenInt) in doxygen xml output for project “qrack” from directory: /tmp/qrack/doc/xml. Potential matches:
 void Swap(bitLenInt qubitIndex1, bitLenInt qubitIndex2)

virtual void Qrack::QInterface::ISwap(bitLenInt qubitIndex1, bitLenInt qubitIndex2)¶
Swap values of two bits in register, and apply phase factor of i if bits are different.
Warning
doxygenfunction: Unable to resolve function “Qrack::QInterface::ISwap” with arguments (bitLenInt, bitLenInt, bitLenInt) in doxygen xml output for project “qrack” from directory: /tmp/qrack/doc/xml. Potential matches:
 void ISwap(bitLenInt qubitIndex1, bitLenInt qubitIndex2)

virtual void Qrack::QInterface::SqrtSwap(bitLenInt qubitIndex1, bitLenInt qubitIndex2)¶
Square root of Swap gate.
Warning
doxygenfunction: Unable to resolve function “Qrack::QInterface::SqrtSwap” with arguments (bitLenInt, bitLenInt, bitLenInt) in doxygen xml output for project “qrack” from directory: /tmp/qrack/doc/xml. Potential matches:
 void SqrtSwap(bitLenInt qubitIndex1, bitLenInt qubitIndex2)

virtual void Qrack::QInterface::CSwap(const std::vector<bitLenInt> &controls, bitLenInt qubit1, bitLenInt qubit2)¶
Apply a swap with arbitrary control bits.

virtual void Qrack::QInterface::AntiCSwap(const std::vector<bitLenInt> &controls, bitLenInt qubit1, bitLenInt qubit2)¶
Apply a swap with arbitrary (anti) control bits.

virtual void Qrack::QInterface::CSqrtSwap(const std::vector<bitLenInt> &controls, bitLenInt qubit1, bitLenInt qubit2)¶
Apply a square root of swap with arbitrary control bits.

virtual void Qrack::QInterface::AntiCSqrtSwap(const std::vector<bitLenInt> &controls, bitLenInt qubit1, bitLenInt qubit2)¶
Apply a square root of swap with arbitrary (anti) control bits.

virtual void Qrack::QInterface::FSim(real1_f theta, real1_f phi, bitLenInt qubitIndex1, bitLenInt qubitIndex2) = 0¶
The 2qubit “fSim” gate, (useful in the simulation of particles with fermionic statistics)
Warning
doxygenfunction: Unable to resolve function “Qrack::QInterface::FSim” with arguments (real1_f, real1_f, bitLenInt, bitLenInt, bitLenInt) in doxygen xml output for project “qrack” from directory: /tmp/qrack/doc/xml. Potential matches:
 void FSim(real1_f theta, real1_f phi, bitLenInt qubitIndex1, bitLenInt qubitIndex2) = 0

virtual void Qrack::QInterface::UniformlyControlledRY(const std::vector<bitLenInt> &controls, bitLenInt qubitIndex, real1 const *angles)¶
Apply a “uniformly controlled” rotation of a bit around the Pauli Y axis.
Uniformly controlled y axis rotation gate  Rotates as e^(i*\theta_k/2) around Pauli y axis for each permutation “k” of the control bits.
(See https://arxiv.org/abs/quantph/0312218)
A different rotation angle is associated with each permutation of the control bits. The first control bit index in the “controls” array is the least significant bit of the permutation, proceeding to the most significant bit. “angles” is an array where each subsequent component is rotation angle associated with the next permutation of the control bits, starting from 0. All combinations of control bits apply one of rotation angles. For k control bits, there are therefore 2^k real components in “angles.”

virtual void Qrack::QInterface::UniformlyControlledRZ(const std::vector<bitLenInt> &controls, bitLenInt qubitIndex, real1 const *angles)¶
Apply a “uniformly controlled” rotation of a bit around the Pauli Z axis.
Uniformly controlled z axis rotation gate  Rotates as e^(i*\theta_k/2) around Pauli z axis for each permutation “k” of the control bits.
(See https://arxiv.org/abs/quantph/0312218)
A different rotation angle is associated with each permutation of the control bits. The first control bit index in the “controls” array is the least significant bit of the permutation, proceeding to the most significant bit. “angles” is an array where each subsequent component is rotation angle associated with the next permutation of the control bits, starting from 0. All combinations of control bits apply one of rotation angles. For k control bits, there are therefore 2^k real components in “angles.”

inline virtual void Qrack::QInterface::Reverse(bitLenInt first, bitLenInt last)¶
Reverse all of the bits in a sequence.

inline virtual bool Qrack::QInterface::TrySeparate(bitLenInt qubit)¶
Singlequbit TrySeparate()

inline virtual bool Qrack::QInterface::TrySeparate(bitLenInt qubit1, bitLenInt qubit2)¶
Twoqubit TrySeparate()

virtual bool Qrack::QInterface::TryDecompose(bitLenInt start, QInterfacePtr dest, real1_f error_tol = TRYDECOMPOSE_EPSILON)¶

virtual std::map<bitCapInt, int> Qrack::QInterface::MultiShotMeasureMask(const std::vector<bitCapInt> &qPowers, unsigned shots)¶
Statistical measure of masked permutation probability.
“qPowers” contains powers of 2^n, each representing QInterface bit “n.” The order of these values defines a mask for the result bitCapInt, of 2^0 ~ qPowers[0U] to 2^(qPowerCount  1) ~ qPowers[qPowerCount  1], in contiguous ascending order. “shots” specifies the number of samples to take as if totally repreparing the premeasurement state. This method returns a dictionary with keys, which are the (maskedorder) measurement results, and values, which are the number of “shots” that produced that particular measurement result. This method does not “collapse” the state of this QInterface. (The idea is to efficiently simulate a potentially statistically random sample of multiple repreparations of the state right before measurement, and to collect random measurement resutls, without forcing the user to reprepare or “clone” the state.)
Warning
PSEUDOQUANTUM

virtual void Qrack::QInterface::MultiShotMeasureMask(const std::vector<bitCapInt> &qPowers, unsigned shots, unsigned long long *shotsArray)¶
Statistical measure of masked permutation probability (returned as array)
Same
Qrack::MultiShotMeasureMask()
, except the shots are returned as an array.Warning
PSEUDOQUANTUM

inline virtual bool Qrack::QInterface::ApproxCompare(QInterfacePtr toCompare, real1_f error_tol = TRYDECOMPOSE_EPSILON)¶
Compare state vectors approximately, component by component, to determine whether this state vector is the same as the target.
Warning
PSEUDOQUANTUM

virtual void Qrack::QInterface::TimeEvolve(Hamiltonian h, real1_f timeDiff)¶
To define a Hamiltonian, give a vector of controlled single bit gates (“HamiltonianOp” instances) that are applied by leftmultiplication in lowtohigh vector index order on the state vector.
As a general point of linear algebra, where A and B are linear operators,
\[\begin{equation}e^{i (A + B) t} = e^{i A t} e^{i B t} \end{equation}\]might NOT hold, if the operators A and B do not commute. As a rule of thumb, A will commute with B at least in the case that A and B act on entirely different sets of qubits. However, for defining the intended Hamiltonian, the programmer can be guaranteed that the exponential factors will be applied righttoleft, by left multiplication, in the order\[\begin{equation} e^{i H_{N  1} t} e^{i H_{N  2} t} \ldots e^{i H_0 t} \left\psi \rangle\right. .\end{equation}\](For example, if A and B are single bit gates acting on the same bit, form their composition into one gate by the intended righttoleft fusion and apply them as a single HamiltonianOp.)Warning
Hamiltonian components might not commute.
Quantum Gates¶
Note
Most gates offer both a singlebit version taking just the index to the qubit, as well as a registerspanning variant for convienence and performance that performs the gate across a sequence of bits.
Note
Qrack::QInterface also offers arithmetic logic unit (ALU) gates. See the Doxygen.
Single Gates¶
Warning
doxygenfunction: Unable to resolve function “Qrack::QInterface::Mtrx” with arguments (complex const*, bitLenInt) in doxygen xml output for project “qrack” from directory: /tmp/qrack/doc/xml. Potential matches:
 void Mtrx(const complex *mtrx, bitLenInt qubitIndex) = 0
Warning
doxygenfunction: Unable to resolve function “Qrack::QInterface::MCMtrx” with arguments (const std::vector<bitLenInt>&, complex const*, bitLenInt) in doxygen xml output for project “qrack” from directory: /tmp/qrack/doc/xml. Potential matches:
 void MCMtrx(const std::vector<bitLenInt> &controls, const complex *mtrx, bitLenInt target) = 0
Warning
doxygenfunction: Unable to resolve function “Qrack::QInterface::MACMtrx” with arguments (const std::vector<bitLenInt>&, complex const*, bitLenInt) in doxygen xml output for project “qrack” from directory: /tmp/qrack/doc/xml. Potential matches:
 void MACMtrx(const std::vector<bitLenInt> &controls, const complex *mtrx, bitLenInt target)

inline virtual void Qrack::QInterface::Phase(const complex topLeft, const complex bottomRight, bitLenInt qubitIndex)¶
Apply a single bit transformation that only effects phase.

inline virtual void Qrack::QInterface::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.

inline virtual void Qrack::QInterface::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.

inline virtual void Qrack::QInterface::Invert(const complex topRight, const complex bottomLeft, bitLenInt qubitIndex)¶
Apply a single bit transformation that reverses bit probability and might effect phase.

inline virtual void Qrack::QInterface::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, with arbitrary control bits.

inline virtual void Qrack::QInterface::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, with arbitrary (anti)control bits.

virtual void Qrack::QInterface::AND(bitLenInt inputBit1, bitLenInt inputBit2, bitLenInt outputBit)¶
Quantum analog of classical “AND” gate.
(Assumes the outputBit is in the 0 state)

virtual void Qrack::QInterface::CLAND(bitLenInt inputQBit, bool inputClassicalBit, bitLenInt outputBit)¶
Quantum analog of classical “AND” gate.
Takes one qubit input and one classical bit input. (Assumes the outputBit is in the 0 state)

virtual void Qrack::QInterface::OR(bitLenInt inputBit1, bitLenInt inputBit2, bitLenInt outputBit)¶
Quantum analog of classical “OR” gate.
(Assumes the outputBit is in the 0 state)

virtual void Qrack::QInterface::CLOR(bitLenInt inputQBit, bool inputClassicalBit, bitLenInt outputBit)¶
Quantum analog of classical “OR” gate.
Takes one qubit input and one classical bit input. (Assumes the outputBit is in the 0 state)

virtual void Qrack::QInterface::XOR(bitLenInt inputBit1, bitLenInt inputBit2, bitLenInt outputBit)¶
Quantum analog of classical “XOR” gate.
(Assumes the outputBit is in the 0 state)

virtual void Qrack::QInterface::CLXOR(bitLenInt inputQBit, bool inputClassicalBit, bitLenInt outputBit)¶
Quantum analog of classical “XOR” gate.
Takes one qubit input and one classical bit input. (Assumes the outputBit is in the 0 state)

inline virtual bool Qrack::QInterface::M(bitLenInt qubitIndex)¶
Measurement gate.
Measures the qubit at “qubitIndex” and returns either “true” or “false.” (This “gate” breaks unitarity.)
All physical evolution of a quantum state should be “unitary,” except measurement. Measurement of a qubit “collapses” the quantum state into either only permutation states consistent with a 0> state for the bit, or else only permutation states consistent with a 1> state for the bit. Measurement also effectively multiplies the overall quantum state vector of the system by a random phase factor, equiprobable over all possible phase angles.
Effectively, when a bit measurement is emulated, Qrack calculates the norm of all permutation state components, to find their respective probabilities. The probabilities of all states in which the measured bit is “0” can be summed to give the probability of the bit being “0,” and separately the probabilities of all states in which the measured bit is “1” can be summed to give the probability of the bit being “1.” To simulate measurement, a random float between 0 and 1 is compared to the sum of the probability of all permutation states in which the bit is equal to “1”. Depending on whether the random float is higher or lower than the probability, the qubit is determined to be either 0> or 1>, (up to phase). If the bit is determined to be 1>, then all permutation eigenstates in which the bit would be equal to 0> have their probability set to zero, and vice versa if the bit is determined to be 0>. Then, all remaining permutation states with nonzero probability are linearly rescaled so that the total probability of all permutation states is again “normalized” to exactly 100% or 1, (within double precision rounding error). Physically, the act of measurement should introduce an overall random phase factor on the state vector, which is emulated by generating another constantly distributed random float to select a phase angle between 0 and 2 * Pi.
Measurement breaks unitary evolution of state. All quantum gates except measurement should generally act as a unitary matrix on a permutation state vector. (Note that Boolean comparison convenience methods in Qrack such as “AND,” “OR,” and “XOR” employ the measurement operation in the act of first clearing output bits before filling them with the result of comparison, and these convenience methods therefore break unitary evolution of state, but in a physically realistic way. Comparable unitary operations would be performed with a combination of X and CCNOT gates, also called “Toffoli” gates, but the output bits would have to be assumed to be in a known fixed state, like all 0>, ahead of time to produce unitary logical comparison operations.)

virtual bool Qrack::QInterface::ForceM(bitLenInt qubit, bool result, bool doForce = true, bool doApply = true) = 0¶
Act as if is a measurement was applied, except force the (usually random) result.
Warning
PSEUDOQUANTUM
Warning
doxygenfunction: Unable to resolve function “Qrack::QInterface::U” with arguments (bitLenInt, bitLenInt, real1_f, real1_f, real1_f) in doxygen xml output for project “qrack” from directory: /tmp/qrack/doc/xml. Potential matches:
 void U(bitLenInt target, real1_f theta, real1_f phi, real1_f lambda)
Warning
doxygenfunction: Unable to resolve function “Qrack::QInterface::U2” with arguments (bitLenInt, bitLenInt, real1_f, real1_f) in doxygen xml output for project “qrack” from directory: /tmp/qrack/doc/xml. Potential matches:
 void U2(bitLenInt target, real1_f phi, real1_f lambda)

inline virtual void Qrack::QInterface::H(bitLenInt qubit)¶
Hadamard gate.
Applies a Hadamard gate on qubit at “qubitIndex.”

inline virtual void Qrack::QInterface::X(bitLenInt qubit)¶
X gate.
Applies the Pauli “X” operator to the qubit at “qubitIndex.” The Pauli “X” operator is equivalent to a logical “NOT.”

inline virtual void Qrack::QInterface::Y(bitLenInt qubit)¶
Y gate.
Applies the Pauli “Y” operator to the qubit at “qubitIndex.” The Pauli “Y” operator is similar to a logical “NOT” with permutation phase. effects.

inline virtual void Qrack::QInterface::Z(bitLenInt qubit)¶
Z gate.
Applies the Pauli “Z” operator to the qubit at “qubitIndex.” The Pauli “Z” operator reverses the phase of 1> and leaves 0> unchanged.

inline virtual void Qrack::QInterface::S(bitLenInt qubit)¶
S gate.
Applies a 1/4 phase rotation to the qubit at “qubitIndex.”

inline virtual void Qrack::QInterface::IS(bitLenInt qubit)¶
Inverse S gate.
Applies an inverse 1/4 phase rotation to the qubit at “qubitIndex.”

inline virtual void Qrack::QInterface::SH(bitLenInt qubit)¶
Ybasis transformation gate.
Converts from Pauli Z basis to Y, (via H then S gates).

inline virtual void Qrack::QInterface::HIS(bitLenInt qubit)¶
Ybasis (inverse) transformation gate.
Converts from Pauli Y basis to Z, (via IS then H gates).

inline virtual void Qrack::QInterface::T(bitLenInt qubit)¶
T gate.
Applies a 1/8 phase rotation to the qubit at “qubitIndex.”

inline virtual void Qrack::QInterface::IT(bitLenInt qubit)¶
Inverse T gate.
Applies an inverse 1/8 phase rotation to the qubit at “qubitIndex.”

inline virtual void Qrack::QInterface::SqrtX(bitLenInt qubit)¶
Square root of X gate.
Applies the square root of the Pauli “X” operator to the qubit at “qubitIndex.” The Pauli “X” operator is equivalent to a logical “NOT.”

inline virtual void Qrack::QInterface::ISqrtX(bitLenInt qubit)¶
Inverse square root of X gate.
Applies the (by convention) inverse square root of the Pauli “X” operator to the qubit at “qubitIndex.” The Pauli “X” operator is equivalent to a logical “NOT.”

inline virtual void Qrack::QInterface::SqrtY(bitLenInt qubit)¶
Square root of Y gate.
Applies the square root of the Pauli “Y” operator to the qubit at “qubitIndex.” The Pauli “Y” operator is similar to a logical “NOT” with permutation phase effects.

inline virtual void Qrack::QInterface::ISqrtY(bitLenInt qubit)¶
Inverse square root of Y gate.
Applies the (by convention) inverse square root of the Pauli “Y” operator to the qubit at “qubitIndex.” The Pauli “Y” operator is similar to a logical “NOT” with permutation phase effects.

inline virtual void Qrack::QInterface::SqrtH(bitLenInt qubit)¶
Square root of Hadamard gate.
Applies the square root of the Hadamard gate on qubit at “qubitIndex.”

inline virtual void Qrack::QInterface::PhaseRootN(bitLenInt n, bitLenInt qubit)¶
“PhaseRootN” gate
Applies a 1/(2^N) phase rotation to the qubit at “qubitIndex.”

inline virtual void Qrack::QInterface::IPhaseRootN(bitLenInt n, bitLenInt qubit)¶
Inverse “PhaseRootN” gate.
Applies an inverse 1/(2^N) phase rotation to the qubit at “qubitIndex.”

inline virtual void Qrack::QInterface::CPhaseRootN(bitLenInt n, bitLenInt control, bitLenInt target)¶
Controlled “PhaseRootN” gate.
If the “control” bit is set to 1, then the “PhaseRootN” gate is applied to “target.”

inline virtual void Qrack::QInterface::CIPhaseRootN(bitLenInt n, bitLenInt control, bitLenInt target)¶
Controlled inverse “PhaseRootN” gate.
If the “control” bit is set to 1, then the inverse “PhaseRootN” gate is applied to “target.”

inline virtual void Qrack::QInterface::CNOT(bitLenInt control, bitLenInt target)¶
Controlled NOT gate.
If the control is set to 1, the target bit is NOTed or Xed.

inline virtual void Qrack::QInterface::AntiCNOT(bitLenInt control, bitLenInt target)¶
Anti controlled NOT gate.
If the control is set to 0, the target bit is NOTed or Xed.

inline virtual void Qrack::QInterface::CCNOT(bitLenInt control1, bitLenInt control2, bitLenInt target)¶
Doublycontrolled NOT gate.
If both controls are set to 1, the target bit is NOTed or Xed.

inline virtual void Qrack::QInterface::AntiCCNOT(bitLenInt control1, bitLenInt control2, bitLenInt target)¶
Anti doublycontrolled NOT gate.
If both controls are set to 0, the target bit is NOTed or Xed.

inline virtual void Qrack::QInterface::CY(bitLenInt control, bitLenInt target)¶
Controlled Y gate.
If the “control” bit is set to 1, then the Pauli “Y” operator is applied to “target.”

inline virtual void Qrack::QInterface::CZ(bitLenInt control, bitLenInt target)¶
Controlled Z gate.
If the “control” bit is set to 1, then the Pauli “Z” operator is applied to “target.”

virtual void Qrack::QInterface::RT(real1_f radians, bitLenInt qubitIndex)¶
Phase shift gate.
“Phase shift gate”  Rotates as e^(i*\theta/2) around 1> state
Rotates as \( e^{i \theta/2} \) around 1> state

virtual void Qrack::QInterface::RX(real1_f radians, bitLenInt qubitIndex)¶
X axis rotation gate.
x axis rotation gate  Rotates as e^(i*\theta/2) around Pauli x axis
Rotates as \( e^{i \theta/2} \) around Pauli X axis

virtual void Qrack::QInterface::RY(real1_f radians, bitLenInt qubitIndex)¶
Y axis rotation gate.
y axis rotation gate  Rotates as e^(i*\theta/2) around Pauli y axis
Rotates as \( e^{i \theta/2} \) around Pauli y axis.

virtual void Qrack::QInterface::RZ(real1_f radians, bitLenInt qubitIndex)¶
Z axis rotation gate.
z axis rotation gate  Rotates as e^(i*\theta/2) around Pauli z axis
Rotates as \( e^{i*\theta/2} \) around Pauli Z axis.

virtual void Qrack::QInterface::CRZ(real1_f radians, bitLenInt control, bitLenInt target)¶
Controlled Z axis rotation gate.
Controlled z axis rotation  if control bit is true, rotates as e^(i*\theta) around Pauli z axis.
If “control” is set to 1, rotates as \( e^{i \theta/2} \) around Pauli Zaxis.
Warning
doxygenfunction: Unable to resolve function “Qrack::QInterface::UniformlyControlledSingleBit” with arguments (const std::vector<bitLenInt>&, bitLenInt, complex const*) in doxygen xml output for project “qrack” from directory: /tmp/qrack/doc/xml. Potential matches:
 void UniformlyControlledSingleBit(const std::vector<bitLenInt> &controls, bitLenInt qubitIndex, const complex *mtrxs)
 void UniformlyControlledSingleBit(const std::vector<bitLenInt> &controls, bitLenInt qubitIndex, const complex *mtrxs, const std::vector<bitCapInt> &mtrxSkipPowers, bitCapInt mtrxSkipValueMask)
Warning
doxygenfunction: Unable to resolve function “Qrack::QInterface::UniformlyControlledSingleBit” with arguments (const std::vector<bitLenInt>&, bitLenInt, complex const*, const std::vector<bitCapInt>&, bitCapInt) in doxygen xml output for project “qrack” from directory: /tmp/qrack/doc/xml. Potential matches:
 void UniformlyControlledSingleBit(const std::vector<bitLenInt> &controls, bitLenInt qubitIndex, const complex *mtrxs)
 void UniformlyControlledSingleBit(const std::vector<bitLenInt> &controls, bitLenInt qubitIndex, const complex *mtrxs, const std::vector<bitCapInt> &mtrxSkipPowers, bitCapInt mtrxSkipValueMask)

virtual void Qrack::QInterface::UniformlyControlledRY(const std::vector<bitLenInt> &controls, bitLenInt qubitIndex, real1 const *angles)
Apply a “uniformly controlled” rotation of a bit around the Pauli Y axis.
Uniformly controlled y axis rotation gate  Rotates as e^(i*\theta_k/2) around Pauli y axis for each permutation “k” of the control bits.
(See https://arxiv.org/abs/quantph/0312218)
A different rotation angle is associated with each permutation of the control bits. The first control bit index in the “controls” array is the least significant bit of the permutation, proceeding to the most significant bit. “angles” is an array where each subsequent component is rotation angle associated with the next permutation of the control bits, starting from 0. All combinations of control bits apply one of rotation angles. For k control bits, there are therefore 2^k real components in “angles.”

virtual void Qrack::QInterface::UniformlyControlledRZ(const std::vector<bitLenInt> &controls, bitLenInt qubitIndex, real1 const *angles)
Apply a “uniformly controlled” rotation of a bit around the Pauli Z axis.
Uniformly controlled z axis rotation gate  Rotates as e^(i*\theta_k/2) around Pauli z axis for each permutation “k” of the control bits.
(See https://arxiv.org/abs/quantph/0312218)
A different rotation angle is associated with each permutation of the control bits. The first control bit index in the “controls” array is the least significant bit of the permutation, proceeding to the most significant bit. “angles” is an array where each subsequent component is rotation angle associated with the next permutation of the control bits, starting from 0. All combinations of control bits apply one of rotation angles. For k control bits, there are therefore 2^k real components in “angles.”
Arithmetic¶
Qrack can build with quantum arithmetic methods, using CMake option ``DENABLE_ALU=ON`.

virtual void Qrack::QInterface::INC(bitCapInt toAdd, bitLenInt start, bitLenInt length)¶
Add integer (without sign)

virtual void Qrack::QInterface::DEC(bitCapInt toSub, bitLenInt start, bitLenInt length)¶
Subtract classical integer (without sign)
Subtract integer (without sign)

virtual void Qrack::QInterface::CINC(bitCapInt toAdd, bitLenInt inOutStart, bitLenInt length, const std::vector<bitLenInt> &controls)¶
Add integer (without sign, with controls)

virtual void Qrack::QInterface::CDEC(bitCapInt toSub, bitLenInt inOutStart, bitLenInt length, const std::vector<bitLenInt> &controls)¶
Subtract classical integer (without sign, with controls)
Subtract integer (without sign, with controls)

virtual void Qrack::QInterface::INCC(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)¶
Add integer (without sign, with carry)

virtual void Qrack::QInterface::INCS(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex)¶
Add a classical integer to the register, with sign and without carry.

virtual void Qrack::QInterface::DECS(bitCapInt toSub, bitLenInt start, bitLenInt length, bitLenInt overflowIndex)¶
Subtract a classical integer from the register, with sign and without carry.
Subtract an integer from the register, with sign and without carry.
Because the register length is an arbitrary number of bits, the sign bit position on the integer to add is variable. Hence, the integer to add is specified as cast to an unsigned format, with the sign bit assumed to be set at the appropriate position before the cast.

virtual void Qrack::QInterface::MULModNOut(bitCapInt toMul, bitCapInt modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length)¶
Multiplication modulo N by integer, (out of place)

virtual void Qrack::QInterface::IMULModNOut(bitCapInt toMul, bitCapInt modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length)¶
Inverse of multiplication modulo N by integer, (out of place)

virtual void Qrack::QInterface::CMULModNOut(bitCapInt toMul, bitCapInt modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length, const std::vector<bitLenInt> &controls)¶
Controlled multiplication modulo N by integer, (out of place)

virtual void Qrack::QInterface::CIMULModNOut(bitCapInt toMul, bitCapInt modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length, const std::vector<bitLenInt> &controls)¶
Inverse of controlled multiplication modulo N by integer, (out of place)

virtual void Qrack::QInterface::FullAdd(bitLenInt inputBit1, bitLenInt inputBit2, bitLenInt carryInSumOut, bitLenInt carryOut)¶
Quantum analog of classical “Full Adder” gate.
(Assumes the outputBit is in the 0 state)

virtual void Qrack::QInterface::IFullAdd(bitLenInt inputBit1, bitLenInt inputBit2, bitLenInt carryInSumOut, bitLenInt carryOut)¶
Inverse of FullAdd.
(Can be thought of as “subtraction,” but with a register convention that the same inputs invert FullAdd.)

virtual void Qrack::QInterface::CFullAdd(const std::vector<bitLenInt> &controls, bitLenInt inputBit1, bitLenInt inputBit2, bitLenInt carryInSumOut, bitLenInt carryOut)¶
Controlled quantum analog of classical “Full Adder” gate.
Quantum analog of classical “Full Adder” gate.
(Assumes the outputBit is in the 0 state)

virtual void Qrack::QInterface::CIFullAdd(const std::vector<bitLenInt> &controls, bitLenInt inputBit1, bitLenInt inputBit2, bitLenInt carryInSumOut, bitLenInt carryOut)¶
Inverse of CFullAdd.
Inverse of FullAdd.
(Can be thought of as “subtraction,” but with a register convention that the same inputs invert CFullAdd.)

virtual void Qrack::QInterface::ADC(bitLenInt input1, bitLenInt input2, bitLenInt output, bitLenInt length, bitLenInt carry)¶
Add a quantum integer to a quantum integer, with carry.
(Assumes the output register is in the 0 state)

virtual void Qrack::QInterface::IADC(bitLenInt input1, bitLenInt input2, bitLenInt output, bitLenInt length, bitLenInt carry)¶
Inverse of ADC.
(Can be thought of as “subtraction,” but with a register convention that the same inputs invert ADC.)

virtual void Qrack::QInterface::CADC(const std::vector<bitLenInt> &controls, bitLenInt input1, bitLenInt input2, bitLenInt output, bitLenInt length, bitLenInt carry)¶
Add a quantum integer to a quantum integer, with carry and with controls.
(Assumes the output register is in the 0 state)

virtual void Qrack::QInterface::CIADC(const std::vector<bitLenInt> &controls, bitLenInt input1, bitLenInt input2, bitLenInt output, bitLenInt length, bitLenInt carry)¶
Inverse of CADC.
(Can be thought of as “subtraction,” but with a register convention that the same inputs invert CADC.)
Algorithmic Implementations¶

virtual void Qrack::QInterface::QFT(bitLenInt start, bitLenInt length, bool trySeparate = false)¶
Quantum Fourier Transform  Apply the quantum Fourier transform to the register.
Quantum Fourier Transform  Optimized for going from 0>/1> to +>/> basis.
“trySeparate” is an optional hitormiss optimization, specifically for QUnit types. Our suggestion is, turn it on for speed and memory effciency if you expect the result of the QFT to be in a permutation basis eigenstate. Otherwise, turning it on will probably take longer.

virtual void Qrack::QInterface::IQFT(bitLenInt start, bitLenInt length, bool trySeparate = false)¶
Inverse Quantum Fourier Transform  Apply the inverse quantum Fourier transform to the register.
Inverse Quantum Fourier Transform  Quantum Fourier transform optimized for going from +>/> to 0>/1> basis.
“trySeparate” is an optional hitormiss optimization, specifically for QUnit types. Our suggestion is, turn it on for speed and memory effciency if you expect the result of the QFT to be in a permutation basis eigenstate. Otherwise, turning it on will probably take longer.

virtual void Qrack::QInterface::QFTR(const std::vector<bitLenInt> &qubits, bool trySeparate = false)¶
Quantum Fourier Transform (random access)  Apply the quantum Fourier transform to the register.
Quantum Fourier Transform  Optimized for going from 0>/1> to +>/> basis.
“trySeparate” is an optional hitormiss optimization, specifically for QUnit types. Our suggestion is, turn it on for speed and memory effciency if you expect the result of the QFT to be in a permutation basis eigenstate. Otherwise, turning it on will probably take longer.

virtual void Qrack::QInterface::IQFTR(const std::vector<bitLenInt> &qubits, bool trySeparate = false)¶
Inverse Quantum Fourier Transform (random access)  Apply the inverse quantum Fourier transform to the register.
Inverse Quantum Fourier Transform  Quantum Fourier transform optimized for going from +>/> to 0>/1> basis.
“trySeparate” is an optional hitormiss optimization, specifically for QUnit types. Our suggestion is, turn it on for speed and memory effciency if you expect the result of the QFT to be in a permutation basis eigenstate. Otherwise, turning it on will probably take longer.