10#include "quest/include/quest.h"
12#include <catch2/catch_test_macros.hpp>
13#include <catch2/generators/catch_generators_range.hpp>
15#include "tests/utils/qvector.hpp"
16#include "tests/utils/qmatrix.hpp"
17#include "tests/utils/cache.hpp"
18#include "tests/utils/compare.hpp"
19#include "tests/utils/convert.hpp"
20#include "tests/utils/evolve.hpp"
21#include "tests/utils/linalg.hpp"
22#include "tests/utils/lists.hpp"
23#include "tests/utils/macros.hpp"
24#include "tests/utils/random.hpp"
38#define TEST_CATEGORY "[unit][decoherence]"
41void TEST_ON_CACHED_QUREGS(
auto apiFunc, vector<int> targs, vector<qmatrix> kraus) {
44 qmatrix reference = getRefDensmatr();
46 for (
auto& [label, qureg]: getCachedDensmatrs()) {
48 DYNAMIC_SECTION( label ) {
54 setToDebugState(reference);
57 applyReferenceOperator(reference, targs, kraus);
59 REQUIRE_AGREE( qureg, reference );
65void TEST_ON_MIXED_CACHED_QUREGS(
auto altQuregCache,
auto apiFunc,
auto refAlt,
auto refFunc) {
69 for (
auto& [labelA, quregOut]: getCachedDensmatrs()) {
70 for (
auto& [labelB, quregAlt]: altQuregCache) {
73 if (!quregOut.isDistributed && quregAlt.isDistributed && !quregAlt.isDensityMatrix)
77 if (quregAlt.isDensityMatrix && quregOut.isDistributed != quregAlt.isDistributed)
80 DYNAMIC_SECTION( labelA + LABEL_DELIMITER + labelB ) {
84 setQuregToReference(quregOut, refOut);
87 setToRandomState(refAlt);
88 setQuregToReference(quregAlt, refAlt);
90 apiFunc(quregOut, quregAlt);
91 refFunc(refOut, refAlt);
92 REQUIRE_AGREE( quregOut, refOut );
110 SECTION( LABEL_CORRECTNESS ) {
112 int numQubits = getNumCachedQubits();
113 int targ = GENERATE_COPY( range(0,numQubits) );
116 vector<qmatrix> kraus = {
117 std::sqrt(1-prob) * getPauliMatrix(0),
118 std::sqrt(prob) * getPauliMatrix(3)
123 CAPTURE( targ, prob );
124 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(apiFunc, {targ}, kraus); }
133 SECTION( LABEL_CORRECTNESS ) {
135 int numQubits = getNumCachedQubits();
136 int targ = GENERATE_COPY( range(0,numQubits) );
139 vector<qmatrix> kraus = {
140 std::sqrt(1-prob) * getPauliMatrix(0),
141 std::sqrt(prob/3) * getPauliMatrix(1),
142 std::sqrt(prob/3) * getPauliMatrix(2),
143 std::sqrt(prob/3) * getPauliMatrix(3),
148 CAPTURE( targ, prob );
149 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(apiFunc, {targ}, kraus); }
158 SECTION( LABEL_CORRECTNESS ) {
160 int numQubits = getNumCachedQubits();
161 int targ = GENERATE_COPY( range(0,numQubits) );
164 vector<qmatrix> kraus = {
165 {{1,0},{0,std::sqrt(1-prob)}},
166 {{0,std::sqrt(prob)}, {0,0}}
171 CAPTURE( targ, prob );
172 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(apiFunc, {targ}, kraus); }
181 SECTION( LABEL_CORRECTNESS ) {
183 int numQubits = getNumCachedQubits();
184 int targ = GENERATE_COPY( range(0,numQubits) );
191 qreal norm = pX + pY + pZ;
198 qreal pI = 1 - pX - pY - pZ;
199 while (std::max({pX,pY,pZ}) > pI) {
203 pI = 1 - pX - pY - pZ;
206 vector<qmatrix> kraus = {
207 std::sqrt(pI) * getPauliMatrix(0),
208 std::sqrt(pX) * getPauliMatrix(1),
209 std::sqrt(pY) * getPauliMatrix(2),
210 std::sqrt(pZ) * getPauliMatrix(3)
213 auto apiFunc = [&](
Qureg qureg) {
mixPaulis(qureg, targ, pX, pY, pZ); };
215 CAPTURE( targ, pX, pY, pZ );
216 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(apiFunc, {targ}, kraus); }
225 SECTION( LABEL_CORRECTNESS ) {
227 auto targs = GENERATE_TARGS( getNumCachedQubits(), 2 );
230 qmatrix i = getPauliMatrix(0);
231 qmatrix z = getPauliMatrix(3);
233 vector<qmatrix> kraus = {
242 CAPTURE( targs, prob );
243 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(apiFunc, targs, kraus); }
252 SECTION( LABEL_CORRECTNESS ) {
254 auto targs = GENERATE_TARGS( getNumCachedQubits(), 2 );
258 for (
int a=0; a<4; a++)
259 for (
int b=0; b<4; b++)
260 kraus.push_back( std::sqrt(prob/15) *
265 CAPTURE( targs, prob );
266 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(apiFunc, targs, kraus); }
275 SECTION( LABEL_CORRECTNESS ) {
278 int numQubits = getNumCachedQubits();
279 int maxNumTargs = (maxFlag != 0 && numQubits > maxFlag)?
282 int numTargs = GENERATE_COPY( range(1,maxNumTargs+1) );
283 int numKraus = GENERATE( 1, 2, 10 );
284 auto targs = GENERATE_TARGS( numQubits, numTargs );
289 auto apiFunc = [&](
Qureg qureg) {
mixKrausMap(qureg, targs.data(), numTargs, map); };
291 CAPTURE( maxNumTargs, targs, numKraus );
292 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(apiFunc, targs, matrices); }
303 SECTION( LABEL_CORRECTNESS ) {
305 int numQubits = getNumCachedQubits();
307 int maxNumTargs = (maxFlag != 0 && numQubits > maxFlag)?
310 int numTargs = GENERATE_COPY( range(1,maxNumTargs+1) );
311 auto targs = GENERATE_TARGS( numQubits, numTargs );
315 setSuperOp(superOp, getSuperOperator(matrices));
316 auto apiFunc = [&](
Qureg qureg) {
mixSuperOp(qureg, targs.data(), numTargs, superOp); };
319 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(apiFunc, targs, matrices); }
328TEST_CASE(
"mixQureg", TEST_CATEGORY LABEL_MIXED_DEPLOY_TAG ) {
330 SECTION( LABEL_CORRECTNESS ) {
339 SECTION( LABEL_DENSMATR LABEL_DELIMITER LABEL_STATEVEC ) {
341 auto refFunc = [&](qmatrix& a, qvector b) { a = (1-prob)*a + prob*getOuterProduct(b,b); };
343 TEST_ON_MIXED_CACHED_QUREGS( getAltCachedStatevecs(), apiFunc, getRefStatevec(), refFunc);
346 SECTION( LABEL_DENSMATR LABEL_DELIMITER LABEL_DENSMATR ) {
348 auto refFunc = [&](qmatrix& a, qmatrix b) { a = (1-prob)*a + prob*b; };
350 TEST_ON_MIXED_CACHED_QUREGS( getAltCachedDensmatrs(), apiFunc, getRefDensmatr(), refFunc);
KrausMap createKrausMap(int numQubits, int numOperators)
SuperOp createSuperOp(int numQubits)
void destroySuperOp(SuperOp op)
void destroyKrausMap(KrausMap map)
void setSuperOp(SuperOp op, qcomp **matrix)
void setKrausMap(KrausMap map, qcomp ***matrices)
void mixDepolarising(Qureg qureg, int qubit, qreal prob)
void mixTwoQubitDephasing(Qureg qureg, int qubit1, int qubit2, qreal prob)
void mixQureg(Qureg qureg, Qureg other, qreal prob)
void mixDamping(Qureg qureg, int qubit, qreal prob)
void mixPaulis(Qureg qureg, int qubit, qreal probX, qreal probY, qreal probZ)
void mixKrausMap(Qureg qureg, int *targets, int numTargets, KrausMap map)
void mixSuperOp(Qureg qureg, int *targets, int numTargets, SuperOp superop)
void mixTwoQubitDepolarising(Qureg qureg, int qubit1, int qubit2, qreal prob)
void mixDephasing(Qureg qureg, int qubit, qreal prob)
void initDebugState(Qureg qureg)
qmatrix getKroneckerProduct(qmatrix a, qmatrix b)
const int TEST_MAX_NUM_SUPEROP_TARGETS
const int TEST_NUM_MIXED_DEPLOYMENT_REPETITIONS
qmatrix getIdentityMatrix(size_t dim)
qreal getRandomReal(qreal min, qreal maxExcl)
qmatrix getRandomDensityMatrix(int numQb)
vector< qmatrix > getRandomKrausMap(int numQb, int numOps)
int getRandomInt(int min, int maxExcl)
TEST_CASE("mixDephasing", TEST_CATEGORY)