The Quantum Exact Simulation Toolkit v4.2.0
Loading...
Searching...
No Matches

Functions for non-destructively calculating the probabilities of measurement outcomes. More...

Functions

qreal calcProbOfBasisState (Qureg qureg, qindex index)
 
qreal calcProbOfMultiQubitOutcome (Qureg qureg, int *qubits, int *outcomes, int numQubits)
 
qreal calcProbOfQubitOutcome (Qureg qureg, int qubit, int outcome)
 
void calcProbsOfAllMultiQubitOutcomes (qreal *outcomeProbs, Qureg qureg, int *qubits, int numQubits)
 

Detailed Description

Functions for non-destructively calculating the probabilities of measurement outcomes.

Function Documentation

◆ calcProbOfBasisState()

qreal calcProbOfBasisState ( Qureg qureg,
qindex index )

Calculates the probability of the full computational basis state of the specified index. This is the probability that, when measured in the \( \hat{Z} \) basis, every qubit of qureg is consistent with the bits of index.

Indexing is little-endian and from zero, such that (for example) computational basis state \( \ket{0011} \) (where qubits at indices \(0\) and \(1\) are in the \(\ket{1}\) state) corresponds to index \( = 3 \). The maximum legal index of an \(N\)-qubit register is index \( = 2^N-1 \).

Formulae

Let \( i = \) index.

  • When qureg is a statevector \( \svpsi \), this function returns

    \[ P(i) = |\braket{i}{\psi}|^2 = |\psi_i|^2 \]

    where \(\psi_i\) is the \(i\)-th amplitude of \(\svpsi\).
  • When qureg is a density matrix \(\dmrho\), this function returns

    \[ P(i) = \re{ \tr{ \ketbra{i}{i} \dmrho } } = \re{ \bra{i} \dmrho \ket{i} } = \re{ \dmrho_{ii} } \]

    where \( \dmrho_{ii} \) is the \(i\)-th diagonal element of \(\dmrho\), and is real whenever \( \dmrho \) is valid (or at least, Hermitian).

When qureg is correctly normalised, these quantities are within \([0, 1]\), and satisfy

\[ \sum\limits_{i=0}^{2^N-1} P(i) = 1 \]

where \(N\) is the number of qubits in qureg.

Equivalences
Example
Qureg qureg = createQureg(5);
qreal prob = calcProbOfBasisState(qureg, 2);
reportScalar("prob of |00010>", prob);
qreal calcProbOfBasisState(Qureg qureg, qindex index)
void initPlusState(Qureg qureg)
Qureg createQureg(int numQubits)
Definition qureg.cpp:283
void reportScalar(const char *label, qcomp num)
Definition types.cpp:51
Parameters
[in]quregthe reference state, which is unchanged.
[in]indexthe index of the queried basis state among the ordered set of all basis states.
Returns
The probability of the basis state at index.
Exceptions
error
  • if qureg is uninitialised.
  • if index is less than zero or beyond (or equal to) the dimension of qureg.
Attention
This function's input validation has not yet been unit tested, so erroneous usage may produce unexpected output. Please use with caution!
See also
Author
Tyson Jones

Definition at line 224 of file calculations.cpp.

224 {
225 validate_quregFields(qureg, __func__);
226 validate_basisStateIndex(qureg, index, __func__);
227
228 // |i><i| = ||(1+2^N)i>>
229 if (qureg.isDensityMatrix)
230 index *= 1 + powerOf2(qureg.numQubits);
231
232 qcomp amp = localiser_statevec_getAmp(qureg, index);
233 qreal prob = (qureg.isDensityMatrix)?
234 std::real(amp):
235 std::norm(amp);
236
237 return prob;
238}

Referenced by TEST_CASE().

◆ calcProbOfMultiQubitOutcome()

qreal calcProbOfMultiQubitOutcome ( Qureg qureg,
int * qubits,
int * outcomes,
int numQubits )

Calculates the probability that the given list of qubits are simultaneously in the respective single-qubit states specified in outcomes.

Formulae

Let \(q_j\) and \(x_j\) notate the \(j\)-th qubit in qubits and its respective outcome in outcomes.

  • When qureg is a statevector \( \svpsi \), this function returns

    \[ \tr{ \bigotimes\limits_j \ketbra{x_j}{x_j}_{q_j} \; \ketbra{\psi}{\psi} } = \sum\limits_i |\psi_i|^2 \prod\limits_j \delta_{x_j, \, i_{[q_j]}} \]

    where \(\psi_i\) is the \(i\)-th amplitude of \(\svpsi\), and \(i_{[q]}\) notates the \(q\)-th bit of \(i\).
  • When qureg is a density matrix \( \dmrho \), this function returns

    \[ \tr{ \bigotimes\limits_j \ketbra{x_j}{x_j}_{q_j} \; \dmrho } = \sum\limits_i \re{\dmrho_{ii}} \prod\limits_j \delta_{x_j, \, i_{[q_j]}} \]

    where \( \dmrho_{ii} \) is the \(i\)-th diagonal element of \(\dmrho\). This is real whenever \(\dmrho\) is validly normalised (specifically, Hermitian).

When qureg is correctly normalised, these quantities are within \([0, 1]\), and their sum across all possible values of outcomes equals one.

Equivalences
  • The output of this function is equal to that found by in-turn finding the probability of each qubit being in the specified outcome, then projecting qureg into it (i.e. forcing that measurement outcome). That approach is however slower and modifies qureg, whereas this function leaves qureg unchanged.
    qreal prob = 1;
    for (int j=0; j<numQubits; j++)
    prob *= applyForcedQubitMeasurement(qureg, qubits[j], outcomes[j]);
    qreal applyForcedQubitMeasurement(Qureg qureg, int target, int outcome)
  • This function is much faster than, but mathematically equivalent to, summing the probability of every computational basis state (e.g. via calcProbOfBasisState()) which is consistent with the given qubit outcomes.
Example
Qureg qureg = createQureg(5);
int num = 3;
int qubits[] = {0, 3, 4};
int outcomes[] = {1, 1, 0};
qreal prob = calcProbOfMultiQubitOutcome(qureg, qubits, outcomes, num);
void initRandomPureState(Qureg qureg)
Parameters
[in]quregthe reference state, which is unchanged.
[in]qubitsa list of target qubits to query.
[in]outcomesa list of corresponding qubit outcomes (each 0 or 1).
[in]numQubitsthe length of list qubits (and outcomes).
Returns
The probability that the given qubits are simultaneously in the specified outcomes.
Exceptions
error
  • if qureg is uninitialised.
  • if qubits contains any duplicates.
  • if any element of qubits is less than zero or beyond the number of qubits in qureg.
  • if any element of outcomes is not 0 or 1.
  • if numQubits is less than one or exceeds the number of qubits in qureg.
seg-fault
  • if either of qubits or outcomes are not lists of length numQubits.
Attention
This function's input validation has not yet been unit tested, so erroneous usage may produce unexpected output. Please use with caution!
See also
Author
Tyson Jones

Definition at line 251 of file calculations.cpp.

251 {
252 validate_quregFields(qureg, __func__);
253 validate_targets(qureg, qubits, numQubits, __func__);
254 validate_measurementOutcomesAreValid(outcomes, numQubits, __func__);
255
256 auto qubitVec = util_getVector(qubits, numQubits);
257 auto outcomeVec = util_getVector(outcomes, numQubits);
258
259 return (qureg.isDensityMatrix)?
260 localiser_densmatr_calcProbOfMultiQubitOutcome(qureg, qubitVec, outcomeVec):
261 localiser_statevec_calcProbOfMultiQubitOutcome(qureg, qubitVec, outcomeVec);
262}

Referenced by applyForcedMultiQubitMeasurement(), calcProbOfMultiQubitOutcome(), calcProbOfQubitOutcome(), and TEST_CASE().

◆ calcProbOfQubitOutcome()

qreal calcProbOfQubitOutcome ( Qureg qureg,
int qubit,
int outcome )

Calculates the probability of the single qubit at index qubit being in the given computational basis outcome (0 or 1).

Formulae

Let \( q = \) qubit and \( x = \) outcome, and let \(\ketbra{x}{x}_q\) notate a projector operating upon qubit \( q \).

  • When qureg is a statevector \( \svpsi \), this function returns

    \[ P_q(x) = \tr{ \ketbra{x}{x}_q \, \ketbra{\psi}{\psi} } = \sum\limits_i |\psi_i|^2 \delta_{x,i_{[q]}} \]

    where \(\psi_i\) is the \(i\)-th amplitude of \(\svpsi\), and \(i_{[q]}\) notates the \(q\)-th bit of \(i\).
  • When qureg is a density matrix \( \dmrho \), this function returns

    \[ P_q(x) = \tr{ \ketbra{x}{x}_q \, \dmrho } = \sum\limits_i \re{ \dmrho_{ii} } \delta_{x,i_{[q]}} \]

    where \( \dmrho_{ii} \) is the \(i\)-th diagonal element of \(\dmrho\). This is real whenever \(\dmrho\) is validly normalised (specifically, Hermitian).

When qureg is correctly normalised, these quantities are within \([0, 1]\), and satisfy

\[ P_q(x=0) + P_q(x=1) = 1. \]

Equivalences
  • This function is a single-qubit convenience overload of calcProbOfMultiQubitOutcome(), which itself has optimised implementations for few-qubit outcomes.
    calcProbOfMultiQubitOutcome(qureg, &qubit, &outcome, 1);
  • This function is much faster than, but mathematically equivalent to, summing the probability of every computational basis state (e.g. via calcProbOfBasisState()) which is consistent with the given qubit outcome.
    qreal prob = 0;
    qindex dim = 1 << qureg.numQubits;
    for (qindex i=0; i<dim; i++)
    if (outcome == (i >> qubit) & 1)
    prob += calcProbOfBasisState(qureg, i);
Example
Qureg qureg = createQureg(5);
int qubit = 2;
int outcome = 1;
qreal theta = 0.3;
applyRotateX(qureg, qubit, theta);
// prob = cos(theta/2)^2
qreal prob = calcProbOfQubitOutcome(qureg, qubit, outcome);
qreal calcProbOfQubitOutcome(Qureg qureg, int qubit, int outcome)
void applyRotateX(Qureg qureg, int target, qreal angle)
Parameters
[in]quregthe reference state, which is unchanged.
[in]qubitthe target qubit to query.
[in]outcomethe outcome of qubit to query (i.e. 0 oe 1).
Returns
The probability that the given qubit is in the given outcome.
Exceptions
error
  • if qureg is uninitialised.
  • if qubit is less than zero or beyond the number of qubits in qureg.
  • if outcome is not 0 or 1.
Attention
This function's input validation has not yet been unit tested, so erroneous usage may produce unexpected output. Please use with caution!
See also
Author
Tyson Jones

Definition at line 241 of file calculations.cpp.

241 {
242 validate_quregFields(qureg, __func__);
243 validate_target(qureg, qubit, __func__);
244 validate_measurementOutcomeIsValid(outcome, __func__);
245
246 int numQubits = 1;
247 return calcProbOfMultiQubitOutcome(qureg, &qubit, &outcome, numQubits);
248}

Referenced by applyForcedQubitMeasurement(), applyQubitMeasurementAndGetProb(), and TEST_CASE().

◆ calcProbsOfAllMultiQubitOutcomes()

void calcProbsOfAllMultiQubitOutcomes ( qreal * outcomeProbs,
Qureg qureg,
int * qubits,
int numQubits )

Populates outcomeProbs with the probabilities of the specified list of qubits being in all of their possible, simultaneous outcomes (of which there are 2^ numQubits).

The list qubits is taken to be in order of increasing significance, determining the ordering of the output outcomeProbs. For example, if qubits \( = \{ 1, 3 \} \), then outcomeProbs will be populated with four values; the probabilities of qubits \((3,1)\) being in the respective simultaneously outcomes \((0,0), \, (0,1), \, (1,0) \) and \((1,1)\). In contrast, qubits \( = \{ 3, 1 \} \) would see the middle two outputs swapped.

Formulae

Let \( n = \) numQubits, and \( q_i \) be the \(i\)-th element of qubits, such that qubits = \( \{ q_0, q_1, \dots, q_{n-1} \} \). Let \( P_{\ket{q_{n-1} \dots q_1 q_0}}(\ket{i}) \) denote the probability that the specified substate is in the computational basis substate \(\ket{i}\). Explicitly, that qubit \(q_j\) is in the outcome given by the \(j\)-th bit of \(n\)-digit integer \(i\) (simultaneously for all \(j\)).

Then, this function sets

\[ \text{outcomeProbs}[i] = P_{\ket{q_{n-1} \dots q_1 q_0}}(\ket{i}) \]

for all \(i \in \{0, 1, \dots 2^n-1\} \).

Explicitly, expressing substate \(\ket{i}\) in terms of its individual qubits;

\[ \begin{gathered} \text{outcomeProbs}[0] = P_{\ket{q_{n-1} \dots q_1 q_0}}( \ket{0\dots00} ) \\ \text{outcomeProbs}[1] = P_{\ket{q_{n-1} \dots q_1 q_0}}( \ket{0\dots01} ) \\ \text{outcomeProbs}[2] = P_{\ket{q_{n-1} \dots q_1 q_0}}( \ket{0\dots10} ) \\ \text{outcomeProbs}[3] = P_{\ket{q_{n-1} \dots q_1 q_0}}( \ket{0\dots11} ) \\ \vdots \\ \text{outcomeProbs}[2^n-1] = P_{\ket{q_{n-1} \dots q_1 q_0}}( \ket{1\dots11} ) \end{gathered} \]

Each probability is that which would be output by calcProbOfMultiQubitOutcome() when passed qubits and the bits of \( i \).

When qureg is correctly normalised, all probabilities are within \([0, 1]\), and the sum of all elements written to outcomeProbs equals one.

Equivalences
  • This function is significantly faster than, but otherwise equivalent to, populating each element of outcomeProbs in-turn with the output of calcProbOfMultiQubitOutcome().
    qindex numOut = (1 << numQubits);
    for (qindex i=0; i<numOut; i++) {
    // set outcomes to the bits of i
    int outcomes[numQubits];
    for (int j=0; j<numQubits; j++)
    outcomes[j] = (i >> j) & 1;
    outcomeProbs[i] = calcProbOfMultiQubitOutcome(qureg, qubits, outcomes, numQubits);
    }
Example
Qureg qureg = createQureg(5);
int num = 3;
int qubits[] = {0, 3, 4};
qreal probs[8];
calcProbsOfAllMultiQubitOutcomes(probs, qureg, qubits, num);
void calcProbsOfAllMultiQubitOutcomes(qreal *outcomeProbs, Qureg qureg, int *qubits, int numQubits)
Parameters
[out]outcomeProbsthe array to which the output is written.
[in]quregthe reference state, which is unchanged.
[in]qubitsa list of target qubits to query.
[in]numQubitsthe length of list qubits.
Exceptions
error
  • if qureg is uninitialised.
  • if qubits contains any duplicates.
  • if any element of qubits is less than zero or beyond the number of qubits in qureg.
  • if numQubits is less than one or exceeds the number of qubits in qureg.
seg-fault
  • if outcomeProbs is not a pre-allocated list of length 2^ numQubits.
  • if qubits is not a list of length numQubits.
Attention
This function's input validation has not yet been unit tested, so erroneous usage may produce unexpected output. Please use with caution!
See also
Author
Tyson Jones

Definition at line 265 of file calculations.cpp.

265 {
266 validate_quregFields(qureg, __func__);
267 validate_targets(qureg, qubits, numQubits, __func__);
268 validate_measurementOutcomesFitInGpuMem(qureg, numQubits, __func__);
269
270 auto qubitVec = util_getVector(qubits, numQubits);
271
272 (qureg.isDensityMatrix)?
273 localiser_densmatr_calcProbsOfAllMultiQubitOutcomes(outcomeProbs, qureg, qubitVec):
274 localiser_statevec_calcProbsOfAllMultiQubitOutcomes(outcomeProbs, qureg, qubitVec);
275}

Referenced by applyMultiQubitMeasurementAndGetProb(), calcProbsOfAllMultiQubitOutcomes(), and TEST_CASE().