diff --git a/quest/include/calculations.h b/quest/include/calculations.h index 97453c8a..bf9e5712 100644 --- a/quest/include/calculations.h +++ b/quest/include/calculations.h @@ -342,6 +342,44 @@ Qureg calcReducedDensityMatrix(Qureg qureg, int* retainQubits, int numRetainQubi */ +/** @ingroup example_prs + * + * Calculates the sum of every amplitude in the state. + * + * @formulae + * Let @f$ n @f$ qubits be the number of qubits in @p qureg. + * + * - When @p qureg is a statevector @f$ \svpsi @f$, this function returns + * @f[ + \sum\limits_i^{2^n} \langle i \svpsi \in \mathbb{C}. + * @f] + * - When @p qureg is a density matrix @f$ \dmrho @f$, this function returns + * @f[ + \sum\limits_i^{2^n} \sum\limits_j^{2^n} \bra{i} \dmrho \ket{j} \in \mathbb{C}. + * @f] + * + * @myexample + * ``` + Qureg qureg = createQureg(4); + initRandomPureState(qureg); + + qcomp ampSum = calcAmpSum(qureg); + reportScalar("ampSum", ampSum); + * ``` + * + * @see + * - calcRealAmpSum() + + * @param[in] qureg the state with the processed amplitudes. + * @returns The the sum of all contained amplitudes. + * @throws @validationerror + * - if @p qureg is uninitialised. + * - if @p qureg contains an odd number of qubits. + * @author Tyson Jones + */ +qcomp calcAmpSum(Qureg qureg); + + /// @ingroup calc_comparisons /// @notdoced /// @notvalidated diff --git a/quest/include/wrappers.h b/quest/include/wrappers.h index 73a281c1..c2256819 100644 --- a/quest/include/wrappers.h +++ b/quest/include/wrappers.h @@ -42,6 +42,15 @@ #ifndef __cplusplus +extern void _wrap_calcAmpSum(Qureg qureg, qcomp* out); + +qcomp calcAmpSum(Qureg qureg) { + + qcomp out; + _wrap_calcAmpSum(qureg, &out); + return out; +} + extern void _wrap_calcInnerProduct(Qureg bra, Qureg ket, qcomp* out); diff --git a/quest/src/api/calculations.cpp b/quest/src/api/calculations.cpp index 19927ca3..0f4c80f0 100644 --- a/quest/src/api/calculations.cpp +++ b/quest/src/api/calculations.cpp @@ -46,6 +46,17 @@ extern Qureg validateAndCreateCustomQureg( */ +qcomp calcAmpSum(Qureg qureg) { + validate_quregFields(qureg, __func__); + + return localiser_statevec_calcAmpSum(qureg); +} +extern "C" void _wrap_calcAmpSum(Qureg qureg, qcomp* out) { + + *out = calcAmpSum(qureg); +} + + qcomp calcInnerProduct(Qureg quregA, Qureg quregB) { validate_quregFields(quregA, __func__); validate_quregFields(quregB, __func__); diff --git a/tests/unit/calculations.cpp b/tests/unit/calculations.cpp index 8c9e6c65..286c3f32 100644 --- a/tests/unit/calculations.cpp +++ b/tests/unit/calculations.cpp @@ -197,6 +197,30 @@ TEST_CASE( "calcRealAmpSum", TEST_CATEGORY ) { +TEST_CASE( "calcAmpSum", TEST_CATEGORY ) { + + SECTION( LABEL_CORRECTNESS ) { + + TEST_ALL_QUREGS( + qureg, calcAmpSum(qureg), + refer, getTotal(refer) + ); + } + + SECTION( LABEL_VALIDATION ) { + + SECTION( "qureg uninitialised" ) { + + Qureg qureg; + qureg.numQubits = -123; + + REQUIRE_THROWS_WITH( calcRealAmpSum(qureg), ContainsSubstring("invalid Qureg") ); + } + } +} + + + TEST_CASE( "calcExpecPauliStr", TEST_CATEGORY ) { SECTION( LABEL_CORRECTNESS ) {