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/lists.hpp"
16#include "quest/src/core/utilities.hpp"
17#include "quest/src/core/localiser.hpp"
18#include "quest/src/core/bitwise.hpp"
19#include "quest/src/core/errors.hpp"
31extern Qureg validateAndCreateCustomQureg(
32 int numQubits,
int isDensMatr,
int useDistrib,
33 int useGpuAccel,
int useMultithread,
const char* caller);
51 validate_quregFields(quregA, __func__);
52 validate_quregFields(quregB, __func__);
53 validate_quregsCanBeProducted(quregA, quregB, __func__);
56 if (quregA.isDensityMatrix == quregB.isDensityMatrix)
57 return localiser_statevec_calcInnerProduct(quregA, quregB);
59 return (quregA.isDensityMatrix)?
60 localiser_densmatr_calcFidelityWithPureState(quregA, quregB,
true):
61 localiser_densmatr_calcFidelityWithPureState(quregB, quregA,
false);
63extern "C" void _wrap_calcInnerProduct(
Qureg bra,
Qureg ket, qcomp* out) {
70 validate_quregFields(qureg, __func__);
71 validate_pauliStrSumFields(sum, __func__);
72 validate_pauliStrSumTargets(sum, qureg, __func__);
74 qcomp value = (qureg.isDensityMatrix)?
75 localiser_densmatr_calcExpecPauliStrSum(qureg, sum):
76 localiser_statevec_calcExpecPauliStrSum(qureg, sum);
80extern "C" void _wrap_calcExpecNonHermitianPauliStrSum(qcomp* out,
Qureg qureg,
PauliStrSum sum) {
87 validate_quregFields(qureg, __func__);
88 validate_matrixFields(matrix, __func__);
89 validate_matrixAndQuregAreCompatible(matrix, qureg,
true, __func__);
93extern "C" void _wrap_calcExpecNonHermitianFullStateDiagMatr(qcomp* out,
Qureg qureg,
FullStateDiagMatr matr) {
100 validate_quregFields(qureg, __func__);
101 validate_matrixFields(matrix, __func__);
102 validate_matrixAndQuregAreCompatible(matrix, qureg,
true, __func__);
107 const bool useRealPow =
false;
109 return (qureg.isDensityMatrix)?
110 localiser_densmatr_calcExpecFullStateDiagMatr(qureg, matrix, exponent, useRealPow):
111 localiser_statevec_calcExpecFullStateDiagMatr(qureg, matrix, exponent, useRealPow);
113extern "C" void _wrap_calcExpecNonHermitianFullStateDiagMatrPower(qcomp* out,
Qureg qureg,
FullStateDiagMatr matr, qcomp exponent) {
135 validate_quregFields(qureg, __func__);
136 validate_pauliStrTargets(qureg, str, __func__);
138 qcomp value = (qureg.isDensityMatrix)?
139 localiser_densmatr_calcExpecPauliStr(qureg, str):
140 localiser_statevec_calcExpecPauliStr(qureg, str);
142 validate_expecPauliStrValueIsReal(value, qureg.isDensityMatrix, __func__);
143 return std::real(value);
148 validate_quregFields(qureg, __func__);
149 validate_pauliStrSumFields(sum, __func__);
150 validate_pauliStrSumTargets(sum, qureg, __func__);
151 validate_pauliStrSumIsHermitian(sum, __func__);
153 qcomp value = (qureg.isDensityMatrix)?
154 localiser_densmatr_calcExpecPauliStrSum(qureg, sum):
155 localiser_statevec_calcExpecPauliStrSum(qureg, sum);
157 validate_expecPauliStrSumValueIsReal(value, qureg.isDensityMatrix, __func__);
158 return std::real(value);
163 validate_quregFields(qureg, __func__);
164 validate_matrixFields(matrix, __func__);
165 validate_matrixAndQuregAreCompatible(matrix, qureg,
true, __func__);
166 validate_matrixIsHermitian(matrix, __func__);
169 qcomp exponent = qcomp(1,0);
170 bool useRealPow =
false;
172 qcomp value = (qureg.isDensityMatrix)?
173 localiser_densmatr_calcExpecFullStateDiagMatr(qureg, matrix, exponent, useRealPow):
174 localiser_statevec_calcExpecFullStateDiagMatr(qureg, matrix, exponent, useRealPow);
179 if (qureg.isDensityMatrix)
180 validate_densMatrExpecDiagMatrValueIsReal(value, exponent, __func__);
182 return std::real(value);
187 validate_quregFields(qureg, __func__);
188 validate_matrixFields(matrix, __func__);
189 validate_matrixAndQuregAreCompatible(matrix, qureg,
true, __func__);
190 validate_matrixExpIsHermitian(matrix, exponent, __func__);
200 const bool useRealPow =
true;
202 qcomp value = (qureg.isDensityMatrix)?
203 localiser_densmatr_calcExpecFullStateDiagMatr(qureg, matrix, exponent, useRealPow):
204 localiser_statevec_calcExpecFullStateDiagMatr(qureg, matrix, exponent, useRealPow);
212 if (qureg.isDensityMatrix)
213 validate_densMatrExpecDiagMatrValueIsReal(value, exponent, __func__);
215 return std::real(value);
226 validate_quregFields(qureg, __func__);
227 validate_basisStateIndex(qureg, index, __func__);
230 if (qureg.isDensityMatrix)
231 index *= 1 + powerOf2(qureg.numQubits);
233 qcomp amp = localiser_statevec_getAmp(qureg, index);
234 qreal prob = (qureg.isDensityMatrix)?
243 validate_quregFields(qureg, __func__);
244 validate_target(qureg, qubit, __func__);
245 validate_measurementOutcomeIsValid(outcome, __func__);
253 validate_quregFields(qureg, __func__);
254 validate_targets(qureg, qubits, numQubits, __func__);
255 validate_measurementOutcomesAreValid(outcomes, numQubits, __func__);
257 auto qubitList = lists_getList64(qubits, numQubits);
258 auto outcomeList = lists_getList64(outcomes, numQubits);
260 return (qureg.isDensityMatrix)?
261 localiser_densmatr_calcProbOfMultiQubitOutcome(qureg, qubitList, outcomeList):
262 localiser_statevec_calcProbOfMultiQubitOutcome(qureg, qubitList, outcomeList);
267 validate_quregFields(qureg, __func__);
268 validate_targets(qureg, qubits, numQubits, __func__);
269 validate_measurementOutcomesFitInGpuMem(qureg, numQubits, __func__);
271 auto qubitList = lists_getList64(qubits, numQubits);
273 (qureg.isDensityMatrix)?
274 localiser_densmatr_calcProbsOfAllMultiQubitOutcomes(outcomeProbs, qureg, qubitList):
275 localiser_statevec_calcProbsOfAllMultiQubitOutcomes(outcomeProbs, qureg, qubitList);
280 validate_quregFields(qureg, __func__);
282 return (qureg.isDensityMatrix)?
283 localiser_densmatr_calcTotalProb(qureg):
284 localiser_statevec_calcTotalProb(qureg);
295 validate_quregFields(qureg, __func__);
299 qreal prob = localiser_statevec_calcTotalProb(qureg);
300 return (qureg.isDensityMatrix)? prob : prob * prob;
305 validate_quregFields(quregA, __func__);
306 validate_quregFields(quregB, __func__);
307 validate_quregsCanBeProducted(quregA, quregB, __func__);
309 bool isDensA = quregA.isDensityMatrix;
310 bool isDensB = quregB.isDensityMatrix;
313 if (isDensA && isDensB)
314 validate_throwErrorBecauseCalcFidOfDensMatrNotYetImplemented(__func__);
317 if (!isDensA && !isDensB) {
318 qcomp prod = localiser_statevec_calcInnerProduct(quregA, quregB);
319 return std::norm(prod);
323 qcomp fid = (quregA.isDensityMatrix)?
324 localiser_densmatr_calcFidelityWithPureState(quregA, quregB,
false):
325 localiser_densmatr_calcFidelityWithPureState(quregB, quregA,
false);
327 validate_fidelityIsReal(fid, __func__);
328 return std::real(fid);
333 validate_quregFields(quregA, __func__);
334 validate_quregFields(quregB, __func__);
335 validate_quregsCanBeProducted(quregA, quregB, __func__);
337 bool isDensA = quregA.isDensityMatrix;
338 bool isDensB = quregB.isDensityMatrix;
341 if (isDensA && isDensB) {
342 qreal dif = localiser_densmatr_calcHilbertSchmidtDistance(quregA, quregB);
343 return std::sqrt(dif);
347 if (!isDensA && !isDensB) {
348 qcomp prod = localiser_statevec_calcInnerProduct(quregA, quregB);
349 qreal mag = std::abs(prod);
351 validate_buresDistanceInnerProdIsNormalised(mag, __func__);
352 mag = (mag > 1)? 1 : mag;
353 return std::sqrt(2 - 2 * mag);
357 qcomp fid = (quregA.isDensityMatrix)?
358 localiser_densmatr_calcFidelityWithPureState(quregA, quregB,
false):
359 localiser_densmatr_calcFidelityWithPureState(quregB, quregA,
false);
361 validate_purifiedDistanceIsNormalised(fid, __func__);
362 qreal re = std::real(fid);
363 re = (re > 1)? 1 : re;
364 return std::sqrt(1 - re);
375 validate_quregFields(qureg, __func__);
376 validate_quregIsDensityMatrix(qureg, __func__);
377 validate_targets(qureg, traceOutQubits, numTraceQubits, __func__);
378 validate_quregCanBeReduced(qureg, numTraceQubits, __func__);
381 Qureg out = validateAndCreateCustomQureg(
382 qureg.numQubits - numTraceQubits,
383 qureg.isDensityMatrix, qureg.isDistributed,
384 qureg.isGpuAccelerated, qureg.isMultithreaded, __func__);
387 auto targets = lists_getList64(traceOutQubits, numTraceQubits);
388 localiser_densmatr_partialTrace(qureg, out, targets);
395 validate_quregFields(qureg, __func__);
396 validate_quregIsDensityMatrix(qureg, __func__);
397 validate_targets(qureg, retainQubits, numRetainQubits, __func__);
398 validate_quregCanBeReduced(qureg, qureg.numQubits - numRetainQubits, __func__);
400 auto traceQubits = util_getNonTargetedQubits(lists_getList64(retainQubits, numRetainQubits), qureg.numQubits);
422 validate_measurementOutcomesMatchTargets(qubits.size(), outcomes.size(), __func__);
433 qindex numOut = powerOf2(qubits.size());
434 auto callback = [&]() { validate_tempListAllocSucceeded(
false, numOut,
sizeof(qreal), __func__); };
435 util_tryAllocVector(out, numOut, callback);
442 return calcPartialTrace(qureg, traceOutQubits.data(), traceOutQubits.size());
qreal calcFidelity(Qureg quregA, Qureg quregB)
qreal calcDistance(Qureg quregA, Qureg quregB)
qcomp calcInnerProduct(Qureg quregA, Qureg quregB)
qreal calcExpecFullStateDiagMatr(Qureg qureg, FullStateDiagMatr matrix)
qcomp calcExpecNonHermitianFullStateDiagMatr(Qureg qureg, FullStateDiagMatr matrix)
qreal calcExpecPauliStrSum(Qureg qureg, PauliStrSum sum)
qcomp calcExpecNonHermitianPauliStrSum(Qureg qureg, PauliStrSum sum)
qreal calcExpecFullStateDiagMatrPower(Qureg qureg, FullStateDiagMatr matrix, qreal exponent)
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)