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 \
42 LABEL_UNIT_TAG "[decoherence]"
45void TEST_ON_CACHED_QUREGS(
auto apiFunc, vector<int> targs, vector<qmatrix> kraus) {
48 qmatrix reference = getRefDensmatr();
50 for (
auto& [label, qureg]: getCachedDensmatrs()) {
52 DYNAMIC_SECTION( label ) {
58 setToDebugState(reference);
61 applyReferenceOperator(reference, targs, kraus);
63 REQUIRE_AGREE( qureg, reference );
69void TEST_ON_MIXED_CACHED_QUREGS(
auto altQuregCache,
auto apiFunc,
auto refAlt,
auto refFunc) {
73 for (
auto& [labelA, quregOut]: getCachedDensmatrs()) {
74 for (
auto& [labelB, quregAlt]: altQuregCache) {
77 if (!quregOut.isDistributed && quregAlt.isDistributed && !quregAlt.isDensityMatrix)
81 if (quregAlt.isDensityMatrix && quregOut.isDistributed != quregAlt.isDistributed)
84 DYNAMIC_SECTION( labelA + LABEL_DELIMITER + labelB ) {
88 setQuregToReference(quregOut, refOut);
91 setToRandomState(refAlt);
92 setQuregToReference(quregAlt, refAlt);
94 apiFunc(quregOut, quregAlt);
95 refFunc(refOut, refAlt);
96 REQUIRE_AGREE( quregOut, refOut );
114 SECTION( LABEL_CORRECTNESS ) {
116 int numQubits = getNumCachedQubits();
117 int targ = GENERATE_COPY( range(0,numQubits) );
120 vector<qmatrix> kraus = {
121 std::sqrt(1-prob) * getPauliMatrix(0),
122 std::sqrt(prob) * getPauliMatrix(3)
127 CAPTURE( targ, prob );
128 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(apiFunc, {targ}, kraus); }
137 SECTION( LABEL_CORRECTNESS ) {
139 int numQubits = getNumCachedQubits();
140 int targ = GENERATE_COPY( range(0,numQubits) );
143 vector<qmatrix> kraus = {
144 std::sqrt(1-prob) * getPauliMatrix(0),
145 std::sqrt(prob/3) * getPauliMatrix(1),
146 std::sqrt(prob/3) * getPauliMatrix(2),
147 std::sqrt(prob/3) * getPauliMatrix(3),
152 CAPTURE( targ, prob );
153 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(apiFunc, {targ}, kraus); }
162 SECTION( LABEL_CORRECTNESS ) {
164 int numQubits = getNumCachedQubits();
165 int targ = GENERATE_COPY( range(0,numQubits) );
168 vector<qmatrix> kraus = {
169 {{1,0},{0,std::sqrt(1-prob)}},
170 {{0,std::sqrt(prob)}, {0,0}}
175 CAPTURE( targ, prob );
176 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(apiFunc, {targ}, kraus); }
185 SECTION( LABEL_CORRECTNESS ) {
187 int numQubits = getNumCachedQubits();
188 int targ = GENERATE_COPY( range(0,numQubits) );
195 qreal norm = pX + pY + pZ;
202 qreal pI = 1 - pX - pY - pZ;
203 while (std::max({pX,pY,pZ}) > pI) {
207 pI = 1 - pX - pY - pZ;
210 vector<qmatrix> kraus = {
211 std::sqrt(pI) * getPauliMatrix(0),
212 std::sqrt(pX) * getPauliMatrix(1),
213 std::sqrt(pY) * getPauliMatrix(2),
214 std::sqrt(pZ) * getPauliMatrix(3)
217 auto apiFunc = [&](
Qureg qureg) {
mixPaulis(qureg, targ, pX, pY, pZ); };
219 CAPTURE( targ, pX, pY, pZ );
220 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(apiFunc, {targ}, kraus); }
229 SECTION( LABEL_CORRECTNESS ) {
231 auto targs = GENERATE_TARGS( getNumCachedQubits(), 2 );
234 qmatrix i = getPauliMatrix(0);
235 qmatrix z = getPauliMatrix(3);
237 vector<qmatrix> kraus = {
246 CAPTURE( targs, prob );
247 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(apiFunc, targs, kraus); }
256 SECTION( LABEL_CORRECTNESS ) {
258 auto targs = GENERATE_TARGS( getNumCachedQubits(), 2 );
262 for (
int a=0; a<4; a++)
263 for (
int b=0; b<4; b++)
264 kraus.push_back( std::sqrt(prob/15) *
269 CAPTURE( targs, prob );
270 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(apiFunc, targs, kraus); }
279 SECTION( LABEL_CORRECTNESS ) {
281 int maxFlag = getMaxNumTestedSuperoperatorTargets();
282 int numQubits = getNumCachedQubits();
283 int maxNumTargs = (maxFlag != 0 && numQubits > maxFlag)?
286 int numTargs = GENERATE_COPY( range(1,maxNumTargs+1) );
287 int numKraus = GENERATE( 1, 2, 10 );
288 auto targs = GENERATE_TARGS( numQubits, numTargs );
293 auto apiFunc = [&](
Qureg qureg) {
mixKrausMap(qureg, targs.data(), numTargs, map); };
295 CAPTURE( maxNumTargs, targs, numKraus );
296 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(apiFunc, targs, matrices); }
307 SECTION( LABEL_CORRECTNESS ) {
309 int numQubits = getNumCachedQubits();
310 int maxFlag = getMaxNumTestedSuperoperatorTargets();
311 int maxNumTargs = (maxFlag != 0 && numQubits > maxFlag)?
314 int numTargs = GENERATE_COPY( range(1,maxNumTargs+1) );
315 auto targs = GENERATE_TARGS( numQubits, numTargs );
319 setSuperOp(superOp, getSuperOperator(matrices));
320 auto apiFunc = [&](
Qureg qureg) {
mixSuperOp(qureg, targs.data(), numTargs, superOp); };
323 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(apiFunc, targs, matrices); }
332TEST_CASE(
"mixQureg", TEST_CATEGORY LABEL_MIXED_DEPLOY_TAG ) {
334 SECTION( LABEL_CORRECTNESS ) {
341 GENERATE( range(0, getNumTestedMixedDeploymentRepetitions()) );
343 SECTION( LABEL_DENSMATR LABEL_DELIMITER LABEL_STATEVEC ) {
345 auto refFunc = [&](qmatrix& a, qvector b) { a = (1-prob)*a + prob*getOuterProduct(b,b); };
347 TEST_ON_MIXED_CACHED_QUREGS( getAltCachedStatevecs(), apiFunc, getRefStatevec(), refFunc);
350 SECTION( LABEL_DENSMATR LABEL_DELIMITER LABEL_DENSMATR ) {
352 auto refFunc = [&](qmatrix& a, qmatrix b) { a = (1-prob)*a + prob*b; };
354 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)