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

Functions for comparing multiple quantum states. More...

Functions

qreal calcDistance (Qureg qureg, Qureg other)
 
qreal calcFidelity (Qureg qureg, Qureg other)
 
qcomp calcInnerProduct (Qureg qureg, Qureg other)
 

Detailed Description

Functions for comparing multiple quantum states.

Function Documentation

◆ calcDistance()

qreal calcDistance ( Qureg qureg,
Qureg other )

Calculates one of three distance measures between qureg and other, depending upon whether one or both are density matrices. These are the Hilbert-Schmidt distance, Bures distance and purified distance.

Formulae
  • When both qureg and other are statevectors (respectively \(\ket{\psi}\) and \(\ket{\phi}\)), this function returns the Bures distance defined as

    \[ d_B\left(\ket{\psi},\ket{\phi}\right) = \sqrt{2 - 2 \left| \braket{\phi}{\psi} \right|} \]

    where \(\left| \braket{\phi}{\psi} \right|\) is the square-root of the fidelity between \(\ket{\psi}\) and \(\ket{\phi}\) as would be computed by calcFidelity().
  • When both qureg and other are density matrices (respectively \(\mathbf{\rho}\) and \(\mathbf{\sigma}\)), this function returns the Hilbert-Schmidt distance defined as

    \[ d_{HS}\left(\mathbf{\rho}, \mathbf{\sigma}\right) = \sqrt{ \tr{ \left| \mathbf{\rho} - \mathbf{\sigma} \right|^2 } } = \sqrt{ \sum\limits_{ij} \left| \rho_{ij} - \sigma_{ij} \right|^2 }. \]

  • When one of qureg or other is a statevector \(\svpsi\), and the other is a density matrix \(\dmrho\), this function returns the purified distance defined as

    \[ d_p\left(\svpsi,\dmrho\right) = \sqrt{ 1 - \brapsi \dmrho \svpsi } \]

    where \(\brapsi \dmrho \svpsi\) is the fidelity as returned by calcFidelity().
Constraints
  • The output of this function is always real, which is always mathematically satisfied by the Hilbert-Schmidt distance, but may be violated by the Bures and purified distances when the input Qureg are not normalised, or otherwise due to numerical imprecision. Postcondition validation of the Bures distance will check that

    \[ \left| \braket{\phi}{\psi} \right| \le 1 + \valeps \]

    while the purified distance validation will check that

    \[ \left| \, \im{ \brapsi \dmrho \svpsi } \, \right| \le \valeps, \\ \re{ \brapsi \dmrho \svpsi } \le 1 + \valeps, \]

    where \(\valeps\) is the validation epsilon, adjustable via setQuESTValidationEpsilon().
  • Even when the above postcondition validation is disabled, the Bures and purified distance calculations will respectively replace \(\left| \braket{\phi}{\psi} \right|\) and \(\re{ \brapsi \dmrho \svpsi }\) which exceed \(1\) with value \(1\), and the imaginary component of \(\brapsi \dmrho \svpsi\) is discarded.
  • When qureg and other are both statevectors, or both density matrices, then both or neither must be GPU-accelerated. That is, their CPU vs GPU deployments must agree. They are permitted to differ in distribution however. Such considerations are only relevant when creating the registers using createCustomQureg(), since the automatic deployments of createQureg() and createDensityQureg() will always agree.
  • When qureg and other dimensionally differ (i.e. one is a statevector while the other is a density matrix), the statevector must not be distributed unless the density matrix is distributed. The CPU vs GPU deployments however are permitted to disagree. These requirements are again consistent with the automatic deployments of the createQureg() and createDensityQureg() functions.
Equivalences
  • When both qureg and other are statevectors, this function wraps calcInnerProduct().
    qcomp prod = calcInnerProduct(qureg, other); // <qureg|other>
    qreal mag = abs(prod);
    mag = (mag > 1)? 1 : mag;
    qreal dist = std::sqrt(2 - 2 * mag);
    qcomp calcInnerProduct(Qureg qureg, Qureg other)
  • When qureg is a density matrix and other is a statevector, this function wraps calcInnerProduct() as a complex-valued proxy for calcFidelity().
    qcomp prod = calcInnerProduct(other, qureg); // <other|qureg|other>
    qreal re = real(prod);
    re = (re > 1)? 1 : re;
    qreal dist = sqrt(1 - re);
Example
setQuregToClone(rho2, rho1);
qreal distA = calcDistance(rho1, rho2); // = 0
qreal distB = calcDistance(rho1, rho2); // > 0
qreal calcDistance(Qureg qureg, Qureg other)
void setQuregToClone(Qureg outQureg, Qureg inQureg)
void initRandomMixedState(Qureg qureg, qindex numPureStates)
Qureg createDensityQureg(int numQubits)
Definition qureg.cpp:297
Definition qureg.h:49
Parameters
[in]qurega state
[in]otheranother state containing an equal number of qubits
Returns
The distance between qureg and other, according to the above measures.
Exceptions
error
  • if qureg or other is uninitialised.
  • if qureg and other contain a different number of qubits.
  • if qureg and other are incompatible deployed.
  • if qureg or other is unnormalised such that the Bures or purified distances would be non-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 332 of file calculations.cpp.

332 {
333 validate_quregFields(quregA, __func__);
334 validate_quregFields(quregB, __func__);
335 validate_quregsCanBeProducted(quregA, quregB, __func__);
336
337 bool isDensA = quregA.isDensityMatrix;
338 bool isDensB = quregB.isDensityMatrix;
339
340 // Hilbert-Schmidt = sqrt( Tr((A-B)(A-B)^dagger) = sqrt(sum_ij |A_ij - B_ij|^2)
341 if (isDensA && isDensB) {
342 qreal dif = localiser_densmatr_calcHilbertSchmidtDistance(quregA, quregB); // >= 0
343 return std::sqrt(dif);
344 }
345
346 // Bures = sqrt(2 - 2 |<A|B>|) (even when unnormalised)
347 if (!isDensA && !isDensB) {
348 qcomp prod = localiser_statevec_calcInnerProduct(quregA, quregB);
349 qreal mag = std::abs(prod); // >= 0
350
351 validate_buresDistanceInnerProdIsNormalised(mag, __func__);
352 mag = (mag > 1)? 1 : mag; // forgive eps error to avoid complex
353 return std::sqrt(2 - 2 * mag);
354 }
355
356 // purified distance = sqrt(1 - <psi|rho|psi>)
357 qcomp fid = (quregA.isDensityMatrix)?
358 localiser_densmatr_calcFidelityWithPureState(quregA, quregB, false): // no conj
359 localiser_densmatr_calcFidelityWithPureState(quregB, quregA, false); // no conj
360
361 validate_purifiedDistanceIsNormalised(fid, __func__);
362 qreal re = std::real(fid);
363 re = (re > 1)? 1 : re; // forgive eps error to avoid complex
364 return std::sqrt(1 - re);
365}

Referenced by TEST_CASE().

◆ calcFidelity()

qreal calcFidelity ( Qureg qureg,
Qureg other )

Calculates the fidelity between qureg and other, where at least one is a statevector.

Formulae
  • When both qureg and other are statevectors (respectively \(\ket{\psi}\) and \(\ket{\phi}\)), this function returns

    \[ \left| \braket{\phi}{\psi} \right|^2. \]

  • When qureg is a density matrix \(\dmrho\) and other is a statevector \(\svpsi\), this function returns

    \[ \bra{\psi} \dmrho \ket{\psi}, \]

    and similarly when qureg is a statevector and other is a density matrix.
Constraints
  • The output of this function is always real, which validation will check after computing the fidelity as a complex scalar. Specifically, validation will assert that the result has an absolute imaginary component less than the validation epsilon, which can be adjusted with setQuESTValidationEpsilon().
  • This function does not yet support both qureg and other being density matrices, for which the fidelity calculation is more substantial.
  • When qureg and other are both statevectors, or both density matrices, then both or neither must be GPU-accelerated. That is, their CPU vs GPU deployments must agree. They are permitted to differ in distribution however. Such considerations are only relevant when creating the registers using createCustomQureg(), since the automatic deployments of createQureg() and createDensityQureg() will always agree.
  • When qureg and other dimensionally differ (i.e. one is a statevector while the other is a density matrix), the statevector must not be distributed unless the density matrix is distributed. The CPU vs GPU deployments however are permitted to disagree. These requirements are again consistent with the automatic deployments of the createQureg() and createDensityQureg() functions.
Equivalences
  • When both qureg and other are statevectors, this function is equivalent to calling calcInnerProduct() and squaring the absolute value of the result.
    qcomp prod = calcInnerProduct(qureg, other);
    qreal fid = pow(abs(prod), 2);
  • When one of qureg or other is a statevector in the computational basis state \(\ket{i}\) (e.g. as can be produced via initClassicalState()), this function is slower but equivalent to finding directly the probability of the basis state.
    // initClassicalState(other, index);
    qreal fid = calcProbOfBasisState(qureg, index);
    qreal calcProbOfBasisState(Qureg qureg, qindex index)
Example
// rho = |psi><psi|
Qureg psi = createQureg(5);
initPureState(rho, psi);
qreal fid0 = calcFidelity(rho, psi); // = 1
mixDepolarising(rho, 0, 0.5);
qreal fid1 = calcFidelity(rho, psi); // < 1
qreal calcFidelity(Qureg qureg, Qureg other)
void mixDepolarising(Qureg qureg, int target, qreal prob)
void initRandomPureState(Qureg qureg)
void initPureState(Qureg qureg, Qureg pure)
Qureg createQureg(int numQubits)
Definition qureg.cpp:289
Parameters
[in]qurega state
[in]otheranother state containing an equal number of qubits.
Returns
The fidelity between qureg and other.
Exceptions
error
  • if qureg or other is uninitialised.
  • if qureg and other contain a different number of qubits.
  • if qureg and other are incompatible deployed.
  • if both qureg and other are density matrices (as is not yet supported).
  • if qureg or other is unnormalised such that the calculated fidelity is non-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 304 of file calculations.cpp.

304 {
305 validate_quregFields(quregA, __func__);
306 validate_quregFields(quregB, __func__);
307 validate_quregsCanBeProducted(quregA, quregB, __func__);
308
309 bool isDensA = quregA.isDensityMatrix;
310 bool isDensB = quregB.isDensityMatrix;
311
312 // F(rho,sigma) not yet supported
313 if (isDensA && isDensB)
314 validate_throwErrorBecauseCalcFidOfDensMatrNotYetImplemented(__func__);
315
316 // |<A|B>|^2
317 if (!isDensA && !isDensB) {
318 qcomp prod = localiser_statevec_calcInnerProduct(quregA, quregB);
319 return std::norm(prod);
320 }
321
322 // Re[<B|A|B>] or Re[<A|B|A>]
323 qcomp fid = (quregA.isDensityMatrix)?
324 localiser_densmatr_calcFidelityWithPureState(quregA, quregB, false): // no conj
325 localiser_densmatr_calcFidelityWithPureState(quregB, quregA, false); // no conj
326
327 validate_fidelityIsReal(fid, __func__);
328 return std::real(fid);
329}

Referenced by TEST_CASE(), and TEST_CASE().

◆ calcInnerProduct()

qcomp calcInnerProduct ( Qureg qureg,
Qureg other )

Calculates the inner product of state qureg with other.

Formulae
  • When both qureg and other are statevectors (respectively \(\ket{\psi}\) and \(\ket{\phi}\)), this function returns

    \[ \braket{\psi}{\phi} = \sum\limits_i \psi_i^* \phi_i \]

    where \(\psi_i\) and \(\phi_i\) are the \(i\)-th amplitudes of \(\ket{\psi}\) (qureg) and \(\ket{\phi}\) (other) respectively, and \(\alpha^*\) notates the complex conjugate of scalar \(\alpha\).
  • When both qureg and other are density matrices (respectively \(\mathbf{\rho}\) and \(\mathbf{\sigma}\)), this function returns

    \[ \tr{ \rho^\dagger \sigma } = \sum\limits_{ij} {\rho_{ij}}^* \, \sigma_{ij}. \]

  • When qureg is a density matrix \(\dmrho\) and other is a statevector \(\ket{\phi}\), this function returns

    \[ \bra{\phi} \dmrho^\dagger \ket{\phi}. \]

  • When qureg is a statevector \(\svpsi\) and other is a density matrix \(\mathbf{\sigma}\), this function returns

    \[ \brapsi \mathbf{\sigma} \svpsi. \]

Constraints
  • When qureg and other are both statevectors, or both density matrices, then both or neither must be GPU-accelerated. That is, their CPU vs GPU deployments must agree. They are permitted to differ in distribution however. Such considerations are only relevant when creating the registers using createCustomQureg(), since the automatic deployments of createQureg() and createDensityQureg() will always agree.
  • When qureg and other dimensionally differ (i.e. one is a statevector while the other is a density matrix), the statevector must not be distributed unless the density matrix is distributed. The CPU vs GPU deployments however are permitted to disagree. These requirements are again consistent with the automatic deployments of the createQureg() and createDensityQureg() functions.
Example
// rho1 = rho2 = |psi><psi|
setQuregToClone(rho2, rho1);
qcomp prodA = calcInnerProduct(rho1, rho2); // = 1
// rho1 = rho2 = sum_i prob_i |psi_i><psi_i|
setQuregToClone(rho2, rho1);
qcomp prodB = calcInnerProduct(rho1, rho2); // < 1, real
// rho1 != rho2
qcomp prodC = calcInnerProduct(rho1, rho2); // abs < 1, complex
Parameters
[in]qurega state
[in]otheranother state with an equal number of qubits
Returns
The inner product of qureg with other.
Exceptions
error
  • if qureg or other is uninitialised.
  • if qureg and other contain a different number of qubits.
  • if qureg and other are incompatibly deployed.
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 50 of file calculations.cpp.

50 {
51 validate_quregFields(quregA, __func__);
52 validate_quregFields(quregB, __func__);
53 validate_quregsCanBeProducted(quregA, quregB, __func__);
54
55 // <A|B> or Tr(A^dagger B) = <<A|B>>
56 if (quregA.isDensityMatrix == quregB.isDensityMatrix)
57 return localiser_statevec_calcInnerProduct(quregA, quregB);
58
59 return (quregA.isDensityMatrix)?
60 localiser_densmatr_calcFidelityWithPureState(quregA, quregB, true): // <B|A^dagger|B>
61 localiser_densmatr_calcFidelityWithPureState(quregB, quregA, false); // <A|B|A>
62}

Referenced by TEST_CASE(), and TEST_CASE().