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/cache.hpp"
19#include "tests/utils/compare.hpp"
20#include "tests/utils/convert.hpp"
21#include "tests/utils/evolve.hpp"
22#include "tests/utils/linalg.hpp"
23#include "tests/utils/lists.hpp"
24#include "tests/utils/macros.hpp"
25#include "tests/utils/random.hpp"
30using Catch::Matchers::ContainsSubstring;
40#define TEST_CATEGORY "[unit][decoherence]"
43void TEST_ON_CACHED_QUREGS(
auto apiFunc, vector<int> targs, vector<qmatrix> kraus) {
46 qmatrix reference = getRefDensmatr();
48 for (
auto& [label, qureg]: getCachedDensmatrs()) {
50 DYNAMIC_SECTION( label ) {
56 setToDebugState(reference);
59 applyReferenceOperator(reference, targs, kraus);
61 REQUIRE_AGREE( qureg, reference );
67void TEST_ON_MIXED_CACHED_QUREGS(
auto altQuregCache,
auto apiFunc,
auto refAlt,
auto refFunc) {
71 for (
auto& [labelA, quregOut]: getCachedDensmatrs()) {
72 for (
auto& [labelB, quregAlt]: altQuregCache) {
75 if (!quregOut.isDistributed && quregAlt.isDistributed && !quregAlt.isDensityMatrix)
79 if (quregAlt.isDensityMatrix && quregOut.isDistributed != quregAlt.isDistributed)
82 DYNAMIC_SECTION( labelA + LABEL_DELIMITER + labelB ) {
86 setQuregToReference(quregOut, refOut);
89 setToRandomState(refAlt);
90 setQuregToReference(quregAlt, refAlt);
92 apiFunc(quregOut, quregAlt);
93 refFunc(refOut, refAlt);
94 REQUIRE_AGREE( quregOut, refOut );
112 SECTION( LABEL_CORRECTNESS ) {
114 int numQubits = getNumCachedQubits();
115 int targ = GENERATE_COPY( range(0,numQubits) );
118 vector<qmatrix> kraus = {
119 std::sqrt(1-prob) * getPauliMatrix(0),
120 std::sqrt(prob) * getPauliMatrix(3)
125 CAPTURE( targ, prob );
126 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(apiFunc, {targ}, kraus); }
135 SECTION( LABEL_CORRECTNESS ) {
137 int numQubits = getNumCachedQubits();
138 int targ = GENERATE_COPY( range(0,numQubits) );
141 vector<qmatrix> kraus = {
142 std::sqrt(1-prob) * getPauliMatrix(0),
143 std::sqrt(prob/3) * getPauliMatrix(1),
144 std::sqrt(prob/3) * getPauliMatrix(2),
145 std::sqrt(prob/3) * getPauliMatrix(3),
150 CAPTURE( targ, prob );
151 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(apiFunc, {targ}, kraus); }
160 SECTION( LABEL_CORRECTNESS ) {
162 int numQubits = getNumCachedQubits();
163 int targ = GENERATE_COPY( range(0,numQubits) );
166 vector<qmatrix> kraus = {
167 {{1,0},{0,std::sqrt(1-prob)}},
168 {{0,std::sqrt(prob)}, {0,0}}
173 CAPTURE( targ, prob );
174 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(apiFunc, {targ}, kraus); }
183 SECTION( LABEL_CORRECTNESS ) {
185 int numQubits = getNumCachedQubits();
186 int targ = GENERATE_COPY( range(0,numQubits) );
193 qreal norm = pX + pY + pZ;
200 qreal pI = 1 - pX - pY - pZ;
201 while (std::max({pX,pY,pZ}) > pI) {
205 pI = 1 - pX - pY - pZ;
208 vector<qmatrix> kraus = {
209 std::sqrt(pI) * getPauliMatrix(0),
210 std::sqrt(pX) * getPauliMatrix(1),
211 std::sqrt(pY) * getPauliMatrix(2),
212 std::sqrt(pZ) * getPauliMatrix(3)
215 auto apiFunc = [&](
Qureg qureg) {
mixPaulis(qureg, targ, pX, pY, pZ); };
217 CAPTURE( targ, pX, pY, pZ );
218 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(apiFunc, {targ}, kraus); }
227 SECTION( LABEL_CORRECTNESS ) {
229 auto targs = GENERATE_TARGS( getNumCachedQubits(), 2 );
232 qmatrix i = getPauliMatrix(0);
233 qmatrix z = getPauliMatrix(3);
235 vector<qmatrix> kraus = {
244 CAPTURE( targs, prob );
245 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(apiFunc, targs, kraus); }
254 SECTION( LABEL_CORRECTNESS ) {
256 auto targs = GENERATE_TARGS( getNumCachedQubits(), 2 );
260 for (
int a=0; a<4; a++)
261 for (
int b=0; b<4; b++)
262 kraus.push_back( std::sqrt(prob/15) *
267 CAPTURE( targs, prob );
268 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(apiFunc, targs, kraus); }
277 SECTION( LABEL_CORRECTNESS ) {
280 int numQubits = getNumCachedQubits();
281 int maxNumTargs = (maxFlag != 0 && numQubits > maxFlag)?
284 int numTargs = GENERATE_COPY( range(1,maxNumTargs+1) );
285 int numKraus = GENERATE( 1, 2, 10 );
286 auto targs = GENERATE_TARGS( numQubits, numTargs );
291 auto apiFunc = [&](
Qureg qureg) {
mixKrausMap(qureg, targs.data(), numTargs, map); };
293 CAPTURE( maxNumTargs, targs, numKraus );
294 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(apiFunc, targs, matrices); }
305 SECTION( LABEL_CORRECTNESS ) {
307 int numQubits = getNumCachedQubits();
309 int maxNumTargs = (maxFlag != 0 && numQubits > maxFlag)?
312 int numTargs = GENERATE_COPY( range(1,maxNumTargs+1) );
313 auto targs = GENERATE_TARGS( numQubits, numTargs );
317 setSuperOp(superOp, getSuperOperator(matrices));
318 auto apiFunc = [&](
Qureg qureg) {
mixSuperOp(qureg, targs.data(), numTargs, superOp); };
321 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(apiFunc, targs, matrices); }
330TEST_CASE(
"mixQureg", TEST_CATEGORY LABEL_MIXED_DEPLOY_TAG ) {
332 SECTION( LABEL_CORRECTNESS ) {
341 SECTION( LABEL_DENSMATR LABEL_DELIMITER LABEL_STATEVEC ) {
343 auto refFunc = [&](qmatrix& a, qvector b) { a = (1-prob)*a + prob*getOuterProduct(b,b); };
345 TEST_ON_MIXED_CACHED_QUREGS( getAltCachedStatevecs(), apiFunc, getRefStatevec(), refFunc);
348 SECTION( LABEL_DENSMATR LABEL_DELIMITER LABEL_DENSMATR ) {
350 auto refFunc = [&](qmatrix& a, qmatrix b) { a = (1-prob)*a + prob*b; };
352 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)
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)