9#include "quest/include/types.h"
10#include "quest/include/qureg.h"
11#include "quest/include/paulis.h"
12#include "quest/include/calculations.h"
14#include "quest/src/core/validation.hpp"
15#include "quest/src/core/utilities.hpp"
16#include "quest/src/core/localiser.hpp"
17#include "quest/src/core/bitwise.hpp"
18#include "quest/src/core/errors.hpp"
30extern Qureg validateAndCreateCustomQureg(
31 int numQubits,
int isDensMatr,
int useDistrib,
32 int useGpuAccel,
int useMultithread,
const char* caller);
50 validate_quregFields(quregA, __func__);
51 validate_quregFields(quregB, __func__);
52 validate_quregsCanBeProducted(quregA, quregB, __func__);
55 if (quregA.isDensityMatrix == quregB.isDensityMatrix)
56 return localiser_statevec_calcInnerProduct(quregA, quregB);
58 return (quregA.isDensityMatrix)?
59 localiser_densmatr_calcFidelityWithPureState(quregA, quregB,
true):
60 localiser_densmatr_calcFidelityWithPureState(quregB, quregA,
false);
62extern "C" void _wrap_calcInnerProduct(
Qureg bra,
Qureg ket, qcomp* out) {
69 validate_quregFields(qureg, __func__);
70 validate_pauliStrSumFields(sum, __func__);
71 validate_pauliStrSumTargets(sum, qureg, __func__);
73 qcomp value = (qureg.isDensityMatrix)?
74 localiser_densmatr_calcExpecPauliStrSum(qureg, sum):
75 localiser_statevec_calcExpecPauliStrSum(qureg, sum);
79extern "C" void _wrap_calcExpecNonHermitianPauliStrSum(qcomp* out,
Qureg qureg,
PauliStrSum sum) {
86 validate_quregFields(qureg, __func__);
87 validate_matrixFields(matrix, __func__);
88 validate_matrixAndQuregAreCompatible(matrix, qureg,
true, __func__);
92extern "C" void _wrap_calcExpecNonHermitianFullStateDiagMatr(qcomp* out,
Qureg qureg,
FullStateDiagMatr matr) {
99 validate_quregFields(qureg, __func__);
100 validate_matrixFields(matrix, __func__);
101 validate_matrixAndQuregAreCompatible(matrix, qureg,
true, __func__);
106 const bool useRealPow =
false;
108 return (qureg.isDensityMatrix)?
109 localiser_densmatr_calcExpecFullStateDiagMatr(qureg, matrix, exponent, useRealPow):
110 localiser_statevec_calcExpecFullStateDiagMatr(qureg, matrix, exponent, useRealPow);
112extern "C" void _wrap_calcExpecNonHermitianFullStateDiagMatrPower(qcomp* out,
Qureg qureg,
FullStateDiagMatr matr, qcomp exponent) {
134 validate_quregFields(qureg, __func__);
135 validate_pauliStrTargets(qureg, str, __func__);
137 qcomp value = (qureg.isDensityMatrix)?
138 localiser_densmatr_calcExpecPauliStr(qureg, str):
139 localiser_statevec_calcExpecPauliStr(qureg, str);
141 validate_expecPauliStrValueIsReal(value, qureg.isDensityMatrix, __func__);
142 return std::real(value);
147 validate_quregFields(qureg, __func__);
148 validate_pauliStrSumFields(sum, __func__);
149 validate_pauliStrSumTargets(sum, qureg, __func__);
150 validate_pauliStrSumIsHermitian(sum, __func__);
152 qcomp value = (qureg.isDensityMatrix)?
153 localiser_densmatr_calcExpecPauliStrSum(qureg, sum):
154 localiser_statevec_calcExpecPauliStrSum(qureg, sum);
156 validate_expecPauliStrSumValueIsReal(value, qureg.isDensityMatrix, __func__);
157 return std::real(value);
162 validate_quregFields(qureg, __func__);
163 validate_matrixFields(matrix, __func__);
164 validate_matrixAndQuregAreCompatible(matrix, qureg,
true, __func__);
165 validate_matrixIsHermitian(matrix, __func__);
168 qcomp exponent = qcomp(1,0);
169 bool useRealPow =
false;
171 qcomp value = (qureg.isDensityMatrix)?
172 localiser_densmatr_calcExpecFullStateDiagMatr(qureg, matrix, exponent, useRealPow):
173 localiser_statevec_calcExpecFullStateDiagMatr(qureg, matrix, exponent, useRealPow);
178 if (qureg.isDensityMatrix)
179 validate_densMatrExpecDiagMatrValueIsReal(value, exponent, __func__);
181 return std::real(value);
186 validate_quregFields(qureg, __func__);
187 validate_matrixFields(matrix, __func__);
188 validate_matrixAndQuregAreCompatible(matrix, qureg,
true, __func__);
189 validate_matrixExpIsHermitian(matrix, exponent, __func__);
199 const bool useRealPow =
true;
201 qcomp value = (qureg.isDensityMatrix)?
202 localiser_densmatr_calcExpecFullStateDiagMatr(qureg, matrix, exponent, useRealPow):
203 localiser_statevec_calcExpecFullStateDiagMatr(qureg, matrix, exponent, useRealPow);
211 if (qureg.isDensityMatrix)
212 validate_densMatrExpecDiagMatrValueIsReal(value, exponent, __func__);
214 return std::real(value);
225 validate_quregFields(qureg, __func__);
226 validate_basisStateIndex(qureg, index, __func__);
229 if (qureg.isDensityMatrix)
230 index *= 1 + powerOf2(qureg.numQubits);
232 qcomp amp = localiser_statevec_getAmp(qureg, index);
233 qreal prob = (qureg.isDensityMatrix)?
242 validate_quregFields(qureg, __func__);
243 validate_target(qureg, qubit, __func__);
244 validate_measurementOutcomeIsValid(outcome, __func__);
252 validate_quregFields(qureg, __func__);
253 validate_targets(qureg, qubits, numQubits, __func__);
254 validate_measurementOutcomesAreValid(outcomes, numQubits, __func__);
256 auto qubitVec = util_getVector(qubits, numQubits);
257 auto outcomeVec = util_getVector(outcomes, numQubits);
259 return (qureg.isDensityMatrix)?
260 localiser_densmatr_calcProbOfMultiQubitOutcome(qureg, qubitVec, outcomeVec):
261 localiser_statevec_calcProbOfMultiQubitOutcome(qureg, qubitVec, outcomeVec);
266 validate_quregFields(qureg, __func__);
267 validate_targets(qureg, qubits, numQubits, __func__);
268 validate_measurementOutcomesFitInGpuMem(qureg, numQubits, __func__);
270 auto qubitVec = util_getVector(qubits, numQubits);
272 (qureg.isDensityMatrix)?
273 localiser_densmatr_calcProbsOfAllMultiQubitOutcomes(outcomeProbs, qureg, qubitVec):
274 localiser_statevec_calcProbsOfAllMultiQubitOutcomes(outcomeProbs, qureg, qubitVec);
279 validate_quregFields(qureg, __func__);
281 return (qureg.isDensityMatrix)?
282 localiser_densmatr_calcTotalProb(qureg):
283 localiser_statevec_calcTotalProb(qureg);
294 validate_quregFields(qureg, __func__);
298 qreal prob = localiser_statevec_calcTotalProb(qureg);
299 return (qureg.isDensityMatrix)? prob : prob * prob;
304 validate_quregFields(quregA, __func__);
305 validate_quregFields(quregB, __func__);
306 validate_quregsCanBeProducted(quregA, quregB, __func__);
308 bool isDensA = quregA.isDensityMatrix;
309 bool isDensB = quregB.isDensityMatrix;
312 if (isDensA && isDensB)
313 validate_throwErrorBecauseCalcFidOfDensMatrNotYetImplemented(__func__);
316 if (!isDensA && !isDensB) {
317 qcomp prod = localiser_statevec_calcInnerProduct(quregA, quregB);
318 return std::norm(prod);
322 qcomp fid = (quregA.isDensityMatrix)?
323 localiser_densmatr_calcFidelityWithPureState(quregA, quregB,
false):
324 localiser_densmatr_calcFidelityWithPureState(quregB, quregA,
false);
326 validate_fidelityIsReal(fid, __func__);
327 return std::real(fid);
332 validate_quregFields(quregA, __func__);
333 validate_quregFields(quregB, __func__);
334 validate_quregsCanBeProducted(quregA, quregB, __func__);
336 bool isDensA = quregA.isDensityMatrix;
337 bool isDensB = quregB.isDensityMatrix;
340 if (isDensA && isDensB) {
341 qreal dif = localiser_densmatr_calcHilbertSchmidtDistance(quregA, quregB);
342 return std::sqrt(dif);
346 if (!isDensA && !isDensB) {
347 qcomp prod = localiser_statevec_calcInnerProduct(quregA, quregB);
348 qreal mag = std::abs(prod);
350 validate_buresDistanceInnerProdIsNormalised(mag, __func__);
351 mag = (mag > 1)? 1 : mag;
352 return std::sqrt(2 - 2 * mag);
356 qcomp fid = (quregA.isDensityMatrix)?
357 localiser_densmatr_calcFidelityWithPureState(quregA, quregB,
false):
358 localiser_densmatr_calcFidelityWithPureState(quregB, quregA,
false);
360 validate_purifiedDistanceIsNormalised(fid, __func__);
361 qreal re = std::real(fid);
362 re = (re > 1)? 1 : re;
363 return std::sqrt(1 - re);
374 validate_quregFields(qureg, __func__);
375 validate_quregIsDensityMatrix(qureg, __func__);
376 validate_targets(qureg, traceOutQubits, numTraceQubits, __func__);
377 validate_quregCanBeReduced(qureg, numTraceQubits, __func__);
380 Qureg out = validateAndCreateCustomQureg(
381 qureg.numQubits - numTraceQubits,
382 qureg.isDensityMatrix, qureg.isDistributed,
383 qureg.isGpuAccelerated, qureg.isMultithreaded, __func__);
386 auto targets = util_getVector(traceOutQubits, numTraceQubits);
387 localiser_densmatr_partialTrace(qureg, out, targets);
394 validate_quregFields(qureg, __func__);
395 validate_quregIsDensityMatrix(qureg, __func__);
396 validate_targets(qureg, retainQubits, numRetainQubits, __func__);
397 validate_quregCanBeReduced(qureg, qureg.numQubits - numRetainQubits, __func__);
399 auto traceQubits = util_getNonTargetedQubits(retainQubits, numRetainQubits, qureg.numQubits);
421 validate_measurementOutcomesMatchTargets(qubits.size(), outcomes.size(), __func__);
432 qindex numOut = powerOf2(qubits.size());
433 auto callback = [&]() { validate_tempAllocSucceeded(
false, numOut,
sizeof(qreal), __func__); };
434 util_tryAllocVector(out, numOut, callback);
441 return calcPartialTrace(qureg, traceOutQubits.data(), traceOutQubits.size());
qcomp calcInnerProduct(Qureg quregA, Qureg quregB)
qreal calcFidelity(Qureg quregA, Qureg quregB)
qreal calcDistance(Qureg quregA, Qureg quregB)
qreal calcExpecFullStateDiagMatr(Qureg qureg, FullStateDiagMatr matrix)
qreal calcExpecFullStateDiagMatrPower(Qureg qureg, FullStateDiagMatr matrix, qreal exponent)
qcomp calcExpecNonHermitianFullStateDiagMatr(Qureg qureg, FullStateDiagMatr matrix)
qreal calcExpecPauliStrSum(Qureg qureg, PauliStrSum sum)
qcomp calcExpecNonHermitianPauliStrSum(Qureg qureg, PauliStrSum sum)
qcomp calcExpecNonHermitianFullStateDiagMatrPower(Qureg qureg, FullStateDiagMatr matrix, qcomp exponent)
qreal calcExpecPauliStr(Qureg qureg, PauliStr str)
Qureg calcReducedDensityMatrix(Qureg qureg, int *retainQubits, int numRetainQubits)
Qureg calcPartialTrace(Qureg qureg, int *traceOutQubits, int numTraceQubits)
qreal calcProbOfQubitOutcome(Qureg qureg, int qubit, int outcome)
void calcProbsOfAllMultiQubitOutcomes(qreal *outcomeProbs, Qureg qureg, int *qubits, int numQubits)
qreal calcProbOfBasisState(Qureg qureg, qindex index)
qreal calcProbOfMultiQubitOutcome(Qureg qureg, int *qubits, int *outcomes, int numQubits)
qreal calcPurity(Qureg qureg)
qreal calcTotalProb(Qureg qureg)