12#include <catch2/catch_test_macros.hpp>
13#include <catch2/matchers/catch_matchers_string.hpp>
14#include <catch2/generators/catch_generators_range.hpp>
16#include "tests/utils/qvector.hpp"
17#include "tests/utils/qmatrix.hpp"
18#include "tests/utils/config.hpp"
19#include "tests/utils/cache.hpp"
20#include "tests/utils/compare.hpp"
21#include "tests/utils/convert.hpp"
22#include "tests/utils/evolve.hpp"
23#include "tests/utils/linalg.hpp"
24#include "tests/utils/lists.hpp"
25#include "tests/utils/macros.hpp"
26#include "tests/utils/random.hpp"
31using Catch::Matchers::ContainsSubstring;
41#define TEST_CATEGORY "[unit][decoherence]"
44void TEST_ON_CACHED_QUREGS(
auto apiFunc, vector<int> targs, vector<qmatrix> kraus) {
47 qmatrix reference = getRefDensmatr();
49 for (
auto& [label, qureg]: getCachedDensmatrs()) {
51 DYNAMIC_SECTION( label ) {
57 setToDebugState(reference);
60 applyReferenceOperator(reference, targs, kraus);
62 REQUIRE_AGREE( qureg, reference );
68void TEST_ON_MIXED_CACHED_QUREGS(
auto altQuregCache,
auto apiFunc,
auto refAlt,
auto refFunc) {
72 for (
auto& [labelA, quregOut]: getCachedDensmatrs()) {
73 for (
auto& [labelB, quregAlt]: altQuregCache) {
76 if (!quregOut.isDistributed && quregAlt.isDistributed && !quregAlt.isDensityMatrix)
80 if (quregAlt.isDensityMatrix && quregOut.isDistributed != quregAlt.isDistributed)
83 DYNAMIC_SECTION( labelA + LABEL_DELIMITER + labelB ) {
87 setQuregToReference(quregOut, refOut);
90 setToRandomState(refAlt);
91 setQuregToReference(quregAlt, refAlt);
93 apiFunc(quregOut, quregAlt);
94 refFunc(refOut, refAlt);
95 REQUIRE_AGREE( quregOut, refOut );
113 SECTION( LABEL_CORRECTNESS ) {
115 int numQubits = getNumCachedQubits();
116 int targ = GENERATE_COPY( range(0,numQubits) );
119 vector<qmatrix> kraus = {
120 std::sqrt(1-prob) * getPauliMatrix(0),
121 std::sqrt(prob) * getPauliMatrix(3)
126 CAPTURE( targ, prob );
127 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(apiFunc, {targ}, kraus); }
136 SECTION( LABEL_CORRECTNESS ) {
138 int numQubits = getNumCachedQubits();
139 int targ = GENERATE_COPY( range(0,numQubits) );
142 vector<qmatrix> kraus = {
143 std::sqrt(1-prob) * getPauliMatrix(0),
144 std::sqrt(prob/3) * getPauliMatrix(1),
145 std::sqrt(prob/3) * getPauliMatrix(2),
146 std::sqrt(prob/3) * getPauliMatrix(3),
151 CAPTURE( targ, prob );
152 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(apiFunc, {targ}, kraus); }
161 SECTION( LABEL_CORRECTNESS ) {
163 int numQubits = getNumCachedQubits();
164 int targ = GENERATE_COPY( range(0,numQubits) );
167 vector<qmatrix> kraus = {
168 {{1,0},{0,std::sqrt(1-prob)}},
169 {{0,std::sqrt(prob)}, {0,0}}
174 CAPTURE( targ, prob );
175 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(apiFunc, {targ}, kraus); }
184 SECTION( LABEL_CORRECTNESS ) {
186 int numQubits = getNumCachedQubits();
187 int targ = GENERATE_COPY( range(0,numQubits) );
194 qreal norm = pX + pY + pZ;
201 qreal pI = 1 - pX - pY - pZ;
202 while (std::max({pX,pY,pZ}) > pI) {
206 pI = 1 - pX - pY - pZ;
209 vector<qmatrix> kraus = {
210 std::sqrt(pI) * getPauliMatrix(0),
211 std::sqrt(pX) * getPauliMatrix(1),
212 std::sqrt(pY) * getPauliMatrix(2),
213 std::sqrt(pZ) * getPauliMatrix(3)
216 auto apiFunc = [&](
Qureg qureg) {
mixPaulis(qureg, targ, pX, pY, pZ); };
218 CAPTURE( targ, pX, pY, pZ );
219 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(apiFunc, {targ}, kraus); }
228 SECTION( LABEL_CORRECTNESS ) {
230 auto targs = GENERATE_TARGS( getNumCachedQubits(), 2 );
233 qmatrix i = getPauliMatrix(0);
234 qmatrix z = getPauliMatrix(3);
236 vector<qmatrix> kraus = {
245 CAPTURE( targs, prob );
246 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(apiFunc, targs, kraus); }
255 SECTION( LABEL_CORRECTNESS ) {
257 auto targs = GENERATE_TARGS( getNumCachedQubits(), 2 );
261 for (
int a=0; a<4; a++)
262 for (
int b=0; b<4; b++)
263 kraus.push_back( std::sqrt(prob/15) *
268 CAPTURE( targs, prob );
269 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(apiFunc, targs, kraus); }
278 SECTION( LABEL_CORRECTNESS ) {
280 int maxFlag = getMaxNumTestedSuperoperatorTargets();
281 int numQubits = getNumCachedQubits();
282 int maxNumTargs = (maxFlag != 0 && numQubits > maxFlag)?
285 int numTargs = GENERATE_COPY( range(1,maxNumTargs+1) );
286 int numKraus = GENERATE( 1, 2, 10 );
287 auto targs = GENERATE_TARGS( numQubits, numTargs );
292 auto apiFunc = [&](
Qureg qureg) {
mixKrausMap(qureg, targs.data(), numTargs, map); };
294 CAPTURE( maxNumTargs, targs, numKraus );
295 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(apiFunc, targs, matrices); }
306 SECTION( LABEL_CORRECTNESS ) {
308 int numQubits = getNumCachedQubits();
309 int maxFlag = getMaxNumTestedSuperoperatorTargets();
310 int maxNumTargs = (maxFlag != 0 && numQubits > maxFlag)?
313 int numTargs = GENERATE_COPY( range(1,maxNumTargs+1) );
314 auto targs = GENERATE_TARGS( numQubits, numTargs );
318 setSuperOp(superOp, getSuperOperator(matrices));
319 auto apiFunc = [&](
Qureg qureg) {
mixSuperOp(qureg, targs.data(), numTargs, superOp); };
322 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(apiFunc, targs, matrices); }
331TEST_CASE(
"mixQureg", TEST_CATEGORY LABEL_MIXED_DEPLOY_TAG ) {
333 SECTION( LABEL_CORRECTNESS ) {
340 GENERATE( range(0, getNumTestedMixedDeploymentRepetitions()) );
342 SECTION( LABEL_DENSMATR LABEL_DELIMITER LABEL_STATEVEC ) {
344 auto refFunc = [&](qmatrix& a, qvector b) { a = (1-prob)*a + prob*getOuterProduct(b,b); };
346 TEST_ON_MIXED_CACHED_QUREGS( getAltCachedStatevecs(), apiFunc, getRefStatevec(), refFunc);
349 SECTION( LABEL_DENSMATR LABEL_DELIMITER LABEL_DENSMATR ) {
351 auto refFunc = [&](qmatrix& a, qmatrix b) { a = (1-prob)*a + prob*b; };
353 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 mixQureg(Qureg qureg, Qureg other, qreal prob)
void mixPaulis(Qureg qureg, int target, 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 mixTwoQubitDephasing(Qureg qureg, int target1, int target2, qreal prob)
void mixTwoQubitDepolarising(Qureg qureg, int target1, int target2, qreal prob)
void mixDamping(Qureg qureg, int target, qreal prob)
void mixDephasing(Qureg qureg, int target, qreal prob)
void mixDepolarising(Qureg qureg, int target, qreal prob)
void initDebugState(Qureg qureg)
qmatrix getKroneckerProduct(qmatrix a, qmatrix b)
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)