# QInterface¶

Defined in qinterface.hpp.

This provides a basic interface with a wide-ranging set of functionality

class Qrack::QInterface

A “Qrack::QInterface” is an abstract interface exposing qubit permutation state vector with methods to operate on it as by gates and register-like instructions.

See README.md for an overview of the algorithms Qrack employs.

Subclassed by Qrack::QEngine, Qrack::QPager, Qrack::QStabilizerHybrid, Qrack::QUnit

## Creating a QInterface¶

There are five primary implementations of a QInterface:

enum Qrack::QInterfaceEngine

Enumerated list of supported engines.

Use QINTERFACE_OPTIMAL for the best supported engine.

Values:

QINTERFACE_CPU = 0

Create a QEngineCPU leveraging only local CPU and memory resources.

QINTERFACE_OPENCL

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

QINTERFACE_HYBRID

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

QINTERFACE_STABILIZER_HYBRID

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

QINTERFACE_QPAGER

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

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.

QINTERFACE_QUNIT_MULTI

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

QINTERFACE_FIRST = QINTERFACE_CPU
QINTERFACE_OPTIMAL_SCHROEDINGER = QINTERFACE_CPU
QINTERFACE_OPTIMAL_SINGLE_PAGE = QINTERFACE_CPU
QINTERFACE_OPTIMAL_G0_CHILD = QINTERFACE_STABILIZER_HYBRID
QINTERFACE_OPTIMAL_G1_CHILD = QINTERFACE_CPU
QINTERFACE_OPTIMAL_G2_CHILD = QINTERFACE_CPU
QINTERFACE_OPTIMAL = QINTERFACE_QUNIT
QINTERFACE_OPTIMAL_MULTI = QINTERFACE_QUNIT_MULTI
QINTERFACE_MAX

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

template <typename… Ts>
QInterfacePtr Qrack::CreateQuantumInterface(QInterfaceEngine engine, QInterfaceEngine subengine1, QInterfaceEngine subengine2, Ts... args)

Factory method to create specific engine implementations.

## Constructors¶

Warning

doxygenfunction: Unable to resolve multiple matches for function “Qrack::QInterface::QInterface” with arguments (bitLenInt, qrack_rand_gen_ptr, bool, bool, bool, real1) in doxygen xml output for project “qrack” from directory: /tmp/qrack/doc/xml. Potential matches:

- Qrack::QInterface::QInterface()
- Qrack::QInterface::QInterface(bitLenInt, qrack_rand_gen_ptr, bool, bool, bool, real1_f)


## Members¶

StateVectorPtr Qrack::QEngineCPU::stateVec

## Configuration Methods¶

bitLenInt Qrack::QInterface::GetQubitCount()

Get the count of bits in this register.

bitCapInt Qrack::QInterface::GetMaxQPower()

Get the maximum number of basis states, namely $$n^2$$ for $$n$$ qubits.

## State Manipulation Methods¶

virtual void Qrack::QInterface::SetPermutation(bitCapInt perm, complex phaseFac = CMPLX_DEFAULT_ARG) = 0

Set to a specific permutation.

virtual void Qrack::QInterface::SetQuantumState(const complex *inputState) = 0

Set an arbitrary pure quantum state representation.

Warning
PSEUDO-QUANTUM

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 “left-hand” subsystem being in |00> is 1/4, and the probablity of the “right-hand” 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” “under-the-hood” 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) = 0
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 well-motivated, 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 well-motivated, 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
PSEUDO-QUANTUM

virtual real1_f Qrack::QInterface::ProbAll(bitCapInt fullRegister) = 0

Direct measure of full permutation probability.

Warning
PSEUDO-QUANTUM

real1_f Qrack::QInterface::ProbReg(const bitLenInt &start, const bitLenInt &length, const bitCapInt &permutation)

Direct measure of register permutation probability.

Returns probability of permutation of the register.

Warning
PSEUDO-QUANTUM

real1_f Qrack::QInterface::ProbMask(const bitCapInt &mask, const 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
PSEUDO-QUANTUM

virtual void Qrack::QInterface::GetProbs(real1 *outputProbs) = 0

Get the pure quantum state representation.

Warning
PSEUDO-QUANTUM

virtual void Qrack::QInterface::Swap(bitLenInt qubitIndex1, bitLenInt qubitIndex2) = 0

Swap values of two bits in register.

virtual void Qrack::QInterface::Swap(bitLenInt start1, bitLenInt start2, bitLenInt length)

Bitwise swap.

virtual void Qrack::QInterface::ISwap(bitLenInt qubitIndex1, bitLenInt qubitIndex2) = 0

Swap values of two bits in register, and apply phase factor of i if bits are different.

virtual void Qrack::QInterface::ISwap(bitLenInt start1, bitLenInt start2, bitLenInt length)

Bitwise swap.

virtual void Qrack::QInterface::SqrtSwap(bitLenInt qubitIndex1, bitLenInt qubitIndex2) = 0

Square root of Swap gate.

virtual void Qrack::QInterface::SqrtSwap(bitLenInt start1, bitLenInt start2, bitLenInt length)

Bitwise square root of swap.

virtual void Qrack::QInterface::CSwap(const bitLenInt *controls, const bitLenInt &controlLen, const bitLenInt &qubit1, const bitLenInt &qubit2) = 0

Apply a swap with arbitrary control bits.

virtual void Qrack::QInterface::AntiCSwap(const bitLenInt *controls, const bitLenInt &controlLen, const bitLenInt &qubit1, const bitLenInt &qubit2) = 0

Apply a swap with arbitrary (anti) control bits.

virtual void Qrack::QInterface::CSqrtSwap(const bitLenInt *controls, const bitLenInt &controlLen, const bitLenInt &qubit1, const bitLenInt &qubit2) = 0

Apply a square root of swap with arbitrary control bits.

virtual void Qrack::QInterface::AntiCSqrtSwap(const bitLenInt *controls, const bitLenInt &controlLen, const bitLenInt &qubit1, const bitLenInt &qubit2) = 0

Apply a square root of swap with arbitrary (anti) control bits.

Warning

doxygenfunction: Unable to resolve multiple matches for function “Qrack::QInterface::FSim” with arguments (real1, real1, bitLenInt, bitLenInt) in doxygen xml output for project “qrack” from directory: /tmp/qrack/doc/xml. Potential matches:

- virtual void Qrack::QInterface::FSim(real1_f, real1_f, bitLenInt, bitLenInt) = 0
- void Qrack::QInterface::FSim(real1_f, real1_f, bitLenInt, bitLenInt, bitLenInt)


Warning

doxygenfunction: Unable to resolve multiple matches for function “Qrack::QInterface::FSim” with arguments (real1, real1, bitLenInt, bitLenInt, bitLenInt) in doxygen xml output for project “qrack” from directory: /tmp/qrack/doc/xml. Potential matches:

- virtual void Qrack::QInterface::FSim(real1_f, real1_f, bitLenInt, bitLenInt) = 0
- void Qrack::QInterface::FSim(real1_f, real1_f, bitLenInt, bitLenInt, bitLenInt)

virtual void Qrack::QInterface::Reverse(bitLenInt first, bitLenInt last)

Reverse all of the bits in a sequence.

virtual bool Qrack::QInterface::TrySeparate(bitLenInt start, bitLenInt length = 1, real1_f error_tol = REAL1_EPSILON)

Qrack::QUnit types maintain explicit separation of representations of qubits, which reduces memory usage and increases gate speed.

This method is used to manually attempt internal separation of a QUnit subsytem. We attempt a Decompose() operation, on a state which might not be separable. If the state is not separable, we abort and return false. Otherwise, we complete the operation, add the separated subsystem back in place into the QUnit “shards,” and return true.

This should never change the logical/physical state of the QInterface, only possibly its internal representation, for simulation optimization purposes. This is not a truly quantum computational operation, but it also does not lead to nonphysical effects.

Warning
PSEUDO-QUANTUM

std::map<bitCapInt, int> Qrack::QInterface::MultiShotMeasureMask(const bitCapInt *qPowers, const bitLenInt qPowerCount, const unsigned int 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[0] to 2^(qPowerCount - 1) ~ qPowers[qPowerCount - 1], in contiguous ascending order. “shots” specifies the number of samples to take as if totally re-preparing the pre-measurement state. This method returns a dictionary with keys, which are the (masked-order) 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 re-preparations of the state right before measurement, and to collect random measurement resutls, without forcing the user to re-prepare or “clone” the state.)

Warning
PSEUDO-QUANTUM

## Quantum Gates¶

Note

Most gates offer both a single-bit version taking just the index to the qubit, as well as a register-spanning variant for convienence and performance that performs the gate across a sequence of bits.

### Single Gates¶

virtual void Qrack::QInterface::ApplySingleBit(const complex *mtrx, bitLenInt qubitIndex) = 0

Apply an arbitrary single bit unitary transformation.

virtual void Qrack::QInterface::ApplyControlledSingleBit(const bitLenInt *controls, const bitLenInt &controlLen, const bitLenInt &target, const complex *mtrx) = 0

Apply an arbitrary single bit unitary transformation, with arbitrary control bits.

void Qrack::QInterface::AND(bitLenInt inputBit1, bitLenInt inputBit2, bitLenInt outputBit)

Quantum analog of classical “AND” gate.

(Assumes the outputBit is in the 0 state)

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)

void Qrack::QInterface::OR(bitLenInt inputBit1, bitLenInt inputBit2, bitLenInt outputBit)

Quantum analog of classical “OR” gate.

(Assumes the outputBit is in the 0 state)

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)

void Qrack::QInterface::XOR(bitLenInt inputBit1, bitLenInt inputBit2, bitLenInt outputBit)

Quantum analog of classical “XOR” gate.

(Assumes the outputBit is in the 0 state)

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)

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
PSEUDO-QUANTUM

virtual void Qrack::QInterface::H(bitLenInt qubitIndex)

Applies a Hadamard gate on qubit at “qubitIndex.”

virtual void Qrack::QInterface::X(bitLenInt qubitIndex)

X gate.

Applies the Pauli “X” operator to the qubit at “qubitIndex.” The Pauli “X” operator is equivalent to a logical “NOT.”

virtual void Qrack::QInterface::Y(bitLenInt qubitIndex)

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.

virtual void Qrack::QInterface::Z(bitLenInt qubitIndex)

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.

void Qrack::QInterface::S(bitLenInt qubitIndex)

S gate.

Apply 1/4 phase rotation.

Applies a 1/4 phase rotation to the qubit at “qubitIndex.”

void Qrack::QInterface::IS(bitLenInt qubitIndex)

Inverse S gate.

Apply inverse 1/4 phase rotation.

Applies an inverse 1/4 phase rotation to the qubit at “qubitIndex.”

void Qrack::QInterface::T(bitLenInt qubitIndex)

T gate.

Apply 1/8 phase rotation.

Applies a 1/8 phase rotation to the qubit at “qubitIndex.”

void Qrack::QInterface::IT(bitLenInt qubitIndex)

Inverse T gate.

Apply inverse 1/8 phase rotation.

Applies an inverse 1/8 phase rotation to the qubit at “qubitIndex.”

virtual void Qrack::QInterface::SqrtX(bitLenInt qubitIndex)

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.”

virtual void Qrack::QInterface::ISqrtX(bitLenInt qubitIndex)

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.”

virtual void Qrack::QInterface::SqrtY(bitLenInt qubitIndex)

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.

virtual void Qrack::QInterface::ISqrtY(bitLenInt qubitIndex)

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.

virtual void Qrack::QInterface::SqrtH(bitLenInt qubitIndex)

Applies the square root of the Hadamard gate on qubit at “qubitIndex.”

virtual void Qrack::QInterface::SqrtXConjT(bitLenInt qubitIndex)

Phased square root of X gate.

Applies T.SqrtX.IT to the qubit at “qubitIndex.”

virtual void Qrack::QInterface::ISqrtXConjT(bitLenInt qubitIndex)

Inverse phased square root of X gate.

Applies IT.ISqrtX.T to the qubit at “qubitIndex.”

void Qrack::QInterface::CNOT(bitLenInt control, bitLenInt target)

Controlled NOT gate.

Controlled not.

If the control is set to 1, the target bit is NOT-ed or X-ed.

void Qrack::QInterface::AntiCNOT(bitLenInt control, bitLenInt target)

Anti controlled NOT gate.

“Anti-controlled not” - Apply “not” if control bit is zero, do not apply if control bit is one.

If the control is set to 0, the target bit is NOT-ed or X-ed.

void Qrack::QInterface::CCNOT(bitLenInt control1, bitLenInt control2, bitLenInt target)

Doubly-controlled NOT gate.

Doubly-controlled not.

If both controls are set to 1, the target bit is NOT-ed or X-ed.

void Qrack::QInterface::AntiCCNOT(bitLenInt control1, bitLenInt control2, bitLenInt target)

Anti doubly-controlled NOT gate.

“Anti-doubly-controlled not” - Apply “not” if control bits are both zero, do not apply if either control bit is one.

If both controls are set to 0, the target bit is NOT-ed or X-ed.

void Qrack::QInterface::CY(bitLenInt control, bitLenInt target)

Controlled Y gate.

Apply controlled Pauli Y matrix to bit.

If the “control” bit is set to 1, then the Pauli “Y” operator is applied to “target.”

void Qrack::QInterface::CZ(bitLenInt control, bitLenInt target)

Controlled Z gate.

Apply controlled Pauli Z matrix to bit.

If the “control” bit is set to 1, then the Pauli “Z” operator is applied to “target.”

Warning

doxygenfunction: Unable to resolve multiple matches for function “Qrack::QInterface::RT” with arguments (real1, bitLenInt) in doxygen xml output for project “qrack” from directory: /tmp/qrack/doc/xml. Potential matches:

- virtual void Qrack::QInterface::RT(real1_f, bitLenInt, bitLenInt)
- void Qrack::QInterface::RT(real1_f, bitLenInt)

void Qrack::QInterface::RTDyad(int numerator, int denomPower, bitLenInt qubitIndex)

Dyadic fraction “phase shift gate” - Rotates as e^(i*(M_PI * numerator) / 2^denomPower) around |1> state.

Rotates as $$\exp\left(i*{\pi * numerator} / 2^{denomPower}\right)$$ around |1> state.

Warning

doxygenfunction: Unable to resolve multiple matches for function “Qrack::QInterface::CRT” with arguments (real1, bitLenInt, bitLenInt) in doxygen xml output for project “qrack” from directory: /tmp/qrack/doc/xml. Potential matches:

- virtual void Qrack::QInterface::CRT(real1_f, bitLenInt, bitLenInt, bitLenInt)
- void Qrack::QInterface::CRT(real1_f, bitLenInt, bitLenInt)

void Qrack::QInterface::CRTDyad(int numerator, int denomPower, bitLenInt control, bitLenInt target)

Controlled dyadic fraction “phase shift gate”.

Controlled dyadic “phase shift gate” - if control bit is true, rotates target bit as e^(i*(M_PI * numerator) / 2^denomPower) around |1> state.

If control bit is set to 1, rotates target bit as $$\exp\left(i*{\pi * numerator} / 2^{denomPower}\right)$$ around |1> state.

Warning

doxygenfunction: Unable to resolve multiple matches for function “Qrack::QInterface::RX” with arguments (real1, bitLenInt) in doxygen xml output for project “qrack” from directory: /tmp/qrack/doc/xml. Potential matches:

- virtual void Qrack::QInterface::RX(real1_f, bitLenInt, bitLenInt)
- void Qrack::QInterface::RX(real1_f, bitLenInt)

void Qrack::QInterface::RXDyad(int numerator, int denomPower, bitLenInt qubitIndex)

Dyadic fraction X axis rotation gate.

Dyadic fraction x axis rotation gate - Rotates around Pauli x axis.

Rotates $$\exp\left(i*{\pi * numerator} / 2^{denomPower}\right)$$ on Pauli x axis.

Warning

doxygenfunction: Unable to resolve multiple matches for function “Qrack::QInterface::CRX” with arguments (real1, bitLenInt, bitLenInt) in doxygen xml output for project “qrack” from directory: /tmp/qrack/doc/xml. Potential matches:

- virtual void Qrack::QInterface::CRX(real1_f, bitLenInt, bitLenInt, bitLenInt)
- void Qrack::QInterface::CRX(real1_f, bitLenInt, bitLenInt)

void Qrack::QInterface::CRXDyad(int numerator, int denomPower, bitLenInt control, bitLenInt target)

Controlled dyadic fraction X axis rotation gate.

Controlled dyadic fraction x axis rotation gate - Rotates around Pauli x axis.

If “control” is 1, rotates as $$\exp\left(i*{\pi * numerator} / 2^{denomPower}\right)$$ around Pauli x axis.

Warning

doxygenfunction: Unable to resolve multiple matches for function “Qrack::QInterface::RY” with arguments (real1, bitLenInt) in doxygen xml output for project “qrack” from directory: /tmp/qrack/doc/xml. Potential matches:

- virtual void Qrack::QInterface::RY(real1_f, bitLenInt, bitLenInt)
- void Qrack::QInterface::RY(real1_f, bitLenInt)

void Qrack::QInterface::RYDyad(int numerator, int denomPower, bitLenInt qubitIndex)

Dyadic fraction Y axis rotation gate.

Dyadic fraction y axis rotation gate - Rotates around Pauli y axis.

Rotates as $$\exp\left(i*{\pi * numerator} / 2^{denomPower}\right)$$ around Pauli Y axis.

Warning

doxygenfunction: Unable to resolve multiple matches for function “Qrack::QInterface::CRY” with arguments (real1, bitLenInt, bitLenInt) in doxygen xml output for project “qrack” from directory: /tmp/qrack/doc/xml. Potential matches:

- virtual void Qrack::QInterface::CRY(real1_f, bitLenInt, bitLenInt, bitLenInt)
- void Qrack::QInterface::CRY(real1_f, bitLenInt, bitLenInt)

void Qrack::QInterface::CRYDyad(int numerator, int denomPower, bitLenInt control, bitLenInt target)

Controlled dyadic fraction y axis rotation gate.

Controlled dyadic fraction y axis rotation gate - Rotates around Pauli y axis.

If “control” is set to 1, rotates as $$\exp\left(i*{\pi * numerator} / 2^{denomPower}\right)$$ around Pauli Y axis.

Warning

doxygenfunction: Unable to resolve multiple matches for function “Qrack::QInterface::RZ” with arguments (real1, bitLenInt) in doxygen xml output for project “qrack” from directory: /tmp/qrack/doc/xml. Potential matches:

- virtual void Qrack::QInterface::RZ(real1_f, bitLenInt, bitLenInt)
- void Qrack::QInterface::RZ(real1_f, bitLenInt)

void Qrack::QInterface::RZDyad(int numerator, int denomPower, bitLenInt qubitIndex)

Dyadic fraction Z axis rotation gate.

Dyadic fraction y axis rotation gate - Rotates around Pauli y axis.

Rotates as $$\exp\left(i*{\pi * numerator} / 2^{denomPower}\right)$$ around Pauli Z axis.

Warning

doxygenfunction: Unable to resolve multiple matches for function “Qrack::QInterface::CRZ” with arguments (real1, bitLenInt, bitLenInt) in doxygen xml output for project “qrack” from directory: /tmp/qrack/doc/xml. Potential matches:

- virtual void Qrack::QInterface::CRZ(real1_f, bitLenInt, bitLenInt, bitLenInt)
- void Qrack::QInterface::CRZ(real1_f, bitLenInt, bitLenInt)

void Qrack::QInterface::CRZDyad(int numerator, int denomPower, bitLenInt control, bitLenInt target)

Controlled dyadic fraction Z axis rotation gate.

Controlled dyadic fraction z axis rotation gate - Rotates around Pauli z axis.

If “control” is set to 1, rotates as $$\exp\left(i*{\pi * numerator} / 2^{denomPower}\right)$$ around Pauli Z axis.

Warning

doxygenfunction: Unable to resolve multiple matches for function “Qrack::QInterface::Exp” with arguments (real1, bitLenInt) in doxygen xml output for project “qrack” from directory: /tmp/qrack/doc/xml. Potential matches:

- virtual void Qrack::QInterface::Exp(real1_f, bitLenInt, bitLenInt)
- void Qrack::QInterface::Exp(bitLenInt *, bitLenInt, bitLenInt, complex *, bool)
- void Qrack::QInterface::Exp(real1_f, bitLenInt)

void Qrack::QInterface::ExpDyad(int numerator, int denomPower, bitLenInt qubitIndex)

Dyadic fraction (identity) exponentiation gate - Applies exponentiation of the identity operator.

Applies $$\exp\left(-i * \pi * numerator * I / 2^{denomPower}\right)$$, exponentiation of the identity operator

Warning

doxygenfunction: Unable to resolve multiple matches for function “Qrack::QInterface::ExpX” with arguments (real1, bitLenInt) in doxygen xml output for project “qrack” from directory: /tmp/qrack/doc/xml. Potential matches:

- virtual void Qrack::QInterface::ExpX(real1_f, bitLenInt, bitLenInt)
- void Qrack::QInterface::ExpX(real1_f, bitLenInt)

void Qrack::QInterface::ExpXDyad(int numerator, int denomPower, bitLenInt qubitIndex)

Dyadic fraction Pauli X exponentiation gate.

Dyadic fraction Pauli X exponentiation gate - Applies exponentiation of the Pauli X operator.

Applies $$\exp\left(-i * \pi * numerator * \sigma_x / 2^{denomPower}\right)$$, exponentiation of the Pauli X operator

Warning

doxygenfunction: Unable to resolve multiple matches for function “Qrack::QInterface::ExpY” with arguments (real1, bitLenInt) in doxygen xml output for project “qrack” from directory: /tmp/qrack/doc/xml. Potential matches:

- virtual void Qrack::QInterface::ExpY(real1_f, bitLenInt, bitLenInt)
- void Qrack::QInterface::ExpY(real1_f, bitLenInt)

void Qrack::QInterface::ExpYDyad(int numerator, int denomPower, bitLenInt qubitIndex)

Dyadic fraction Pauli Y exponentiation gate.

Dyadic fraction Pauli Y exponentiation gate - Applies exponentiation of the Pauli Y operator.

Applies $$\exp\left(-i * \pi * numerator * \sigma_y / 2^{denomPower}\right)$$, exponentiation of the Pauli Y operator

Warning

doxygenfunction: Unable to resolve multiple matches for function “Qrack::QInterface::ExpZ” with arguments (real1, bitLenInt) in doxygen xml output for project “qrack” from directory: /tmp/qrack/doc/xml. Potential matches:

- virtual void Qrack::QInterface::ExpZ(real1_f, bitLenInt, bitLenInt)
- void Qrack::QInterface::ExpZ(real1_f, bitLenInt)

void Qrack::QInterface::ExpZDyad(int numerator, int denomPower, bitLenInt qubitIndex)

Dyadic fraction Pauli Z exponentiation gate.

Dyadic fraction Pauli Z exponentiation gate - Applies exponentiation of the Pauli Z operator.

Applies $$\exp\left(-i * \pi * numerator * \sigma_z / 2^{denomPower}\right)$$, exponentiation of the Pauli Z operator

void Qrack::QInterface::Exp(bitLenInt *controls, bitLenInt controlLen, bitLenInt qubit, complex *matrix2x2, bool antiCtrled = false)

Imaginary exponentiation of arbitrary 2x2 gate.

Imaginary exponentiate of arbitrary single bit gate.

Applies $$e^{-i*Op}$$, where “Op” is a 2x2 matrix, (with controls on the application of the gate).

virtual void Qrack::QInterface::UniformlyControlledSingleBit(const bitLenInt *controls, const bitLenInt &controlLen, bitLenInt qubitIndex, const complex *mtrxs)

Apply a “uniformly controlled” arbitrary single bit unitary transformation.

A different unitary 2x2 complex matrix 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. “mtrxs” is a flat (1-dimensional) array where each subsequent set of 4 components is an arbitrary 2x2 single bit gate associated with the next permutation of the control bits, starting from 0. All combinations of control bits apply one of the 4 component (flat 2x2) matrices. For k control bits, there are therefore 4 * 2^k complex components in “mtrxs,” representing 2^k complex matrices of 2x2 components. (The component ordering in each matrix is the same as all other gates with an arbitrary 2x2 applied to a single bit, such as Qrack::ApplySingleBit.)

void Qrack::QInterface::UniformlyControlledRY(const bitLenInt *controls, const bitLenInt &controlLen, bitLenInt qubitIndex, const real1 *angles)

Apply a “uniformly controlled” rotation of a bit around the Pauli Y axis.

Uniformly controlled y axis rotation gate - Rotates as e^(-i*/2) around Pauli y axis for each permutation “k” of the control bits.

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.”

void Qrack::QInterface::UniformlyControlledRZ(const bitLenInt *controls, const bitLenInt &controlLen, bitLenInt qubitIndex, const real1 *angles)

Apply a “uniformly controlled” rotation of a bit around the Pauli Z axis.

Uniformly controlled z axis rotation gate - Rotates as e^(-i*/2) around Pauli z axis for each permutation “k” of the control bits.

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.”

### Register-wide Gates¶

virtual void Qrack::QInterface::AND(bitLenInt inputStart1, bitLenInt inputStart2, bitLenInt outputStart, bitLenInt length)

Bitwise “AND”.

“AND” registers at “inputStart1” and “inputStart2,” of “length” bits, placing the result in “outputStart”.

virtual void Qrack::QInterface::CLAND(bitLenInt qInputStart, bitCapInt classicalInput, bitLenInt outputStart, bitLenInt length)

Classical bitwise “AND”.

“AND” registers at “inputStart1” and the classic bits of “classicalInput,” of “length” bits, placing the result in “outputStart”.

virtual void Qrack::QInterface::OR(bitLenInt inputStart1, bitLenInt inputStart2, bitLenInt outputStart, bitLenInt length)

Bitwise “OR”.

virtual void Qrack::QInterface::CLOR(bitLenInt qInputStart, bitCapInt classicalInput, bitLenInt outputStart, bitLenInt length)

Classical bitwise “OR”.

virtual void Qrack::QInterface::XOR(bitLenInt inputStart1, bitLenInt inputStart2, bitLenInt outputStart, bitLenInt length)

Bitwise “XOR”.

virtual void Qrack::QInterface::CLXOR(bitLenInt qInputStart, bitCapInt classicalInput, bitLenInt outputStart, bitLenInt length)

Classical bitwise “XOR”.

virtual bitCapInt Qrack::QInterface::MReg(bitLenInt start, bitLenInt length)

Measure permutation state of a register.

virtual void Qrack::QInterface::H(bitLenInt start, bitLenInt length)

virtual void Qrack::QInterface::X(bitLenInt start, bitLenInt length)

Bitwise Pauli X (or logical “NOT”) operator.

virtual void Qrack::QInterface::Y(bitLenInt start, bitLenInt length)

Bitwise Pauli Y operator.

virtual void Qrack::QInterface::Z(bitLenInt start, bitLenInt length)

Bitwise Pauli Z operator.

virtual void Qrack::QInterface::S(bitLenInt start, bitLenInt length)

Bitwise S operator (1/4 phase rotation)

virtual void Qrack::QInterface::IS(bitLenInt start, bitLenInt length)

Bitwise inverse S operator (1/4 phase rotation)

virtual void Qrack::QInterface::T(bitLenInt start, bitLenInt length)

Bitwise T operator (1/8 phase rotation)

virtual void Qrack::QInterface::IT(bitLenInt start, bitLenInt length)

Bitwise inverse T operator (1/8 phase rotation)

virtual void Qrack::QInterface::SqrtX(bitLenInt start, bitLenInt length)

Bitwise square root of Pauli X operator.

virtual void Qrack::QInterface::ISqrtX(bitLenInt start, bitLenInt length)

Bitwise inverse square root of Pauli X operator.

virtual void Qrack::QInterface::SqrtY(bitLenInt start, bitLenInt length)

Bitwise square root of Pauli Y operator.

virtual void Qrack::QInterface::ISqrtY(bitLenInt start, bitLenInt length)

Bitwise inverse square root of Pauli Y operator.

virtual void Qrack::QInterface::SqrtH(bitLenInt start, bitLenInt length)

virtual void Qrack::QInterface::SqrtXConjT(bitLenInt start, bitLenInt length)

Bitwise phased square root of Pauli X operator.

virtual void Qrack::QInterface::ISqrtXConjT(bitLenInt start, bitLenInt length)

Bitwise inverse phased square root of Pauli X operator.

virtual void Qrack::QInterface::CNOT(bitLenInt inputBits, bitLenInt targetBits, bitLenInt length)

Bitwise controlled-not.

virtual void Qrack::QInterface::AntiCNOT(bitLenInt inputBits, bitLenInt targetBits, bitLenInt length)

Bitwise “anti-“controlled-not.

virtual void Qrack::QInterface::CCNOT(bitLenInt control1, bitLenInt control2, bitLenInt target, bitLenInt length)

Bitwise doubly controlled-not.

virtual void Qrack::QInterface::AntiCCNOT(bitLenInt control1, bitLenInt control2, bitLenInt target, bitLenInt length)

Bitwise doubly “anti-“controlled-not.

virtual void Qrack::QInterface::CY(bitLenInt control, bitLenInt target, bitLenInt length)

Bitwise controlled Y gate.

If the “control” bit is set to 1, then the Pauli “Y” operator is applied to “target.”

virtual void Qrack::QInterface::CZ(bitLenInt control, bitLenInt target, bitLenInt length)

Bitwise controlled Z gate.

If the “control” bit is set to 1, then the Pauli “Z” operator is applied to “target.”

Warning

doxygenfunction: Unable to resolve multiple matches for function “Qrack::QInterface::RT” with arguments (real1, bitLenInt, bitLenInt) in doxygen xml output for project “qrack” from directory: /tmp/qrack/doc/xml. Potential matches:

- virtual void Qrack::QInterface::RT(real1_f, bitLenInt, bitLenInt)
- void Qrack::QInterface::RT(real1_f, bitLenInt)

virtual void Qrack::QInterface::RTDyad(int numerator, int denomPower, bitLenInt start, bitLenInt length)

Bitwise dyadic fraction phase shift gate.

Rotates as $$\exp\left(i*{\pi * numerator} / 2^{denomPower}\right)$$ around |1> state.

Warning

doxygenfunction: Unable to resolve multiple matches for function “Qrack::QInterface::RX” with arguments (real1, bitLenInt, bitLenInt) in doxygen xml output for project “qrack” from directory: /tmp/qrack/doc/xml. Potential matches:

- virtual void Qrack::QInterface::RX(real1_f, bitLenInt, bitLenInt)
- void Qrack::QInterface::RX(real1_f, bitLenInt)

virtual void Qrack::QInterface::RXDyad(int numerator, int denomPower, bitLenInt start, bitLenInt length)

Bitwise dyadic fraction X axis rotation gate.

Rotates $$\exp\left(i*{\pi * numerator} / 2^{denomPower}\right)$$ on Pauli x axis.

Warning

doxygenfunction: Unable to resolve multiple matches for function “Qrack::QInterface::CRX” with arguments (real1, bitLenInt, bitLenInt, bitLenInt) in doxygen xml output for project “qrack” from directory: /tmp/qrack/doc/xml. Potential matches:

- virtual void Qrack::QInterface::CRX(real1_f, bitLenInt, bitLenInt, bitLenInt)
- void Qrack::QInterface::CRX(real1_f, bitLenInt, bitLenInt)

virtual void Qrack::QInterface::CRXDyad(int numerator, int denomPower, bitLenInt control, bitLenInt target, bitLenInt length)

Bitwise controlled dyadic fraction X axis rotation gate.

If “control” is 1, rotates as $$\exp\left(i*{\pi * numerator} / 2^{denomPower}\right)$$ around Pauli x axis.

Warning

doxygenfunction: Unable to resolve multiple matches for function “Qrack::QInterface::RY” with arguments (real1, bitLenInt, bitLenInt) in doxygen xml output for project “qrack” from directory: /tmp/qrack/doc/xml. Potential matches:

- virtual void Qrack::QInterface::RY(real1_f, bitLenInt, bitLenInt)
- void Qrack::QInterface::RY(real1_f, bitLenInt)

virtual void Qrack::QInterface::RYDyad(int numerator, int denomPower, bitLenInt start, bitLenInt length)

Bitwise dyadic fraction Y axis rotation gate.

Rotates as $$\exp\left(i*{\pi * numerator} / 2^{denomPower}\right)$$ around Pauli Y axis.

Warning

doxygenfunction: Unable to resolve multiple matches for function “Qrack::QInterface::CRY” with arguments (real1, bitLenInt, bitLenInt, bitLenInt) in doxygen xml output for project “qrack” from directory: /tmp/qrack/doc/xml. Potential matches:

- virtual void Qrack::QInterface::CRY(real1_f, bitLenInt, bitLenInt, bitLenInt)
- void Qrack::QInterface::CRY(real1_f, bitLenInt, bitLenInt)

virtual void Qrack::QInterface::CRYDyad(int numerator, int denomPower, bitLenInt control, bitLenInt target, bitLenInt length)

Bitwise controlled dyadic fraction y axis rotation gate.

If “control” is set to 1, rotates as $$\exp\left(i*{\pi * numerator} / 2^{denomPower}\right)$$ around Pauli Y axis.

Warning

doxygenfunction: Unable to resolve multiple matches for function “Qrack::QInterface::RZ” with arguments (real1, bitLenInt, bitLenInt) in doxygen xml output for project “qrack” from directory: /tmp/qrack/doc/xml. Potential matches:

- virtual void Qrack::QInterface::RZ(real1_f, bitLenInt, bitLenInt)
- void Qrack::QInterface::RZ(real1_f, bitLenInt)

virtual void Qrack::QInterface::RZDyad(int numerator, int denomPower, bitLenInt start, bitLenInt length)

Bitwise dyadic fraction Z axis rotation gate.

Rotates as $$\exp\left(i*{\pi * numerator} / 2^{denomPower}\right)$$ around Pauli Z axis.

Warning

doxygenfunction: Unable to resolve multiple matches for function “Qrack::QInterface::CRZ” with arguments (real1, bitLenInt, bitLenInt, bitLenInt) in doxygen xml output for project “qrack” from directory: /tmp/qrack/doc/xml. Potential matches:

- virtual void Qrack::QInterface::CRZ(real1_f, bitLenInt, bitLenInt, bitLenInt)
- void Qrack::QInterface::CRZ(real1_f, bitLenInt, bitLenInt)

virtual void Qrack::QInterface::CRZDyad(int numerator, int denomPower, bitLenInt control, bitLenInt target, bitLenInt length)

Bitwise controlled dyadic fraction Z axis rotation gate.

If “control” is set to 1, rotates as $$\exp\left(i*{\pi * numerator} / 2^{denomPower}\right)$$ around Pauli Z axis.

Warning

doxygenfunction: Unable to resolve multiple matches for function “Qrack::QInterface::Exp” with arguments (real1, bitLenInt, bitLenInt) in doxygen xml output for project “qrack” from directory: /tmp/qrack/doc/xml. Potential matches:

- virtual void Qrack::QInterface::Exp(real1_f, bitLenInt, bitLenInt)
- void Qrack::QInterface::Exp(bitLenInt *, bitLenInt, bitLenInt, complex *, bool)
- void Qrack::QInterface::Exp(real1_f, bitLenInt)

virtual void Qrack::QInterface::ExpDyad(int numerator, int denomPower, bitLenInt start, bitLenInt length)

Bitwise Dyadic fraction (identity) exponentiation gate.

Applies $$\exp\left(-i * \pi * numerator * I / 2^{denomPower}\right)$$, exponentiation of the identity operator

Warning

doxygenfunction: Unable to resolve multiple matches for function “Qrack::QInterface::ExpX” with arguments (real1, bitLenInt, bitLenInt) in doxygen xml output for project “qrack” from directory: /tmp/qrack/doc/xml. Potential matches:

- virtual void Qrack::QInterface::ExpX(real1_f, bitLenInt, bitLenInt)
- void Qrack::QInterface::ExpX(real1_f, bitLenInt)

virtual void Qrack::QInterface::ExpXDyad(int numerator, int denomPower, bitLenInt start, bitLenInt length)

Bitwise Dyadic fraction Pauli X exponentiation gate.

Applies $$\exp\left(-i * \pi * numerator * \sigma_x / 2^{denomPower}\right)$$, exponentiation of the Pauli X operator

Warning

doxygenfunction: Unable to resolve multiple matches for function “Qrack::QInterface::ExpY” with arguments (real1, bitLenInt, bitLenInt) in doxygen xml output for project “qrack” from directory: /tmp/qrack/doc/xml. Potential matches:

- virtual void Qrack::QInterface::ExpY(real1_f, bitLenInt, bitLenInt)
- void Qrack::QInterface::ExpY(real1_f, bitLenInt)

virtual void Qrack::QInterface::ExpYDyad(int numerator, int denomPower, bitLenInt start, bitLenInt length)

Bitwise Dyadic fraction Pauli Y exponentiation gate.

Applies $$\exp\left(-i * \pi * numerator * \sigma_y / 2^{denomPower}\right)$$, exponentiation of the Pauli Y operator

Warning

doxygenfunction: Unable to resolve multiple matches for function “Qrack::QInterface::ExpZ” with arguments (real1, bitLenInt, bitLenInt) in doxygen xml output for project “qrack” from directory: /tmp/qrack/doc/xml. Potential matches:

- virtual void Qrack::QInterface::ExpZ(real1_f, bitLenInt, bitLenInt)
- void Qrack::QInterface::ExpZ(real1_f, bitLenInt)

virtual void Qrack::QInterface::ExpZDyad(int numerator, int denomPower, bitLenInt start, bitLenInt length)

Bitwise Dyadic fraction Pauli Z exponentiation gate.

Applies $$\exp\left(-i * \pi * numerator * \sigma_z / 2^{denomPower}\right)$$, exponentiation of the Pauli Z operator

## Algorithmic Implementations¶

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 hit-or-miss 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.

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 hit-or-miss 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 bitCapInt Qrack::QInterface::IndexedLDA(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart, bitLenInt valueLength, unsigned char *values, bool resetValue = true) = 0

Set 8 bit register bits by a superposed index-offset-based read from classical memory.

“inputStart” is the start index of 8 qubits that act as an index into the 256 byte “values” array. The “outputStart” bits are first cleared, then the separable |input, 00000000> permutation state is mapped to |input, values[input]>, with “values[input]” placed in the “outputStart” register. FOR BEST EFFICIENCY, the “values” array should be allocated aligned to a 64-byte boundary. (See the unit tests suite code for an example of how to align the allocation.)

While a QInterface represents an interacting set of qubit-based registers, or a virtual quantum chip, the registers need to interact in some way with (classical or quantum) RAM. IndexedLDA is a RAM access method similar to the X addressing mode of the MOS 6502 chip, if the X register can be in a state of coherent superposition when it loads from RAM.

The physical motivation for this addressing mode can be explained as follows: say that we have a superconducting quantum interface device (SQUID) based chip. SQUIDs have already been demonstrated passing coherently superposed electrical currents. In a sufficiently quantum-mechanically isolated qubit chip with a classical cache, with both classical RAM and registers likely cryogenically isolated from the environment, SQUIDs could (hopefully) pass coherently superposed electrical currents into the classical RAM cache to load values into a qubit register. The state loaded would be a superposition of the values of all RAM to which coherently superposed electrical currents were passed.

In qubit system similar to the MOS 6502, say we have qubit-based “accumulator” and “X index” registers, and say that we start with a superposed X index register. In (classical) X addressing mode, the X index register value acts an offset into RAM from a specified starting address. The X addressing mode of a LoaD Accumulator (LDA) instruction, by the physical mechanism described above, should load the accumulator in quantum parallel with the values of every different address of RAM pointed to in superposition by the X index register. The superposed values in the accumulator are entangled with those in the X index register, by way of whatever values the classical RAM pointed to by X held at the time of the load. (If the RAM at index “36” held an unsigned char value of “27,” then the value “36” in the X index register becomes entangled with the value “27” in the accumulator, and so on in quantum parallel for all superposed values of the X index register, at once.) If the X index register or accumulator are then measured, the two registers will both always collapse into a random but valid key-value pair of X index offset and value at that classical RAM address.

Note that a “superposed store operation in classical RAM” is not possible by analagous reasoning. Classical RAM would become entangled with both the accumulator and the X register. When the state of the registers was collapsed, we would find that only one “store” operation to a single memory address had actually been carried out, consistent with the address offset in the collapsed X register and the byte value in the collapsed accumulator. It would not be possible by this model to write in quantum parallel to more than one address of classical memory at a time.

virtual bitCapInt Qrack::QInterface::IndexedADC(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart, bitLenInt valueLength, bitLenInt carryIndex, unsigned char *values) = 0

Add to entangled 8 bit register state with a superposed index-offset-based read from classical memory.

“inputStart” is the start index of 8 qubits that act as an index into the 256 byte “values” array. The “outputStart” bits would usually already be entangled with the “inputStart” bits via a IndexedLDA() operation. With the “inputStart” bits being a “key” and the “outputStart” bits being a value, the permutation state |key, value> is mapped to |key, value + values[key]>. This is similar to classical parallel addition of two arrays. However, when either of the registers are measured, both registers will collapse into one random VALID key-value pair, with any addition or subtraction done to the “value.” See IndexedLDA() for context.

FOR BEST EFFICIENCY, the “values” array should be allocated aligned to a 64-byte boundary. (See the unit tests suite code for an example of how to align the allocation.)

While a QInterface represents an interacting set of qubit-based registers, or a virtual quantum chip, the registers need to interact in some way with (classical or quantum) RAM. IndexedLDA is a RAM access method similar to the X addressing mode of the MOS 6502 chip, if the X register can be in a state of coherent superposition when it loads from RAM. “IndexedADC” and “IndexedSBC” perform add and subtract (with carry) operations on a state usually initially prepared with IndexedLDA().

virtual bitCapInt Qrack::QInterface::IndexedSBC(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart, bitLenInt valueLength, bitLenInt carryIndex, unsigned char *values) = 0

Subtract from an entangled 8 bit register state with a superposed index-offset-based read from classical memory.

“inputStart” is the start index of 8 qubits that act as an index into the 256 byte “values” array. The “outputStart” bits would usually already be entangled with the “inputStart” bits via a IndexedLDA() operation. With the “inputStart” bits being a “key” and the “outputStart” bits being a value, the permutation state |key, value> is mapped to |key, value - values[key]>. This is similar to classical parallel addition of two arrays. However, when either of the registers are measured, both registers will collapse into one random VALID key-value pair, with any addition or subtraction done to the “value.” See QInterface::IndexedLDA for context.

FOR BEST EFFICIENCY, the “values” array should be allocated aligned to a 64-byte boundary. (See the unit tests suite code for an example of how to align the allocation.)

While a QInterface represents an interacting set of qubit-based registers, or a virtual quantum chip, the registers need to interact in some way with (classical or quantum) RAM. IndexedLDA is a RAM access method similar to the X addressing mode of the MOS 6502 chip, if the X register can be in a state of coherent superposition when it loads from RAM. “IndexedADC” and “IndexedSBC” perform add and subtract (with carry) operations on a state usually initially prepared with IndexedLDA().

virtual void Qrack::QInterface::Hash(bitLenInt start, bitLenInt length, unsigned char *values) = 0

Transform a length of qubit register via lookup through a hash table.

The hash table must be a one-to-one function, otherwise the behavior of this method is undefined. The value array definition convention is the same as IndexedLDA(). Essentially, this is an IndexedLDA() operation that replaces the index register with the value register, but the lookup table must therefore be one-to-one, for this operation to be unitary, as required.

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 left-multiplication in low-to-high vector index order on the state vector.

As a general point of linear algebra, where A and B are linear operators,

$$$e^{i (A + B) t} = e^{i A t} e^{i B t}$$$
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 right-to-left, by left multiplication, in the order
$$$e^{-i H_{N - 1} t} e^{-i H_{N - 2} t} \ldots e^{-i H_0 t} \left|\psi \rangle\right. .$$$
(For example, if A and B are single bit gates acting on the same bit, form their composition into one gate by the intended right-to-left fusion and apply them as a single HamiltonianOp.)
Warning
Hamiltonian components might not commute.