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

Functions for calculating expected values of Hermitian observables. More...

Functions

qreal calcExpecFullStateDiagMatr (Qureg qureg, FullStateDiagMatr matr)
 
qreal calcExpecFullStateDiagMatrPower (Qureg qureg, FullStateDiagMatr matrix, qreal exponent)
 
qcomp calcExpecNonHermitianFullStateDiagMatr (Qureg qureg, FullStateDiagMatr matr)
 
qcomp calcExpecNonHermitianFullStateDiagMatrPower (Qureg qureg, FullStateDiagMatr matrix, qcomp exponent)
 
qcomp calcExpecNonHermitianPauliStrSum (Qureg qureg, PauliStrSum sum)
 
qreal calcExpecPauliStr (Qureg qureg, PauliStr str)
 
qreal calcExpecPauliStrSum (Qureg qureg, PauliStrSum sum)
 

Detailed Description

Functions for calculating expected values of Hermitian observables.

Function Documentation

◆ calcExpecFullStateDiagMatr()

qreal calcExpecFullStateDiagMatr ( Qureg qureg,
FullStateDiagMatr matr )

Calculates the expectation value of the given Hermitian observable matr - a diagonal, Hermitian matrix spanning the full Hilbert space - under the given state qureg, without modifying it.

Formulae

Let \( \hat{D} = \) matr.

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

    \[ \brapsi \hat{D} \svpsi \in \mathbb{R}. \]

  • When qureg is a density matrix \(\dmrho\), this function returns the real component of

    \[ \tr{ \hat{D} \dmrho } \]

    which is the exact expectation value when \(\dmrho\) is physical (or at least, Hermitian).
Constraints
  • Hermiticity of matr requires that every element within is real. Validation will check matr is approximately Hermitian, i.e. that

    \[ |\im{c}| \le \valeps \]

    for all \(c \in \) matr.cpuElems. Adjust \(\valeps\) using setValidationEpsilon().
  • Postcondition validation will check that the calculated expectation value is approximately real (i.e. the imaginary component is smaller in size than the validation epsilon), as should be admitted when qureg is correctly normalised, and matr is Hermitian.
  • The returned value is always real, and the imaginary component is neglected even when matr Hermiticity validation is relaxed and/or qureg is an unnormalised density matrix. The full complex value can be obtained using calcExpecNonHermitianFullStateDiagMatr().
Equivalences
  • This function is mathematically equivalent to (albeit much faster than) calling calcExpecPauliStrSum() with a PauliStrSum consisting of all permutations of \(\hat{I}\) and \(\hat{Z}\) Pauli operators with a precise, linear combination of coefficients.
Example
Qureg qureg = createQureg(5);
// profanely inefficient per-element initialisation
for (int n=0; n<matr.numElems; n++) {
qcomp elem = getQcomp(n, 0);
setFullStateDiagMatr(matr, n, &elem, 1);
}
// prints "expec: 15.5"
qreal expec = calcExpecFullStateDiagMatr(qureg, matr);
reportScalar("expec", expec);
qreal calcExpecFullStateDiagMatr(Qureg qureg, FullStateDiagMatr matr)
void initPlusState(Qureg qureg)
FullStateDiagMatr createFullStateDiagMatr(int numQubits)
Definition matrices.cpp:323
void setFullStateDiagMatr(FullStateDiagMatr out, qindex startInd, qcomp *in, qindex numElems)
Definition matrices.cpp:443
Qureg createQureg(int numQubits)
Definition qureg.cpp:283
static qcomp getQcomp(qreal re, qreal im)
Definition types.h:91
void reportScalar(const char *label, qcomp num)
Definition types.cpp:51
Definition qureg.h:49
Parameters
[in]quregthe reference state.
[in]matrthe observable operator.
Returns
The real component of the expectation value.
Exceptions
error
  • if qureg or matr are uninitialised.
  • if matr does not match the dimension of qureg
  • if matr is distributed but qureg is not
  • if matr is not approximately Hermitian.
  • if the output (with unreturned imaginary component) is not approximately real.
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 161 of file calculations.cpp.

161 {
162 validate_quregFields(qureg, __func__);
163 validate_matrixFields(matrix, __func__);
164 validate_matrixAndQuregAreCompatible(matrix, qureg, true, __func__);
165 validate_matrixIsHermitian(matrix, __func__);
166
167 // unused parameters; see calcExpecFullStateDiagMatrPower() for explanation
168 qcomp exponent = qcomp(1,0);
169 bool useRealPow = false;
170
171 qcomp value = (qureg.isDensityMatrix)?
172 localiser_densmatr_calcExpecFullStateDiagMatr(qureg, matrix, exponent, useRealPow):
173 localiser_statevec_calcExpecFullStateDiagMatr(qureg, matrix, exponent, useRealPow);
174
175 // the sub-epsilon imaginary components in matrix never damage the real
176 // component of the statevector expectation value, so we do not validate
177 // imag(value)~0; we can always safely discard it, and only validate for densmatr:
178 if (qureg.isDensityMatrix)
179 validate_densMatrExpecDiagMatrValueIsReal(value, exponent, __func__);
180
181 return std::real(value);
182}

Referenced by TEST_CASE().

◆ calcExpecFullStateDiagMatrPower()

qreal calcExpecFullStateDiagMatrPower ( Qureg qureg,
FullStateDiagMatr matrix,
qreal exponent )

Calculates the expectation value of the given Hermitian observable matrix - a diagonal, Hermitian matrix spanning the full Hilbert space - when raised to the given exponent, under the given state qureg, which is not modified.

Formulae

Let \( \hat{D} = \) matrix and \(x = \) exponent.

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

    \[ \brapsi \hat{D}^x \svpsi \in \mathbb{R}. \]

  • When qureg is a density matrix \(\dmrho\), this function returns the real component of

    \[ \tr{ \hat{D}^x \dmrho } \]

    which is the exact expectation value when \(\dmrho\) is physical (or at least, Hermitian).
Constraints
  • Hermiticity of matrix itself requires that every element within is real. Validation will check matrix is approximately Hermitian, i.e. that

    \[ |\im{c}| \le \valeps \]

    for all \(c \in \) matr.cpuElems. Adjust \(\valeps\) using setValidationEpsilon().
Attention
Unlike other functions (including calcExpecFullStateDiagMatr()), this function will NOT consult the imaginary components of the elements of matrix, since a non-complex exponentiation function is used. That is, while validation permits the imaginary components to be small, they will be internally treated as precisely zero. This is true even when Hermiticity validation is disabled using setValidationOff(). To consult the imaginary components of matrix, use calcExpecNonHermitianFullStateDiagMatrPower().
  • Hermiticity of matrix when raised to exponent further requires that, when exponent is a non-integer, matrix does not contain any negative elements which would otherwise produce complex elements in \(\hat{D}^x\). This validation is always strict (i.e. independent of \(\valeps\)), and demands that

    \[ \min(\hat{D}) \ge 0 \text{ when } x \notin \mathbb{R}. \]

  • Numerical stability requires that if exponent is negative, matrix does not contain any zero elements which would otherwise create divergences in \(\hat{D}^x\). Validation ergo checks that when exponent is (strictly) negative, matrix contains no elements within distance \(\valeps\) to zero (regardless of the magnitude of exponent). Adjust \(\valeps\) using setValidationEpsilon().
  • The passed exponent is always real, but can be relaxed to a general complex scalar via calcExpecNonHermitianFullStateDiagMatrPower().
  • The returned value is always real, and the imaginary component is neglected even when Hermiticity validation is relaxed and/or qureg is an unnormalised density matrix. The full complex value can be obtained using calcExpecNonHermitianFullStateDiagMatrPower().
Example
Qureg qureg = createQureg(5);
FullStateDiagMatr matrix = createFullStateDiagMatr(qureg.numQubits);
// profanely inefficient per-element initialisation
for (int n=0; n<matrix.numElems; n++) {
qcomp elem = getQcomp(n+1, 0);
setFullStateDiagMatr(matrix, n, &elem, 1);
}
// prints "expec: 0.044503"
qreal exponent = -2.3;
qreal expec = calcExpecFullStateDiagMatrPower(qureg, matrix, exponent);
reportScalar("expec", expec);
qreal calcExpecFullStateDiagMatrPower(Qureg qureg, FullStateDiagMatr matrix, qreal exponent)
Parameters
[in]quregthe reference state.
[in]matrixthe observable operator.
[in]exponentthe exponent to which to raise matrix
Returns
The real component of the expectation value of matrix raised to exponent.
Exceptions
error
  • if qureg or matrix are uninitialised.
  • if matrix does not match the dimension of qureg
  • if matrix is distributed but qureg is not
  • if matrix is not approximately Hermitian.
  • if exponent is (precisely) non-integer but matrix contains (precisely) negative elements.
  • if exponent is (precisely) negative but matrix contains elements which are approximately zero.
  • if the output (with unreturned imaginary component) is not approximately real.
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 185 of file calculations.cpp.

185 {
186 validate_quregFields(qureg, __func__);
187 validate_matrixFields(matrix, __func__);
188 validate_matrixAndQuregAreCompatible(matrix, qureg, true, __func__);
189 validate_matrixExpIsHermitian(matrix, exponent, __func__);
190
191 // the backend can use either the pow(qcomp,qcomp) or pow(qreal,qreal) overload;
192 // the former is significantly less accurate when the base is real & negative and
193 // the exponent is real, because complex pow(a,b) = exp(i b Arg(a)) = exp(i b 2 pi),
194 // and the numerical error in pi is compounded by the exponent and the exp(). Because
195 // this function assumes approx/intended Hermiticity, it will always use the real-pow
196 // overload, discarding the imaginary components of 'matrix' during computation - this
197 // is a behaviour unique to this function (other functions collect the erroneous
198 // imaginary components before a final validation and discarding).
199 const bool useRealPow = true;
200
201 qcomp value = (qureg.isDensityMatrix)?
202 localiser_densmatr_calcExpecFullStateDiagMatr(qureg, matrix, exponent, useRealPow):
203 localiser_statevec_calcExpecFullStateDiagMatr(qureg, matrix, exponent, useRealPow);
204
205 // is it impossible for the statevector routine to produce non-zero
206 // imaginary components because of our use of real-pow, the result of
207 // which is multiplied by abs(amp). Alas, density matrices multiply the
208 // result with a complex scalar and can accrue erroneous imaginary
209 // components when the density matrix is non-Hermitian, or due to rounding
210 // errors. As such, we only post-validate density matrix values.
211 if (qureg.isDensityMatrix)
212 validate_densMatrExpecDiagMatrValueIsReal(value, exponent, __func__);
213
214 return std::real(value);
215}

Referenced by TEST_CASE().

◆ calcExpecNonHermitianFullStateDiagMatr()

qcomp calcExpecNonHermitianFullStateDiagMatr ( Qureg qureg,
FullStateDiagMatr matr )

Calculates the expectation value of the given permittedly non-Hermitian operator matr, under the given state qureg, without modifying it.

Formulae

This function is mathematically equivalent to calcExpecFullStateDiagMatr(), except that here a complex scalar is returned. This permits obtaining the full scalar when sum contains non-real elements, and/or when qureg is unnormalised.

Example
Qureg qureg = createQureg(5);
// profanely inefficient per-element initialisation
for (int n=0; n<matr.numElems; n++) {
qcomp elem = getQcomp(n, n+1);
setFullStateDiagMatr(matr, n, &elem, 1);
}
// prints "expec: 15.5+16.5i"
qcomp expec = calcExpecNonHermitianFullStateDiagMatr(qureg, matr);
reportScalar("expec", expec);
qcomp calcExpecNonHermitianFullStateDiagMatr(Qureg qureg, FullStateDiagMatr matr)
Parameters
[in]quregthe permittedly unnormalised reference state.
[in]matrthe permittedly non-Hermitian operator.
Returns
The permittedly complex expectation value.
Exceptions
error
  • if qureg or matr are uninitialised.
  • if matr does not match the dimension of qureg
  • if matr is distributed but qureg is not
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 85 of file calculations.cpp.

85 {
86 validate_quregFields(qureg, __func__);
87 validate_matrixFields(matrix, __func__);
88 validate_matrixAndQuregAreCompatible(matrix, qureg, true, __func__);
89
90 return calcExpecNonHermitianFullStateDiagMatrPower(qureg, matrix, 1); // harmlessly re-validates
91}
qcomp calcExpecNonHermitianFullStateDiagMatrPower(Qureg qureg, FullStateDiagMatr matrix, qcomp exponent)

Referenced by TEST_CASE().

◆ calcExpecNonHermitianFullStateDiagMatrPower()

qcomp calcExpecNonHermitianFullStateDiagMatrPower ( Qureg qureg,
FullStateDiagMatr matrix,
qcomp exponent )

Calculates the expectation value of the given permittedly non-Hermitian operator matrix, raised to the arbitrary complex exponent, under the given state qureg, which is not modified.

Formulae

This function is mathematically equivalent to calcExpecFullStateDiagMatrPower(), except that here a complex scalar is returned, in addition to exponent being permittedly complex. This permits obtaining the full scalar when qureg is unnormalised or matrix (after being raised to exponent) is non-Hermitian.

Example
Qureg qureg = createQureg(5);
FullStateDiagMatr matrix = createFullStateDiagMatr(qureg.numQubits);
// profanely inefficient per-element initialisation
for (int n=0; n<matrix.numElems; n++) {
qcomp elem = getQcomp(n, n+1);
setFullStateDiagMatr(matrix, n, &elem, 1);
}
qcomp exponent = 3+4_i;
// prints "expec: -257.26-613.8i"
qcomp expec = calcExpecNonHermitianFullStateDiagMatrPower(qureg, matrix, exponent);
reportScalar("expec", expec);
Parameters
[in]quregthe permittedly unnormalised reference state.
[in]matrixthe permittedly non-Hermitian operator.
[in]exponentthe permittedly complex exponent.
Returns
The permittedly complex expectation value.
Exceptions
error
  • if qureg or matrix are uninitialised.
  • if matrix does not match the dimension of qureg
  • if matrix is distributed but qureg is not
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 98 of file calculations.cpp.

98 {
99 validate_quregFields(qureg, __func__);
100 validate_matrixFields(matrix, __func__);
101 validate_matrixAndQuregAreCompatible(matrix, qureg, true, __func__);
102
103 // this function never uses the qreal-pow overload (because we make
104 // no assumption matrix is Hermitian i.e. real), and instead always
105 // uses the relatively numerically inaccurate qcomp overload
106 const bool useRealPow = false;
107
108 return (qureg.isDensityMatrix)?
109 localiser_densmatr_calcExpecFullStateDiagMatr(qureg, matrix, exponent, useRealPow):
110 localiser_statevec_calcExpecFullStateDiagMatr(qureg, matrix, exponent, useRealPow);
111}

Referenced by calcExpecNonHermitianFullStateDiagMatr(), and TEST_CASE().

◆ calcExpecNonHermitianPauliStrSum()

qcomp calcExpecNonHermitianPauliStrSum ( Qureg qureg,
PauliStrSum sum )

Calculates the expectation value of the given permittedly non-Hermitian operator sum

  • a weighted sum of Pauli strings with complex weights - under the given state qureg, which is not modified.
Formulae

This function is mathematically equivalent to calcExpecPauliStrSum(), except that here a complex scalar is returned. This permits obtaining the full scalar when sum contains non-real weights, and/or when qureg is unnormalised.

Example
Qureg qureg = createQureg(5);
0.123 + 3.5i ZIZIZI
1.234 - 1E-5i XYZXZ
-1E-2 IIIII
)");
// prints "expec: 0.113+3.5i"
qcomp expec = calcExpecNonHermitianPauliStrSum(qureg, sum);
reportScalar("expec", expec);
qcomp calcExpecNonHermitianPauliStrSum(Qureg qureg, PauliStrSum sum)
PauliStrSum createInlinePauliStrSum(const char *str)
Definition paulis.cpp:198
Parameters
[in]quregthe permittedly unnormalised reference state.
[in]sumthe permittedly non-Hermitian operator.
Returns
The permittedly complex expectation value.
Exceptions
error
  • if qureg or sum are uninitialised.
  • if any PauliStr in sum targets a higher-index qubit than exists in 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 68 of file calculations.cpp.

68 {
69 validate_quregFields(qureg, __func__);
70 validate_pauliStrSumFields(sum, __func__);
71 validate_pauliStrSumTargets(sum, qureg, __func__);
72
73 qcomp value = (qureg.isDensityMatrix)?
74 localiser_densmatr_calcExpecPauliStrSum(qureg, sum):
75 localiser_statevec_calcExpecPauliStrSum(qureg, sum);
76
77 return value;
78}

Referenced by TEST_CASE().

◆ calcExpecPauliStr()

qreal calcExpecPauliStr ( Qureg qureg,
PauliStr str )

Calculates the expectation value of the given Pauli string observable str under the given state qureg without modifying it.

Formulae

Let \( \pstr = \) str, which notates a tensor product of single-qubit Pauli operators.

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

    \[ \brapsi \pstr \svpsi \in \mathbb{R}. \]

  • When qureg is a density matrix \(\dmrho\), this function returns the real component of

    \[ \tr{ \pstr \dmrho } \]

    which is exact when \(\dmrho\) is physical (specifically Hermitian).
Constraints
  • Postcondition validation will check that the calculated expectation value is approximately real (i.e. the imaginary component is smaller in size than the validation epsilon), as admitted when qureg is correctly normalised. This behaviour can be adjusted using setValidationEpsilon().
  • Regardless of the validation epsilon, the returned value is always real and the imaginary component is discarded. The full complex value can be obtained using calcExpecNonHermitianPauliStrSum().
Equivalences
Example
Qureg qureg = createQureg(10);
PauliStr str = getInlinePauliStr("XYZ", {0,2,3});
qreal expec = calcExpecPauliStr(qureg, str);
reportScalar("expec", expec);
qreal calcExpecPauliStr(Qureg qureg, PauliStr str)
void initRandomPureState(Qureg qureg)
PauliStr getInlinePauliStr(const char *paulis, { list })
See also
Parameters
[in]quregthe reference state.
[in]strthe observable operator.
Returns
The real component of the expectation value.
Exceptions
error
  • if qureg is uninitialised.
  • if str contains a (non-identity) Pauli upon a higher-index qubit than exists in qureg.
  • if the output (with unreturned imaginary component) is not approximately real.
Attention
This function's input validation has not yet been unit tested, so erroneous usage may produce unexpected output. Please use with caution!
Author
Tyson Jones

Definition at line 133 of file calculations.cpp.

133 {
134 validate_quregFields(qureg, __func__);
135 validate_pauliStrTargets(qureg, str, __func__);
136
137 qcomp value = (qureg.isDensityMatrix)?
138 localiser_densmatr_calcExpecPauliStr(qureg, str):
139 localiser_statevec_calcExpecPauliStr(qureg, str);
140
141 validate_expecPauliStrValueIsReal(value, qureg.isDensityMatrix, __func__);
142 return std::real(value);
143}

Referenced by TEST_CASE().

◆ calcExpecPauliStrSum()

qreal calcExpecPauliStrSum ( Qureg qureg,
PauliStrSum sum )

Calculates the expectation value of the given Hermitian observable sum - a weighted sum of Pauli strings - under the given state qureg, without modifying it.

Formulae

Let \( \hat{H} = \) sum.

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

    \[ \brapsi \hat{H} \svpsi \in \mathbb{R}. \]

  • When qureg is a density matrix \(\dmrho\), this function returns the real component of

    \[ \tr{ \hat{H} \dmrho } \]

    which is the exact expectation value when \(\dmrho\) is physical (or at least, Hermitian).
Constraints
  • Hermiticity of sum requires that every coefficient within is real. Validation will check sum is approximately Hermitian, i.e. that

    \[ |\im{c}| \le \valeps \]

    for all \(c \in \) sum.coeffs. Adjust \(\valeps\) using setValidationEpsilon(). The sub-epsilon imaginary components of the coefficients are included in calculation.
  • Postcondition validation will check that the calculated expectation value is approximately real (i.e. the imaginary component is smaller in size than the validation epsilon), as should be admitted when qureg is correctly normalised, and sum is Hermitian.
  • The returned value is always real, and the imaginary component is neglected even when Hermiticity validation is relaxed and/or qureg is an unnormalised density matrix. The full complex value can be obtained using calcExpecNonHermitianPauliStrSum().
Equivalences
  • This function is mathematically equivalent to (albeit faster than) calling calcExpecPauliStr() upon each constituent PauliStr within sum, weighting each by its corresponding coefficient, and summing the outputs.
  • When sum contains only \(\pauliz\) and \(\id\) operators, its corresponding operator matrix is diagonal, and could be instead effected with calcExpecFullStateDiagMatr(). This may be faster when sum contains very-many terms and operates upon all qubits of the register.
Example
Qureg qureg = createQureg(5);
0.123 XXIXX
1.234 XYZXZ
-1E-2 IIIII
)");
qreal expec = calcExpecPauliStrSum(qureg, sum);
reportScalar("expec", expec);
qreal calcExpecPauliStrSum(Qureg qureg, PauliStrSum sum)
Parameters
[in]quregthe reference state.
[in]sumthe observable operator.
Returns
The real component of the expectation value.
Exceptions
error
  • if qureg or sum are uninitialised.
  • if any PauliStr in sum targets a higher-index qubit than exists in qureg.
  • if sum is not approximately Hermitian.
  • if the output (with unreturned imaginary component) is not approximately real.
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 146 of file calculations.cpp.

146 {
147 validate_quregFields(qureg, __func__);
148 validate_pauliStrSumFields(sum, __func__);
149 validate_pauliStrSumTargets(sum, qureg, __func__);
150 validate_pauliStrSumIsHermitian(sum, __func__);
151
152 qcomp value = (qureg.isDensityMatrix)?
153 localiser_densmatr_calcExpecPauliStrSum(qureg, sum):
154 localiser_statevec_calcExpecPauliStrSum(qureg, sum);
155
156 validate_expecPauliStrSumValueIsReal(value, qureg.isDensityMatrix, __func__);
157 return std::real(value);
158}

Referenced by TEST_CASE().