Calculations

Calculations and property-getters which do not modify the studied quantum state. More...

Functions

qreal calcDensityInnerProduct (Qureg rho1, Qureg rho2)
 Computes the Hilbert-Schmidt scalar product (which is equivalent to the Frobenius inner product of matrices) of two density matrices rho1 and rho2 of equivalent size. More...
 
Complex calcExpecDiagonalOp (Qureg qureg, DiagonalOp op)
 Computes the expected value of the diagonal operator op for state qureg. More...
 
qreal calcExpecPauliHamil (Qureg qureg, PauliHamil hamil, Qureg workspace)
 Computes the expected value of qureg under Hermitian operator hamil. More...
 
qreal calcExpecPauliProd (Qureg qureg, int *targetQubits, enum pauliOpType *pauliCodes, int numTargets, Qureg workspace)
 Computes the expected value of a product of Pauli operators. More...
 
qreal calcExpecPauliSum (Qureg qureg, enum pauliOpType *allPauliCodes, qreal *termCoeffs, int numSumTerms, Qureg workspace)
 Computes the expected value of a sum of products of Pauli operators. More...
 
qreal calcFidelity (Qureg qureg, Qureg pureState)
 Calculates the fidelity of qureg (a statevector or density matrix) against a reference pure state (necessarily a statevector). More...
 
qreal calcHilbertSchmidtDistance (Qureg a, Qureg b)
 Computes the Hilbert Schmidt distance between two density matrices a and b, defined as the Frobenius norm of the difference between them. More...
 
Complex calcInnerProduct (Qureg bra, Qureg ket)
 Computes the inner product $ \langle \text{bra} | \text{ket} \rangle $ of two equal-size state vectors, given by. More...
 
qreal calcProbOfOutcome (Qureg qureg, int measureQubit, int outcome)
 Gives the probability of a specified qubit being measured in the given outcome (0 or 1). More...
 
qreal calcPurity (Qureg qureg)
 Calculates the purity of a density matrix, by the trace of the density matrix squared. More...
 
qreal calcTotalProb (Qureg qureg)
 A debugging function which calculates the probability of the qubits in qureg being in any state, which should always be 1 for correctly normalised states (hence returning a real number). More...
 
Complex getAmp (Qureg qureg, long long int index)
 Get the complex amplitude at a given index in the state vector. More...
 
Complex getDensityAmp (Qureg qureg, long long int row, long long int col)
 Get an amplitude from a density matrix at a given row and column. More...
 
qreal getImagAmp (Qureg qureg, long long int index)
 Get the imaginary component of the complex probability amplitude at an index in the state vector. More...
 
long long int getNumAmps (Qureg qureg)
 Get the number of probability amplitudes in a qureg object, given by 2^numQubits. More...
 
int getNumQubits (Qureg qureg)
 Get the number of qubits in a qureg object. More...
 
qreal getProbAmp (Qureg qureg, long long int index)
 Get the probability of a state-vector at an index in the full state vector. More...
 
qreal getRealAmp (Qureg qureg, long long int index)
 Get the real component of the complex probability amplitude at an index in the state vector. More...
 

Detailed Description

Calculations and property-getters which do not modify the studied quantum state.

Function Documentation

◆ calcDensityInnerProduct()

qreal calcDensityInnerProduct ( Qureg  rho1,
Qureg  rho2 
)

Computes the Hilbert-Schmidt scalar product (which is equivalent to the Frobenius inner product of matrices) of two density matrices rho1 and rho2 of equivalent size.

That is, we define the Hilbert-Schmidt scalar product

\[ ((\rho_1, \rho_2))_{HS} := \text{Tr}[ \rho_1^\dagger \rho_2 ], \]

which is equivalent to the sum of products of matrix elemets, i.e.,

\[ ((\rho_1, \rho_2))_{HS} = \sum\limits_i \sum\limits_j (\rho_1)_{ij}^* (\rho_2)_{ij} \]

Assuming that both density matrices are Hermitian, the resulting scalar product is real and invariant under reordering its arguments as

\[ ((\rho_1, \rho_2))_{HS} = ((\rho_2, \rho_1))_{HS} = \text{Tr}[\rho_1 \rho_2] \]

If both rho1 and rho2 are density matrices of pure states bra and ket, then the equality holds

\[ ((\rho_1, \rho_2))_{HS} = |\langle \text{bra} | \text{ket} \rangle|^2. \]

If either or both of rho1 and rho2 are non Hermitian (i.e. invalid density matrices), then this function returns the real component of the scalar product, and discards the imaginary component. That is, it returns

\[ \text{Re}\{ \text{Tr}[ \rho_1^\dagger \rho_2 ] \} = \text{Re}\{ \text{Tr}[ \rho_2^\dagger \rho_1 ] \}. \]

This is still sometimes useful, e.g. in calculating the inner product with an anti-commutator, e.g. (for Hermitian $ \sigma $, $ \rho $, $ H $)

\[ ((\sigma, H \rho + \rho H))_{HS} = 2 \; \text{Re} \{ ((\sigma, H \rho))_{HS} \} \]

where $ H \rho $ could be a weighted sum of Pauli products applied to $ \rho $ through applyPauliSum().

Parameters
[in]rho1qureg as a density matrix (to have its values conjugate transposed)
[in]rho2qureg as a density matrix
Returns
the real Hilbert-Schmidt scalar product of density matrices rho1 and rho2 (assuming Hermiticity)
Exceptions
invalidQuESTInputErrorif rho1 and rho2 are not density matrices or have mismatching dimensions.
Author
Balint Koczor (CPU)
Tyson Jones (GPU)

Definition at line 918 of file QuEST.c.

918  {
919  validateDensityMatrQureg(rho1, __func__);
920  validateDensityMatrQureg(rho2, __func__);
921  validateMatchingQuregDims(rho1, rho2, __func__);
922 
923  return densmatr_calcInnerProduct(rho1, rho2);
924 }

References densmatr_calcInnerProduct(), validateDensityMatrQureg(), and validateMatchingQuregDims().

Referenced by TEST_CASE().

◆ calcExpecDiagonalOp()

Complex calcExpecDiagonalOp ( Qureg  qureg,
DiagonalOp  op 
)

Computes the expected value of the diagonal operator op for state qureg.

Since op is not necessarily Hermitian, the expected value may be a complex number.

Let $ D $ be the diagonal operator op, with diagonal elements $ d_i $. Then if qureg is a state-vector $|\psi\rangle $, this function computes

\[ \langle \psi | D | \psi \rangle = \sum_i |\psi_i|^2 \, d_i \]

If qureg is a density matrix $ \rho $, this function computes

\[ \text{Trace}( D \rho ) = \sum_i \rho_{ii} \, d_i \]

Parameters
[in]qurega state-vector or density matrix
[in]opthe diagonal operator to compute the expected value of
Returns
the expected vaulue of the operator
Exceptions
invalidQuESTInputErrorif op was not created, or if op acts on a different number of qubits than qureg represents.
Author
Tyson Jones

Definition at line 979 of file QuEST.c.

979  {
980  validateDiagonalOp(qureg, op, __func__);
981 
982  if (qureg.isDensityMatrix)
983  return densmatr_calcExpecDiagonalOp(qureg, op);
984  else
985  return statevec_calcExpecDiagonalOp(qureg, op);
986 }

References densmatr_calcExpecDiagonalOp(), Qureg::isDensityMatrix, statevec_calcExpecDiagonalOp(), and validateDiagonalOp().

Referenced by TEST_CASE().

◆ calcExpecPauliHamil()

qreal calcExpecPauliHamil ( Qureg  qureg,
PauliHamil  hamil,
Qureg  workspace 
)

Computes the expected value of qureg under Hermitian operator hamil.

Represent hamil as $ H = \sum_i c_i \otimes_j^{N} \hat{\sigma}_{i,j} $ (where $ c_i \in $ hamil.termCoeffs and $ N = $ hamil.numQubits). This function computes $ \langle \psi | H | \psi \rangle $ if qureg = $ \psi $ is a statevector, and computes $ \text{Trace}(H \rho) =\text{Trace}(\rho H) $ if qureg = $ \rho $ is a density matrix.

This function is merely an encapsulation of calcExpecPauliSum() - refer to the doc there for an elaboration.

workspace must be a register with the same type (statevector vs density matrix) and dimensions (number of represented qubits) as qureg and hamil, and is used as working space. When this function returns, qureg will be unchanged and workspace will be set to qureg pre-multiplied with the final Pauli product in hamil. NOTE that if qureg is a density matrix, workspace will become $ \hat{\sigma} \rho $ which is itself not a density matrix (it is distinct from $ \hat{\sigma} \rho \hat{\sigma}^\dagger $).

This function works by cloning the qureg state into workspace, applying each of the specified Pauli products in hamil to workspace (one Pauli operation at a time), then computing its inner product with qureg (for statevectors) or its trace (for density matrices) multiplied with the corresponding coefficient, and summing these contributions. It therefore should scale linearly in time with the total number of non-identity specified Pauli operators.

Parameters
[in]quregthe register of which to find the expected value, which is unchanged by this function
[in]hamila PauliHamil created with createPauliHamil() or createPauliHamilFromFile()
[in,out]workspacea working-space qureg with the same dimensions as qureg, which is modified to be the result of multiplying the state with the final specified Pauli product
Exceptions
invalidQuESTInputErrorif any code in hamil.pauliCodes is not a valid Pauli code, or if hamil.numSumTerms <= 0, or if workspace is not of the same type and dimensions as qureg and hamil
Author
Tyson Jones

Definition at line 970 of file QuEST.c.

970  {
971  validateMatchingQuregTypes(qureg, workspace, __func__);
972  validateMatchingQuregDims(qureg, workspace, __func__);
973  validatePauliHamil(hamil, __func__);
974  validateMatchingQuregPauliHamilDims(qureg, hamil, __func__);
975 
976  return statevec_calcExpecPauliSum(qureg, hamil.pauliCodes, hamil.termCoeffs, hamil.numSumTerms, workspace);
977 }

References PauliHamil::numSumTerms, PauliHamil::pauliCodes, statevec_calcExpecPauliSum(), PauliHamil::termCoeffs, validateMatchingQuregDims(), validateMatchingQuregPauliHamilDims(), validateMatchingQuregTypes(), and validatePauliHamil().

Referenced by TEST_CASE().

◆ calcExpecPauliProd()

qreal calcExpecPauliProd ( Qureg  qureg,
int *  targetQubits,
enum pauliOpType pauliCodes,
int  numTargets,
Qureg  workspace 
)

Computes the expected value of a product of Pauli operators.

Letting $ \sigma = \otimes_j \hat{\sigma}_j $ be the operators indicated by pauliCodes and acting on qubits targetQubits, this function computes $ \langle \psi | \sigma | \psi \rangle $ if qureg = $ \psi $ is a statevector, and computes $ \text{Trace}(\sigma \rho) $ if qureg = $ \rho $ is a density matrix.

pauliCodes is an array of length numTargets which specifies which Pauli operators to enact on the corresponding qubits in targetQubits, where 0 = PAULI_I, 1 = PAULI_X, 2 = PAULI_Y, 3 = PAULI_Z. The target qubits must be unique, and at most qureg.numQubitsRepresented may be specified. For example, on a 7-qubit statevector,

calcExpecPauliProd(qureg, {4,5,6}, {PAULI_X, PAULI_I, PAULI_Z}, 3, workspace);

will compute $ \langle \psi | I I I I X I Z | \psi \rangle $ (where in this notation, the left-most operator applies to the least-significant qubit, i.e. that with index 0).

workspace must be a register with the same type (statevector vs density matrix) and dimensions (number of represented qubits) as qureg, and is used as working space. When this function returns, qureg will be unchanged and workspace will be set to $ \sigma | \psi \rangle $ (if qureg is a statevector) or $ \sigma \rho $ (if qureg is a density matrix). NOTE that this last quantity is NOT the result of applying the paulis as unitaries, $ \sigma^\dagger \rho \sigma $, but is instead the result of their direct multiplication with the density matrix. It is therefore itself not a valid density matrix.

This function works by cloning the qureg state into workspace, applying the specified Pauli operators to workspace then computing its inner product with qureg (for statevectors) or its trace (for density matrices). It therefore should scale linearly in time with the number of specified non-identity Pauli operators, which is bounded by the number of represented qubits.

Parameters
[in]quregthe register of which to find the expected value, which is unchanged by this function
[in]targetQubitsa list of the indices of the target qubits
[in]pauliCodesa list of the Pauli codes (0=PAULI_I, 1=PAULI_X, 2=PAULI_Y, 3=PAULI_Z) to apply to the corresponding qubits in targetQubits
[in]numTargetsnumber of target qubits, i.e. the length of targetQubits and pauliCodes
[in,out]workspacea working-space qureg with the same dimensions as qureg, which is modified to be the result of multiplying the state with the pauli operators
Exceptions
invalidQuESTInputErrorif numTargets is outside [1, qureg.numQubitsRepresented]), or if any qubit in targetQubits is outside [0, qureg.numQubitsRepresented)) or if any qubit in targetQubits is repeated, or if any code in pauliCodes is not in {0,1,2,3}, or if workspace is not of the same type and dimensions as qureg
Author
Tyson Jones

Definition at line 952 of file QuEST.c.

952  {
953  validateMultiTargets(qureg, targetQubits, numTargets, __func__);
954  validatePauliCodes(pauliCodes, numTargets, __func__);
955  validateMatchingQuregTypes(qureg, workspace, __func__);
956  validateMatchingQuregDims(qureg, workspace, __func__);
957 
958  return statevec_calcExpecPauliProd(qureg, targetQubits, pauliCodes, numTargets, workspace);
959 }

References statevec_calcExpecPauliProd(), validateMatchingQuregDims(), validateMatchingQuregTypes(), validateMultiTargets(), and validatePauliCodes().

Referenced by TEST_CASE().

◆ calcExpecPauliSum()

qreal calcExpecPauliSum ( Qureg  qureg,
enum pauliOpType allPauliCodes,
qreal termCoeffs,
int  numSumTerms,
Qureg  workspace 
)

Computes the expected value of a sum of products of Pauli operators.

Let $ H = \sum_i c_i \otimes_j^{N} \hat{\sigma}_{i,j} $ be the operators indicated by allPauliCodes (where $ c_i \in $ termCoeffs and $ N = $ qureg.numQubitsRepresented). This function computes $ \langle \psi | H | \psi \rangle $ if qureg = $ \psi $ is a statevector, and computes $ \text{Trace}(H \rho) =\text{Trace}(\rho H) $ if qureg = $ \rho $ is a density matrix.

allPauliCodes is an array of length numSumTerms*qureg.numQubitsRepresented which specifies which Pauli operators to apply, where 0 = PAULI_I, 1 = PAULI_X, 2 = PAULI_Y, 3 = PAULI_Z. For each sum term, a Pauli operator must be specified for EVERY qubit in qureg; each set of numSumTerms operators will be grouped into a product. termCoeffs is an arrray of length numSumTerms containing the term coefficients. For example, on a 3-qubit statevector,

int paulis[6] = {PAULI_X, PAULI_I, PAULI_I,  PAULI_X, PAULI_Y, PAULI_Z};
qreal coeffs[2] = {1.5, -3.6};
calcExpecPauliSum(qureg, paulis, coeffs, 2, workspace);

will compute $ \langle \psi | (1.5 X I I - 3.6 X Y Z) | \psi \rangle $ (where in this notation, the left-most operator applies to the least-significant qubit, i.e. that with index 0).

workspace must be a register with the same type (statevector vs density matrix) and dimensions (number of represented qubits) as qureg, and is used as working space. When this function returns, qureg will be unchanged and workspace will be set to qureg pre-multiplied with the final Pauli product. NOTE that if qureg is a density matrix, workspace will become $ \hat{\sigma} \rho $ which is itself not a density matrix (it is distinct from $ \hat{\sigma} \rho \hat{\sigma}^\dagger $).

This function works by cloning the qureg state into workspace, applying each of the specified Pauli products to workspace (one Pauli operation at a time), then computing its inner product with qureg (for statevectors) or its trace (for density matrices) multiplied with the corresponding coefficient, and summing these contributions. It therefore should scale linearly in time with the total number of non-identity specified Pauli operators.

Parameters
[in]quregthe register of which to find the expected value, which is unchanged by this function
[in]allPauliCodesa list of the Pauli codes (0=PAULI_I, 1=PAULI_X, 2=PAULI_Y, 3=PAULI_Z) of all Paulis involved in the products of terms. A Pauli must be specified for each qubit in the register, in every term of the sum.
[in]termCoeffsThe coefficients of each term in the sum of Pauli products
[in]numSumTermsThe total number of Pauli products specified
[in,out]workspacea working-space qureg with the same dimensions as qureg, which is modified to be the result of multiplying the state with the final specified Pauli product
Exceptions
invalidQuESTInputErrorif any code in allPauliCodes is not in {0,1,2,3}, or if numSumTerms <= 0, or if workspace is not of the same type and dimensions as qureg
Author
Tyson Jones

Definition at line 961 of file QuEST.c.

961  {
962  validateNumPauliSumTerms(numSumTerms, __func__);
963  validatePauliCodes(allPauliCodes, numSumTerms*qureg.numQubitsRepresented, __func__);
964  validateMatchingQuregTypes(qureg, workspace, __func__);
965  validateMatchingQuregDims(qureg, workspace, __func__);
966 
967  return statevec_calcExpecPauliSum(qureg, allPauliCodes, termCoeffs, numSumTerms, workspace);
968 }

References Qureg::numQubitsRepresented, statevec_calcExpecPauliSum(), validateMatchingQuregDims(), validateMatchingQuregTypes(), validateNumPauliSumTerms(), and validatePauliCodes().

Referenced by TEST_CASE().

◆ calcFidelity()

qreal calcFidelity ( Qureg  qureg,
Qureg  pureState 
)

Calculates the fidelity of qureg (a statevector or density matrix) against a reference pure state (necessarily a statevector).

If qureg is a state-vector, this function computes

\[ |\langle \text{qureg} | \text{pureState} \rangle|^2 \]

If qureg is a density matrix, this function computes

\[ \langle \text{pureState} | \text{qureg} | \text{pureState} \rangle \]

In either case, the returned fidelity lies in [0, 1] (assuming both input states have valid normalisation). If any of the input Quregs are not normalised, this function will return the real component of the correct linear algebra calculation.

The number of qubits represented in qureg and pureState must match.

Parameters
[in]qurega density matrix or state vector
[in]pureStatea state vector
Returns
the fidelity between the input registers
Exceptions
invalidQuESTInputErrorif the second argument (pureState) is not a statevector, or if the number of qubits in qureg and pureState do not match
Author
Tyson Jones

Definition at line 942 of file QuEST.c.

942  {
943  validateSecondQuregStateVec(pureState, __func__);
944  validateMatchingQuregDims(qureg, pureState, __func__);
945 
946  if (qureg.isDensityMatrix)
947  return densmatr_calcFidelity(qureg, pureState);
948  else
949  return statevec_calcFidelity(qureg, pureState);
950 }

References densmatr_calcFidelity(), Qureg::isDensityMatrix, statevec_calcFidelity(), validateMatchingQuregDims(), and validateSecondQuregStateVec().

Referenced by TEST_CASE().

◆ calcHilbertSchmidtDistance()

qreal calcHilbertSchmidtDistance ( Qureg  a,
Qureg  b 
)

Computes the Hilbert Schmidt distance between two density matrices a and b, defined as the Frobenius norm of the difference between them.

That is, we define the Hilbert Schmidt distance

\[ D(a, b) = \| a - b \|_F = \sqrt{ \text{Tr}[ (a-b)(a-b)^\dagger ] } \]

This is equivalent to the square-root of the sum of the absolute value squared of the element-differences of the matrices, i.e.

\[ D(a, b) = \sqrt{ \sum\limits_i \sum\limits_j | a_{ij} - b_{ij} |^2 } \]

We caution this may differ by some definitions of the Hilbert Schmidt distance by a square-root.

This function correctly returns the result of the above formulations even when a and b are incorrectly normalised (i.e. are general matrices).

Parameters
[in]aa density matrix
[in]ban equally-sized density matrix
Exceptions
invalidQuESTInputErrorif either a or b are not density matrices, or if a and have mismatching dimensions.
Author
Balint Koczor
Tyson Jones (refactored, doc)

Definition at line 988 of file QuEST.c.

988  {
989  validateDensityMatrQureg(a, __func__);
990  validateDensityMatrQureg(b, __func__);
991  validateMatchingQuregDims(a, b, __func__);
992 
994 }

References densmatr_calcHilbertSchmidtDistance(), validateDensityMatrQureg(), and validateMatchingQuregDims().

Referenced by TEST_CASE().

◆ calcInnerProduct()

Complex calcInnerProduct ( Qureg  bra,
Qureg  ket 
)

Computes the inner product $ \langle \text{bra} | \text{ket} \rangle $ of two equal-size state vectors, given by.

\[ \langle \text{bra} | \text{ket} \rangle = \sum_i {\text{bra}_i}^* \; \times \; \text{ket}_i \]

The same qureg may be passed as both bra and ket, though we recommend users check state-vector normalisation with calcTotalProb which employs Kahan summation for greater accuracy. Neither state-vector is modified.

This function returns the correct inner product even if bra and ket are not correctly normalised states.

Parameters
[in]braqureg to be the 'bra' (i.e. have its values conjugate transposed) in the inner product
[in]ketqureg to be the 'ket' in the inner product
Returns
the complex inner product of bra and ket
Exceptions
invalidQuESTInputErrorif either bra or ket are not state-vectors, or if bra and ket do not have equal dimensions.
Author
Tyson Jones

Definition at line 910 of file QuEST.c.

910  {
911  validateStateVecQureg(bra, __func__);
912  validateStateVecQureg(ket, __func__);
913  validateMatchingQuregDims(bra, ket, __func__);
914 
915  return statevec_calcInnerProduct(bra, ket);
916 }

References statevec_calcInnerProduct(), validateMatchingQuregDims(), and validateStateVecQureg().

Referenced by TEST_CASE().

◆ calcProbOfOutcome()

qreal calcProbOfOutcome ( Qureg  qureg,
int  measureQubit,
int  outcome 
)

Gives the probability of a specified qubit being measured in the given outcome (0 or 1).

This performs no actual measurement and does not change the state of the qubits.

For state-vectors, this function works by summing the absolute-value-squared of every amplitude in the state-vector for which measureQubit = 0. If outcome = 1, it returns 1 minus this value. Hence for unnormalised state-vectors, this result will differ from the absolute-value-squared of every amplitude where measureQubit = outcome.

For density matrices, this function sums the diagonal values (should be real) corresponding to measureQubit = 0 (returning 1 minus this if outcome = 1).

Parameters
[in]quregobject representing the set of all qubits
[in]measureQubitqubit to study
[in]outcomefor which to find the probability of the qubit being measured in
Returns
probability of qubit measureQubit being measured in the given outcome
Exceptions
invalidQuESTInputErrorif measureQubit is outside [0, qureg.numQubitsRepresented), or if outcome is not in {0, 1}.
Author
Ania Brown (state-vector)
Tyson Jones (density matrix)

Definition at line 926 of file QuEST.c.

926  {
927  validateTarget(qureg, measureQubit, __func__);
928  validateOutcome(outcome, __func__);
929 
930  if (qureg.isDensityMatrix)
931  return densmatr_calcProbOfOutcome(qureg, measureQubit, outcome);
932  else
933  return statevec_calcProbOfOutcome(qureg, measureQubit, outcome);
934 }

References densmatr_calcProbOfOutcome(), Qureg::isDensityMatrix, statevec_calcProbOfOutcome(), validateOutcome(), and validateTarget().

Referenced by TEST_CASE().

◆ calcPurity()

qreal calcPurity ( Qureg  qureg)

Calculates the purity of a density matrix, by the trace of the density matrix squared.

Returns $\text{Tr}(\rho^2)$. For a pure state, this =1. For a mixed state, the purity is less than 1 and is lower bounded by 1/2^n, where n is the number of qubits. The minimum purity is achieved for the maximally mixed state identity/2^n.

This function does not accept state-vectors, which clearly have purity 1.

Note this function will give incorrect results for non-Hermitian Quregs (i.e. invalid density matrices), which will disagree with $\text{Tr}(\rho^2)$. Instead, this function returns $\sum_{ij} |\rho_{ij}|^2 $.

Parameters
[in]qurega density matrix of which to measure the purity
Returns
the purity
Exceptions
invalidQuESTInputErrorif either combineQureg or otherQureg are not density matrices, or if the dimensions of combineQureg and otherQureg do not match, or if prob is not in [0, 1]
Author
Tyson Jones

Definition at line 936 of file QuEST.c.

936  {
937  validateDensityMatrQureg(qureg, __func__);
938 
939  return densmatr_calcPurity(qureg);
940 }

References densmatr_calcPurity(), and validateDensityMatrQureg().

Referenced by TEST_CASE().

◆ calcTotalProb()

qreal calcTotalProb ( Qureg  qureg)

A debugging function which calculates the probability of the qubits in qureg being in any state, which should always be 1 for correctly normalised states (hence returning a real number).

For state-vectors $ \psi $, this is the norm of the entire state-vector (the sum of the absolute-value-squared of every amplitude):

\[ \sum\limits_i |\psi_i|^2 \]

and for density matrices $ \rho $, it is the trace:

\[ \text{Trace}(\rho) = \sum\limits_i \rho_{i,i} \; \]

For un-normalised density matrices (those directly modified or initialised by the user), this function returns the real component of the trace.

Note this calculation utilises Kahan summation for greater accuracy, and hence is not parallelised and so will be slower than other functions.

Parameters
[in]quregobject representing a set of qubits
Returns
the total probability of the qubits in qureg being in any state
Author
Ania Brown (state-vector)
Tyson Jones (density matrix, doc)

Definition at line 903 of file QuEST.c.

903  {
904  if (qureg.isDensityMatrix)
905  return densmatr_calcTotalProb(qureg);
906  else
907  return statevec_calcTotalProb(qureg);
908 }

References densmatr_calcTotalProb(), Qureg::isDensityMatrix, and statevec_calcTotalProb().

Referenced by TEST_CASE().

◆ getAmp()

Complex getAmp ( Qureg  qureg,
long long int  index 
)

Get the complex amplitude at a given index in the state vector.

Parameters
[in]quregobject representing a set of qubits
[in]indexindex in state vector of probability amplitudes
Returns
amplitude at index, returned as a Complex struct (with .real and .imag attributes)
Exceptions
invalidQuESTInputErrorif qureg is a density matrix, or if index is outside [0, $2^{N}$) where $N = $ qureg.numQubitsRepresented
Author
Tyson Jones

Definition at line 699 of file QuEST.c.

699  {
700  validateStateVecQureg(qureg, __func__);
701  validateAmpIndex(qureg, index, __func__);
702 
703  Complex amp;
704  amp.real = statevec_getRealAmp(qureg, index);
705  amp.imag = statevec_getImagAmp(qureg, index);
706  return amp;
707 }

References Complex::imag, Complex::real, statevec_getImagAmp(), statevec_getRealAmp(), validateAmpIndex(), and validateStateVecQureg().

Referenced by TEST_CASE().

◆ getDensityAmp()

Complex getDensityAmp ( Qureg  qureg,
long long int  row,
long long int  col 
)

Get an amplitude from a density matrix at a given row and column.

Parameters
[in]quregobject representing a density matrix
[in]rowrow of the desired amplitude in the density matrix
[in]colcolumn of the desired amplitude in the density matrix
Returns
a Complex scalar representing the desired amplitude
Exceptions
invalidQuESTInputErrorif qureg is a statevector, or if row or col are outside [0, $2^{N}$) where $N = $ qureg.numQubitsRepresented
Author
Tyson Jones

Definition at line 709 of file QuEST.c.

709  {
710  validateDensityMatrQureg(qureg, __func__);
711  validateAmpIndex(qureg, row, __func__);
712  validateAmpIndex(qureg, col, __func__);
713 
714  long long ind = row + col*(1LL << qureg.numQubitsRepresented);
715  Complex amp;
716  amp.real = statevec_getRealAmp(qureg, ind);
717  amp.imag = statevec_getImagAmp(qureg, ind);
718  return amp;
719 }

References Qureg::numQubitsRepresented, Complex::real, statevec_getImagAmp(), statevec_getRealAmp(), validateAmpIndex(), and validateDensityMatrQureg().

Referenced by TEST_CASE().

◆ getImagAmp()

qreal getImagAmp ( Qureg  qureg,
long long int  index 
)

Get the imaginary component of the complex probability amplitude at an index in the state vector.

Parameters
[in]quregobject representing a set of qubits
[in]indexindex in state vector of probability amplitudes
Returns
imaginary component at that index
Exceptions
invalidQuESTInputErrorif qureg is a density matrix, or if index is outside [0, $2^{N}$) where $N = $ qureg.numQubitsRepresented
Author
Ania Brown

Definition at line 685 of file QuEST.c.

685  {
686  validateStateVecQureg(qureg, __func__);
687  validateAmpIndex(qureg, index, __func__);
688 
689  return statevec_getImagAmp(qureg, index);
690 }

References statevec_getImagAmp(), validateAmpIndex(), and validateStateVecQureg().

Referenced by TEST_CASE().

◆ getNumAmps()

long long int getNumAmps ( Qureg  qureg)

Get the number of probability amplitudes in a qureg object, given by 2^numQubits.

Author
Tyson Jones

Definition at line 672 of file QuEST.c.

672  {
673  validateStateVecQureg(qureg, __func__);
674 
675  return qureg.numAmpsTotal;
676 }

References Qureg::numAmpsTotal, and validateStateVecQureg().

Referenced by TEST_CASE().

◆ getNumQubits()

int getNumQubits ( Qureg  qureg)

Get the number of qubits in a qureg object.

Author
Tyson Jones

Definition at line 668 of file QuEST.c.

668  {
669  return qureg.numQubitsRepresented;
670 }

References Qureg::numQubitsRepresented.

Referenced by TEST_CASE().

◆ getProbAmp()

qreal getProbAmp ( Qureg  qureg,
long long int  index 
)

Get the probability of a state-vector at an index in the full state vector.

Parameters
[in]quregobject representing a set of qubits
[in]indexindex in state vector of probability amplitudes
Returns
realEl*realEl + imagEl*imagEl
Exceptions
invalidQuESTInputErrorif qureg is a density matrix, or if index is outside [0, $2^{N}$) where $N = $ qureg.numQubitsRepresented
Author
Ania Brown

Definition at line 692 of file QuEST.c.

692  {
693  validateStateVecQureg(qureg, __func__);
694  validateAmpIndex(qureg, index, __func__);
695 
696  return statevec_getProbAmp(qureg, index);
697 }

References statevec_getProbAmp(), validateAmpIndex(), and validateStateVecQureg().

Referenced by TEST_CASE().

◆ getRealAmp()

qreal getRealAmp ( Qureg  qureg,
long long int  index 
)

Get the real component of the complex probability amplitude at an index in the state vector.

Parameters
[in]quregobject representing a set of qubits
[in]indexindex in state vector of probability amplitudes
Returns
real component at that index
Exceptions
invalidQuESTInputErrorif qureg is a density matrix, or if index is outside [0, $2^{N}$) where $N = $ qureg.numQubitsRepresented
Author
Ania Brown

Definition at line 678 of file QuEST.c.

678  {
679  validateStateVecQureg(qureg, __func__);
680  validateAmpIndex(qureg, index, __func__);
681 
682  return statevec_getRealAmp(qureg, index);
683 }

References statevec_getRealAmp(), validateAmpIndex(), and validateStateVecQureg().

Referenced by TEST_CASE().

void validateDensityMatrQureg(Qureg qureg, const char *caller)
void validateTarget(Qureg qureg, int targetQubit, const char *caller)
void validateOutcome(int outcome, const char *caller)
qreal densmatr_calcInnerProduct(Qureg a, Qureg b)
qreal statevec_calcExpecPauliProd(Qureg qureg, int *targetQubits, enum pauliOpType *pauliCodes, int numTargets, Qureg workspace)
Definition: QuEST_common.c:465
void validateStateVecQureg(Qureg qureg, const char *caller)
qreal statevec_calcExpecPauliSum(Qureg qureg, enum pauliOpType *allCodes, qreal *termCoeffs, int numSumTerms, Qureg workspace)
Definition: QuEST_common.c:480
qreal densmatr_calcPurity(Qureg qureg)
Computes the trace of the density matrix squared.
qreal statevec_calcProbOfOutcome(Qureg qureg, int measureQubit, int outcome)
void validateNumPauliSumTerms(int numTerms, const char *caller)
qreal statevec_calcFidelity(Qureg qureg, Qureg pureState)
Definition: QuEST_common.c:377
qreal statevec_getProbAmp(Qureg qureg, long long int index)
Definition: QuEST_common.c:245
qreal densmatr_calcTotalProb(Qureg qureg)
Complex statevec_calcExpecDiagonalOp(Qureg qureg, DiagonalOp op)
void validateDiagonalOp(Qureg qureg, DiagonalOp op, const char *caller)
qreal * termCoeffs
The coefficient of each Pauli product. This is a length numSumTerms array.
Definition: QuEST.h:164
enum pauliOpType * pauliCodes
The Pauli operators acting on each qubit, flattened over every operator.
Definition: QuEST.h:162
void validateMultiTargets(Qureg qureg, int *targetQubits, int numTargetQubits, const char *caller)
void validateMatchingQuregDims(Qureg qureg1, Qureg qureg2, const char *caller)
int numSumTerms
The number of terms in the weighted sum, or the number of Pauli products.
Definition: QuEST.h:166
Complex densmatr_calcExpecDiagonalOp(Qureg qureg, DiagonalOp op)
Complex statevec_calcInnerProduct(Qureg bra, Qureg ket)
Terrible code which unnecessarily individually computes and sums the real and imaginary components of...
qreal statevec_getImagAmp(Qureg qureg, long long int index)
void validatePauliHamil(PauliHamil hamil, const char *caller)
qreal densmatr_calcFidelity(Qureg qureg, Qureg pureState)
void validateMatchingQuregPauliHamilDims(Qureg qureg, PauliHamil hamil, const char *caller)
int isDensityMatrix
Whether this instance is a density-state representation.
Definition: QuEST.h:206
void validateMatchingQuregTypes(Qureg qureg1, Qureg qureg2, const char *caller)
void validateAmpIndex(Qureg qureg, long long int ampInd, const char *caller)
void validateSecondQuregStateVec(Qureg qureg2, const char *caller)
int numQubitsRepresented
The number of qubits represented in either the state-vector or density matrix.
Definition: QuEST.h:208
long long int numAmpsTotal
Total number of amplitudes, which are possibly distributed among machines.
Definition: QuEST.h:215
qreal real
Definition: QuEST.h:105
qreal imag
Definition: QuEST.h:106
qreal densmatr_calcHilbertSchmidtDistance(Qureg a, Qureg b)
Represents one complex number.
Definition: QuEST.h:103
void validatePauliCodes(enum pauliOpType *pauliCodes, int numPauliCodes, const char *caller)
qreal densmatr_calcProbOfOutcome(Qureg qureg, int measureQubit, int outcome)
qreal statevec_getRealAmp(Qureg qureg, long long int index)
qreal statevec_calcTotalProb(Qureg qureg)