10#include "quest/include/quest.h"
12#include <catch2/catch_test_macros.hpp>
13#include <catch2/catch_template_test_macros.hpp>
14#include <catch2/matchers/catch_matchers_string.hpp>
15#include <catch2/generators/catch_generators_range.hpp>
17#include "tests/utils/cache.hpp"
18#include "tests/utils/qvector.hpp"
19#include "tests/utils/qmatrix.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/measure.hpp"
26#include "tests/utils/macros.hpp"
27#include "tests/utils/random.hpp"
39#define TEST_CATEGORY \
40 LABEL_UNIT_TAG "[operations]"
47namespace FixedMatrices {
50 {1/std::sqrt(2), 1/std::sqrt(2)},
51 {1/std::sqrt(2), -1/std::sqrt(2)}};
53 qmatrix X = getPauliMatrix(1);
54 qmatrix Y = getPauliMatrix(2);
55 qmatrix Z = getPauliMatrix(3);
57 qreal PI = 3.14159265358979323846;
60 {0, std::exp(1_i * PI/4)}};
74 {0, (1+1_i)/2, (1-1_i)/2, 0},
75 {0, (1-1_i)/2, (1+1_i)/2, 0},
79namespace ParameterisedMatrices {
85 auto PS = [](qreal p) {
return qmatrix{{1, 0}, {0, std::exp(p*1_i)}}; };
86 auto PS2 = [](qreal p) {
return getControlledMatrix(PS(p), 1); };
89namespace VariableSizeMatrices {
92 auto PF = [](
int n) {
return getControlledMatrix(FixedMatrices::Z, n - 1); };
95namespace VariableSizeParameterisedMatrices {
97 auto Z = [](qreal p,
int n) {
102 auto PS = [](qreal p,
int n) {
103 qmatrix m = ParameterisedMatrices::PS(p);
104 return getControlledMatrix(m, n - 1);
119void TEST_ON_CACHED_QUREGS(quregCache quregs,
auto& reference,
auto& function) {
121 for (
auto& [label, qureg]: quregs) {
123 DYNAMIC_SECTION( label ) {
129 setToDebugState(reference);
131 function(qureg, reference);
132 REQUIRE_AGREE( qureg, reference );
137void TEST_ON_CACHED_QUREG_AND_MATRIX(quregCache quregs, matrixCache matrices,
auto apiFunc,
auto refState,
auto refMatr,
auto refFunc) {
139 for (
auto& [labelA, qureg]: quregs) {
140 for (
auto& [labelB, matrix]: matrices) {
143 if (matrix.isDistributed && ! qureg.isDistributed)
146 DYNAMIC_SECTION( labelA + LABEL_DELIMITER + labelB ) {
150 setToDebugState(refState);
156 apiFunc(qureg, matrix);
157 refFunc(refState, refMatr);
158 REQUIRE_AGREE( qureg, refState );
169#define PREPARE_TEST( numQubits, statevecQuregs, densmatrQuregs, statevecRef, densmatrRef ) \
170 int numQubits = getNumCachedQubits(); \
171 auto statevecQuregs = getCachedStatevecs(); \
172 auto densmatrQuregs = getCachedDensmatrs(); \
173 qvector statevecRef = getZeroVector(getPow2(numQubits)); \
174 qmatrix densmatrRef = getZeroMatrix(getPow2(numQubits));
197enum ArgsFlag { none, scalar, axisrots, diagmatr, diagpower, compmatr, paulistr, pauligad };
214enum NumQubitsFlag { zero, one, two, any, anystates };
216void assertNumQubitsFlagsAreValid(NumQubitsFlag ctrlsFlag, NumQubitsFlag targsFlag) {
222 ctrlsFlag == anystates );
231void assertNumQubitsFlagsValid(
232 NumQubitsFlag ctrlsFlag, NumQubitsFlag targsFlag,
233 vector<int> ctrls, vector<int> states, vector<int> targs
235 assertNumQubitsFlagsAreValid(ctrlsFlag, targsFlag);
242 if (targsFlag == one)
243 DEMAND( targs.size() == 1 );
245 if (targsFlag == two)
246 DEMAND( targs.size() == 2 );
248 if (ctrlsFlag == zero)
249 DEMAND( ctrls.size() == 0 );
251 if (ctrlsFlag == one)
252 DEMAND( ctrls.size() == 1 );
254 if (ctrlsFlag == anystates)
255 DEMAND( states.size() == ctrls.size() );
257 DEMAND( states.size() == 0 );
270template <NumQubitsFlag Ctrls, NumQubitsFlag Targs, ArgsFlag Args>
271int GENERATE_NUM_TARGS(
int numQuregQubits) {
273 assertNumQubitsFlagsAreValid(zero, Targs);
274 DEMAND( Targs != one || numQuregQubits >= 1 );
275 DEMAND( Targs != two || numQuregQubits >= 2 );
276 DEMAND( numQuregQubits > 0 );
279 if constexpr (Targs == one)
281 if constexpr (Targs == two)
284 if constexpr (Targs == any) {
287 int maxNumTargs = numQuregQubits;
293 if (Args == compmatr)
294 maxNumTargs = numQuregQubits - getLog2(
getQuESTEnv().numNodes);
297 if (Ctrls == one && maxNumTargs == numQuregQubits)
300 return GENERATE_COPY( range(1, maxNumTargs+1) );
304template <NumQubitsFlag Ctrls>
305int GENERATE_NUM_CTRLS(
int numFreeQubits) {
307 assertNumQubitsFlagsAreValid(Ctrls, one);
308 DEMAND( Ctrls != one || numFreeQubits >= 1 );
309 DEMAND( numFreeQubits >= 0 );
311 if constexpr (Ctrls == zero)
314 if constexpr (Ctrls == one)
317 if constexpr (Ctrls == any || Ctrls == anystates)
318 return GENERATE_COPY( range(0, numFreeQubits+1) );
339template <NumQubitsFlag Ctrls, NumQubitsFlag Targs>
340void invokeApiOperation(
341 auto operation,
Qureg qureg,
342 vector<int> ctrls, vector<int> states,
int numCtrls,
343 vector<int> targs,
int numTargs,
346 assertNumQubitsFlagsValid(Ctrls, Targs, ctrls, states, targs);
348 if constexpr (Ctrls == zero) {
349 if constexpr (Targs == zero) operation(qureg, args...);
350 if constexpr (Targs == one) operation(qureg, targs[0], args...);
351 if constexpr (Targs == two) operation(qureg, targs[0], targs[1], args...);
352 if constexpr (Targs == any) operation(qureg, targs.data(), numTargs, args...);
354 if constexpr (Ctrls == one) {
355 if constexpr (Targs == zero) operation(qureg, ctrls[0], args...);
356 if constexpr (Targs == one) operation(qureg, ctrls[0], targs[0], args...);
357 if constexpr (Targs == two) operation(qureg, ctrls[0], targs[0], targs[1], args...);
358 if constexpr (Targs == any) operation(qureg, ctrls[0], targs.data(), numTargs, args...);
360 if constexpr (Ctrls == any) {
361 if constexpr (Targs == zero) operation(qureg, ctrls.data(), numCtrls, args...);
362 if constexpr (Targs == one) operation(qureg, ctrls.data(), numCtrls, targs[0], args...);
363 if constexpr (Targs == two) operation(qureg, ctrls.data(), numCtrls, targs[0], targs[1], args...);
364 if constexpr (Targs == any) operation(qureg, ctrls.data(), numCtrls, targs.data(), numTargs, args...);
366 if constexpr (Ctrls == anystates) {
367 if constexpr (Targs == zero) operation(qureg, ctrls.data(), states.data(), numCtrls, args...);
368 if constexpr (Targs == one) operation(qureg, ctrls.data(), states.data(), numCtrls, targs[0], args...);
369 if constexpr (Targs == two) operation(qureg, ctrls.data(), states.data(), numCtrls, targs[0], targs[1], args...);
370 if constexpr (Targs == any) operation(qureg, ctrls.data(), states.data(), numCtrls, targs.data(), numTargs, args...);
376template <NumQubitsFlag Ctrls, NumQubitsFlag Targs>
377void invokeApiOperation(
auto operation,
Qureg qureg, vector<int> ctrls, vector<int> states, vector<int> targs,
auto&... args) {
378 invokeApiOperation<Ctrls,Targs>(operation, qureg, ctrls, states, ctrls.size(), targs, targs.size(), args...);
389template <NumQubitsFlag Targs, ArgsFlag Args>
390auto getRandomApiMatrix(
int numTargs) {
397 qmatrix qm = (Args == compmatr)?
399 getRandomDiagonalUnitary(numTargs);
401 if constexpr (Args == compmatr && Targs == one)
404 if constexpr (Args == compmatr && Targs == two)
407 if constexpr (Args == compmatr && Targs == any) {
413 qvector dv = getDiagonals(qm);
414 constexpr bool diag = (Args == diagmatr || Args == diagpower);
416 if constexpr (diag && Targs == one)
419 if constexpr (diag && Targs == two)
422 if constexpr (diag && Targs == any) {
440template <NumQubitsFlag Targs, ArgsFlag Args>
441auto getRandomRemainingArgs(vector<int> targs) {
443 if constexpr (Args == none)
446 if constexpr (Args == scalar) {
447 qreal angle = getRandomPhase();
448 return tuple{ angle };
451 if constexpr (Args == axisrots) {
452 qreal angle = getRandomPhase();
456 return tuple{ angle, x, y, z };
459 if constexpr (Args == compmatr || Args == diagmatr) {
460 auto matrix = getRandomApiMatrix<Targs,Args>(targs.size());
461 return tuple{ matrix };
464 if constexpr (Args == diagpower) {
465 DiagMatr matrix = getRandomApiMatrix<Targs,Args>(targs.size());
467 return tuple{ matrix, exponent };
470 if constexpr (Args == paulistr) {
471 PauliStr str = getRandomPauliStr(targs);
475 if constexpr (Args == pauligad) {
476 PauliStr str = getRandomPauliStr(targs);
477 qreal angle = getRandomPhase();
478 return tuple{ str, angle };
483template <NumQubitsFlag Targs, ArgsFlag Args>
484void freeRemainingArgs(
auto args) {
486 if constexpr (Targs == any && Args == compmatr)
489 if constexpr (Targs == any && Args == diagmatr)
492 if constexpr (Targs == any && Args == diagpower)
505template <NumQubitsFlag Targs, ArgsFlag Args>
506qmatrix getReferenceMatrix(
auto matrixRefGen, vector<int> targs,
auto additionalArgs) {
508 if constexpr (Args == none && Targs != any)
511 if constexpr (Args == none && Targs == any)
512 return matrixRefGen(targs.size());
514 if constexpr (Args == scalar && Targs != any) {
515 qreal angle = std::get<0>(additionalArgs);
516 return matrixRefGen(angle);
519 if constexpr (Args == scalar && Targs == any) {
520 qreal angle = std::get<0>(additionalArgs);
521 return matrixRefGen(angle, targs.size());
524 if constexpr (Args == axisrots) {
525 qreal angle = std::get<0>(additionalArgs);
526 qreal x = std::get<1>(additionalArgs);
527 qreal y = std::get<2>(additionalArgs);
528 qreal z = std::get<3>(additionalArgs);
529 return getExponentialOfNormalisedPauliVector(angle, x, y, z);
532 if constexpr (Args == compmatr || Args == diagmatr) {
533 auto apiMatrix = std::get<0>(additionalArgs);
534 return getMatrix(apiMatrix);
537 if constexpr (Args == diagpower) {
538 auto apiMatrix = std::get<0>(additionalArgs);
539 qmatrix diag = getMatrix(apiMatrix);
540 qcomp power = std::get<1>(additionalArgs);
541 return getPowerOfDiagonalMatrix(diag, power);
544 if constexpr (Args == paulistr) {
545 PauliStr str = std::get<0>(additionalArgs);
546 return getMatrix(str, targs);
549 if constexpr (Args == pauligad) {
550 PauliStr str = std::get<0>(additionalArgs);
551 qreal angle = std::get<1>(additionalArgs);
552 qmatrix matr = getMatrix(str, targs);
571std::string toString(vector<int> list) {
573 std::string out =
"{ ";
575 out += std::to_string(e) +
" ";
580extern int paulis_getPauliAt(
PauliStr str,
int ind);
582std::string toString(
PauliStr str, vector<int> targs) {
584 std::string labels =
"IXYZ";
587 std::string out =
"";
588 for (
int i=targs.size()-1; i>=0; i--)
589 out += labels[paulis_getPauliAt(str, targs[i])];
594template <NumQubitsFlag Ctrls, NumQubitsFlag Targs, ArgsFlag Args>
595void CAPTURE_RELEVANT( vector<int> ctrls, vector<int> states, vector<int> targs,
auto& args ) {
599 UNSCOPED_INFO(
"control := " << ctrls[0] );
600 if (Ctrls == any || Ctrls == anystates )
601 UNSCOPED_INFO(
"controls := " << toString(ctrls) );
604 if (Ctrls == anystates)
605 UNSCOPED_INFO(
"states := " << toString(states) );
609 UNSCOPED_INFO(
"target := " << targs[0] );
612 UNSCOPED_INFO(
"target A := " << targs[0] );
613 UNSCOPED_INFO(
"target B := " << targs[1] );
616 UNSCOPED_INFO(
"targets := " << toString(targs) );
619 if constexpr (Args == scalar)
620 UNSCOPED_INFO(
"angle := " << std::get<0>(args) );
623 if constexpr (Args == axisrots) {
624 UNSCOPED_INFO(
"angle := " << std::get<0>(args) );
625 UNSCOPED_INFO(
"x := " << std::get<1>(args) );
626 UNSCOPED_INFO(
"y := " << std::get<2>(args) );
627 UNSCOPED_INFO(
"z := " << std::get<3>(args) );
631 if constexpr (Args == compmatr || Args == diagmatr || Args == diagpower)
632 UNSCOPED_INFO(
"matrix := (omitted)" );
635 if constexpr (Args == diagpower) {
636 qcomp p = std::get<1>(args);
637 UNSCOPED_INFO(
"exponent := " << std::real(p) <<
" + (" << std::imag(p) <<
")i" );
641 if constexpr (Args == paulistr || Args == pauligad)
642 UNSCOPED_INFO(
"paulis := " << toString(std::get<0>(args), targs) );
645 if constexpr (Args == pauligad)
646 UNSCOPED_INFO(
"angle := " << std::get<1>(args) );
658template <NumQubitsFlag Ctrls, NumQubitsFlag Targs, ArgsFlag Args>
659void testOperation(
auto operation,
auto matrixRefGen,
bool multiplyOnly) {
661 assertNumQubitsFlagsAreValid(Ctrls, Targs);
663 PREPARE_TEST( numQubits, statevecQuregs, densmatrQuregs, statevecRef, densmatrRef );
665 SECTION( LABEL_CORRECTNESS ) {
668 int numTargs = GENERATE_NUM_TARGS<Ctrls,Targs,Args>(numQubits);
669 int numCtrls = GENERATE_NUM_CTRLS<Ctrls>(numQubits - numTargs);
672 auto ctrlsAndTargs = GENERATE_CTRLS_AND_TARGS( numQubits, numCtrls, numTargs );
673 vector<int> ctrls = std::get<0>(ctrlsAndTargs);
674 vector<int> targs = std::get<1>(ctrlsAndTargs);
677 vector<int> states = getRandomOutcomes(numCtrls * (Ctrls == anystates));
680 auto primaryArgs = tuple{ ctrls, states, targs };
681 auto furtherArgs = getRandomRemainingArgs<Targs,Args>(targs);
684 qmatrix matrixRef = getReferenceMatrix<Targs,Args>(matrixRefGen, targs, furtherArgs);
687 constexpr NumQubitsFlag RevTargs = (Args==paulistr||Args==pauligad)? zero : Targs;
698 auto testFunc = [&](
Qureg qureg,
auto& stateRef) ->
void {
701 auto apiFunc = [](
auto&&... args) {
return invokeApiOperation<Ctrls,RevTargs>(args...); };
702 auto allArgs = std::tuple_cat(tuple{operation, qureg}, primaryArgs, furtherArgs);
703 std::apply(apiFunc, allArgs);
707 multiplyReferenceOperator(stateRef, ctrls, states, targs, matrixRef):
708 applyReferenceOperator(stateRef, ctrls, states, targs, matrixRef);
712 CAPTURE_RELEVANT<Ctrls,Targs,Args>( ctrls, states, targs, furtherArgs );
715 SECTION( LABEL_STATEVEC ) { TEST_ON_CACHED_QUREGS(statevecQuregs, statevecRef, testFunc); }
716 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(densmatrQuregs, densmatrRef, testFunc); }
719 freeRemainingArgs<Targs,Args>(furtherArgs);
727template <NumQubitsFlag Ctrls, NumQubitsFlag Targs, ArgsFlag Args>
728void testOperation(
auto operation,
auto matrixRefGen) {
731 testOperation<Ctrls,Targs,Args>(operation, matrixRefGen,
false);
745#define TEST_ANY_CTRL_OPERATION( namesuffix, numtargs, argtype, matrixgen ) \
746 TEST_CASE( "apply" #namesuffix, TEST_CATEGORY ) { testOperation<zero, numtargs,argtype>( apply ## namesuffix, matrixgen); } \
747 TEST_CASE( "applyControlled" #namesuffix, TEST_CATEGORY ) { testOperation<one, numtargs,argtype>( applyControlled ## namesuffix, matrixgen); } \
748 TEST_CASE( "applyMultiControlled" #namesuffix, TEST_CATEGORY ) { testOperation<any, numtargs,argtype>( applyMultiControlled ## namesuffix, matrixgen); } \
749 TEST_CASE( "applyMultiStateControlled" #namesuffix, TEST_CATEGORY ) { testOperation<anystates,numtargs,argtype>( applyMultiStateControlled ## namesuffix, matrixgen); }
803TEST_CASE(
"multiplyPhaseGadget", TEST_CATEGORY ) { testOperation<zero,any,scalar>(
multiplyPhaseGadget, VariableSizeParameterisedMatrices::Z,
true); }
805TEST_CASE(
"applyPhaseFlip", TEST_CATEGORY ) { testOperation<zero,one,none>(
applyPhaseFlip, VariableSizeMatrices::PF(1)); }
809TEST_CASE(
"applyPhaseShift", TEST_CATEGORY ) { testOperation<zero,one,scalar>(
applyPhaseShift, ParameterisedMatrices::PS); }
814TEST_CASE(
"applyQuantumFourierTransform", TEST_CATEGORY ) {
816 PREPARE_TEST( numQubits, statevecQuregs, densmatrQuregs, statevecRef, densmatrRef );
818 SECTION( LABEL_CORRECTNESS ) {
820 int numTargs = GENERATE_COPY( range(1,numQubits+1) );
821 auto targs = GENERATE_TARGS( numQubits, numTargs );
825 SECTION( LABEL_STATEVEC ) {
827 auto testFunc = [&](
Qureg qureg, qvector& ref) {
829 ref = getDisceteFourierTransform(ref, targs);
832 TEST_ON_CACHED_QUREGS(statevecQuregs, statevecRef, testFunc);
835 SECTION( LABEL_DENSMATR ) {
838 auto states = getRandomOrthonormalStateVectors(numQubits,
getRandomInt(1,10));
841 auto testFunc = [&](
Qureg qureg, qmatrix& ref) {
844 setQuregToReference(qureg, getMixture(states, probs));
848 for (
size_t i=0; i<states.size(); i++) {
849 qvector vec = getDisceteFourierTransform(states[i], targs);
850 ref += probs[i] * getOuterProduct(vec, vec);
854 TEST_ON_CACHED_QUREGS(densmatrQuregs, densmatrRef, testFunc);
862TEST_CASE(
"applyFullQuantumFourierTransform", TEST_CATEGORY ) {
864 PREPARE_TEST( numQubits, statevecQuregs, densmatrQuregs, statevecRef, densmatrRef );
866 SECTION( LABEL_CORRECTNESS ) {
868 GENERATE( range(0,10) );
870 SECTION( LABEL_STATEVEC ) {
872 auto testFunc = [&](
Qureg qureg, qvector& ref) {
874 ref = getDisceteFourierTransform(ref);
877 TEST_ON_CACHED_QUREGS(statevecQuregs, statevecRef, testFunc);
880 SECTION( LABEL_DENSMATR ) {
883 auto states = getRandomOrthonormalStateVectors(numQubits,
getRandomInt(1,10));
886 auto testFunc = [&](
Qureg qureg, qmatrix& ref) {
889 setQuregToReference(qureg, getMixture(states, probs));
893 for (
size_t i=0; i<states.size(); i++) {
894 qvector vec = getDisceteFourierTransform(states[i]);
895 ref += probs[i] * getOuterProduct(vec, vec);
899 TEST_ON_CACHED_QUREGS(densmatrQuregs, densmatrRef, testFunc);
909 PREPARE_TEST( numQubits, statevecQuregs, densmatrQuregs, statevecRef, densmatrRef );
911 SECTION( LABEL_CORRECTNESS ) {
913 GENERATE( range(0,10) );
914 int target = GENERATE_COPY( range(0,numQubits) );
915 int outcome = GENERATE( 0, 1 );
917 qmatrix projector = getProjector(outcome);
919 auto testFunc = [&](
Qureg qureg,
auto& ref) {
921 applyReferenceOperator(ref, {target}, projector);
924 CAPTURE( target, outcome );
925 SECTION( LABEL_STATEVEC ) { TEST_ON_CACHED_QUREGS(statevecQuregs, statevecRef, testFunc); }
926 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(densmatrQuregs, densmatrRef, testFunc); }
935 PREPARE_TEST( numQubits, statevecQuregs, densmatrQuregs, statevecRef, densmatrRef );
937 SECTION( LABEL_CORRECTNESS ) {
939 int numTargs = GENERATE_COPY( range(1,numQubits+1) );
940 auto targets = GENERATE_TARGS( numQubits, numTargs );
941 auto outcomes = getRandomOutcomes(numTargs);
943 qmatrix projector = getProjector(targets, outcomes, numQubits);
945 auto testFunc = [&](
Qureg qureg,
auto& ref) {
947 applyReferenceOperator(ref, projector);
950 CAPTURE( targets, outcomes );
951 SECTION( LABEL_STATEVEC ) { TEST_ON_CACHED_QUREGS(statevecQuregs, statevecRef, testFunc); }
952 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(densmatrQuregs, densmatrRef, testFunc); }
959TEST_CASE(
"applyForcedQubitMeasurement", TEST_CATEGORY ) {
961 PREPARE_TEST( numQubits, statevecQuregs, densmatrQuregs, statevecRef, densmatrRef );
963 SECTION( LABEL_CORRECTNESS ) {
965 GENERATE( range(0,10) );
966 int target = GENERATE_COPY( range(0,numQubits) );
967 int outcome = GENERATE( 0, 1 );
969 qmatrix projector = getProjector(outcome);
971 auto testFunc = [&](
Qureg qureg,
auto& ref) {
975 setToRandomState(ref);
976 setQuregToReference(qureg, ref);
980 qreal refProb = getReferenceProbability(ref, {target}, {outcome});
981 REQUIRE_AGREE( apiProb, refProb );
984 applyReferenceOperator(ref, {target}, projector);
985 ref /= (qureg.isDensityMatrix)?
986 refProb : std::sqrt(refProb);
989 CAPTURE( target, outcome );
990 SECTION( LABEL_STATEVEC ) { TEST_ON_CACHED_QUREGS(statevecQuregs, statevecRef, testFunc); }
991 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(densmatrQuregs, densmatrRef, testFunc); }
998TEST_CASE(
"applyForcedMultiQubitMeasurement", TEST_CATEGORY ) {
1000 PREPARE_TEST( numQubits, statevecQuregs, densmatrQuregs, statevecRef, densmatrRef );
1002 SECTION( LABEL_CORRECTNESS ) {
1004 int numTargs = GENERATE_COPY( range(1,numQubits+1) );
1005 auto targets = GENERATE_TARGS( numQubits, numTargs );
1006 auto outcomes = getRandomOutcomes(numTargs);
1008 qmatrix projector = getProjector(targets, outcomes, numQubits);
1010 auto testFunc = [&](
Qureg qureg,
auto& ref) {
1014 setToRandomState(ref);
1015 setQuregToReference(qureg, ref);
1019 qreal refProb = getReferenceProbability(ref, targets, outcomes);
1020 REQUIRE_AGREE( apiProb, refProb );
1023 applyReferenceOperator(ref, projector);
1024 ref /= (qureg.isDensityMatrix)?
1025 refProb : std::sqrt(refProb);
1028 CAPTURE( targets, outcomes );
1029 SECTION( LABEL_STATEVEC ) { TEST_ON_CACHED_QUREGS(statevecQuregs, statevecRef, testFunc); }
1030 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(densmatrQuregs, densmatrRef, testFunc); }
1039 PREPARE_TEST( numQubits, statevecQuregs, densmatrQuregs, statevecRef, densmatrRef );
1041 SECTION( LABEL_CORRECTNESS ) {
1043 int numTargs = GENERATE_COPY( range(1,numQubits+1) );
1044 auto targets = GENERATE_TARGS( numQubits, numTargs );
1046 auto testFunc = [&](
Qureg qureg,
auto& ref) {
1050 setToRandomState(ref);
1051 setQuregToReference(qureg, ref);
1057 auto apiOutBits = getBits(apiOut, numTargs);
1058 qmatrix projector = getProjector(targets, apiOutBits, numQubits);
1059 applyReferenceOperator(ref, projector);
1060 qreal refProb = getReferenceProbability(ref, targets, apiOutBits);
1061 ref /= (qureg.isDensityMatrix)?
1062 refProb : std::sqrt(refProb);
1066 SECTION( LABEL_STATEVEC ) { TEST_ON_CACHED_QUREGS(statevecQuregs, statevecRef, testFunc); }
1067 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(densmatrQuregs, densmatrRef, testFunc); }
1074TEST_CASE(
"applyMultiQubitMeasurementAndGetProb", TEST_CATEGORY ) {
1076 PREPARE_TEST( numQubits, statevecQuregs, densmatrQuregs, statevecRef, densmatrRef );
1078 SECTION( LABEL_CORRECTNESS ) {
1080 int numTargs = GENERATE_COPY( range(1,numQubits+1) );
1081 auto targets = GENERATE_TARGS( numQubits, numTargs );
1083 auto testFunc = [&](
Qureg qureg,
auto& ref) {
1087 setToRandomState(ref);
1088 setQuregToReference(qureg, ref);
1093 auto apiOutBits = getBits(apiOut, numTargs);
1094 qreal refProb = getReferenceProbability(ref, targets, apiOutBits);
1095 REQUIRE_AGREE( apiProb, refProb );
1098 qmatrix projector = getProjector(targets, apiOutBits, numQubits);
1099 applyReferenceOperator(ref, projector);
1100 ref /= (qureg.isDensityMatrix)?
1101 refProb : std::sqrt(refProb);
1105 SECTION( LABEL_STATEVEC ) { TEST_ON_CACHED_QUREGS(statevecQuregs, statevecRef, testFunc); }
1106 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(densmatrQuregs, densmatrRef, testFunc); }
1115 PREPARE_TEST( numQubits, statevecQuregs, densmatrQuregs, statevecRef, densmatrRef );
1117 SECTION( LABEL_CORRECTNESS ) {
1119 GENERATE( range(0,10) );
1120 int target = GENERATE_COPY( range(0,numQubits) );
1122 auto testFunc = [&](
Qureg qureg,
auto& ref) {
1126 setToRandomState(ref);
1127 setQuregToReference(qureg, ref);
1133 qmatrix projector = getProjector(apiOut);
1134 applyReferenceOperator(ref, {target}, projector);
1135 qreal refProb = getReferenceProbability(ref, {target}, {apiOut});
1136 ref /= (qureg.isDensityMatrix)?
1137 refProb : std::sqrt(refProb);
1141 SECTION( LABEL_STATEVEC ) { TEST_ON_CACHED_QUREGS(statevecQuregs, statevecRef, testFunc); }
1142 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(densmatrQuregs, densmatrRef, testFunc); }
1149TEST_CASE(
"applyQubitMeasurementAndGetProb", TEST_CATEGORY ) {
1151 PREPARE_TEST( numQubits, statevecQuregs, densmatrQuregs, statevecRef, densmatrRef );
1153 SECTION( LABEL_CORRECTNESS ) {
1155 GENERATE( range(0,10) );
1156 int target = GENERATE_COPY( range(0,numQubits) );
1158 auto testFunc = [&](
Qureg qureg,
auto& ref) {
1162 setToRandomState(ref);
1163 setQuregToReference(qureg, ref);
1168 qreal refProb = getReferenceProbability(ref, {target}, {apiOut});
1169 REQUIRE_AGREE( apiProb, refProb );
1172 qmatrix projector = getProjector(apiOut);
1173 applyReferenceOperator(ref, {target}, projector);
1174 ref /= (qureg.isDensityMatrix)?
1175 refProb : std::sqrt(refProb);
1179 SECTION( LABEL_STATEVEC ) { TEST_ON_CACHED_QUREGS(statevecQuregs, statevecRef, testFunc); }
1180 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(densmatrQuregs, densmatrRef, testFunc); }
1187TEST_CASE(
"multiplyFullStateDiagMatr", TEST_CATEGORY LABEL_MIXED_DEPLOY_TAG ) {
1189 PREPARE_TEST( numQubits, cachedSV, cachedDM, refSV, refDM );
1191 auto cachedMatrs = getCachedFullStateDiagMatrs();
1193 SECTION( LABEL_CORRECTNESS ) {
1195 qmatrix refMatr = getRandomDiagonalMatrix(getPow2(numQubits));
1198 GENERATE( range(0, TEST_NUM_MIXED_DEPLOYMENT_REPETITIONS) );
1200 SECTION( LABEL_STATEVEC ) {
1202 auto refFunc = [&] (qvector& state, qmatrix matr) { multiplyReferenceOperator(state, matr); };
1204 TEST_ON_CACHED_QUREG_AND_MATRIX( cachedSV, cachedMatrs, apiFunc, refSV, refMatr, refFunc);
1207 SECTION( LABEL_DENSMATR ) {
1209 auto refFunc = [&] (qmatrix& state, qmatrix matr) { multiplyReferenceOperator(state, matr); };
1211 TEST_ON_CACHED_QUREG_AND_MATRIX( cachedDM, cachedMatrs, apiFunc, refDM, refMatr, refFunc);
1219TEST_CASE(
"multiplyFullStateDiagMatrPower", TEST_CATEGORY LABEL_MIXED_DEPLOY_TAG ) {
1221 PREPARE_TEST( numQubits, cachedSV, cachedDM, refSV, refDM );
1223 auto cachedMatrs = getCachedFullStateDiagMatrs();
1225 SECTION( LABEL_CORRECTNESS ) {
1227 qmatrix refMatr = getRandomDiagonalMatrix(getPow2(numQubits));
1234 CAPTURE( exponent );
1236 GENERATE( range(0, TEST_NUM_MIXED_DEPLOYMENT_REPETITIONS) );
1238 SECTION( LABEL_STATEVEC ) {
1240 auto refFunc = [&] (qvector& state, qmatrix matr) {
1241 matr = getPowerOfDiagonalMatrix(matr, exponent);
1242 multiplyReferenceOperator(state, matr);
1245 TEST_ON_CACHED_QUREG_AND_MATRIX( cachedSV, cachedMatrs, apiFunc, refSV, refMatr, refFunc);
1248 SECTION( LABEL_DENSMATR ) {
1250 auto refFunc = [&] (qmatrix& state, qmatrix matr) {
1251 matr = getPowerOfDiagonalMatrix(matr, exponent);
1252 multiplyReferenceOperator(state, matr);
1255 TEST_ON_CACHED_QUREG_AND_MATRIX( cachedDM, cachedMatrs, apiFunc, refDM, refMatr, refFunc);
1263TEST_CASE(
"applyFullStateDiagMatr", TEST_CATEGORY LABEL_MIXED_DEPLOY_TAG ) {
1265 PREPARE_TEST( numQubits, cachedSV, cachedDM, refSV, refDM );
1267 auto cachedMatrs = getCachedFullStateDiagMatrs();
1269 SECTION( LABEL_CORRECTNESS ) {
1271 qmatrix refMatr = getRandomDiagonalUnitary(numQubits);
1274 GENERATE( range(0, TEST_NUM_MIXED_DEPLOYMENT_REPETITIONS) );
1276 SECTION( LABEL_STATEVEC ) {
1278 auto refFunc = [&] (qvector& state, qmatrix matr) { applyReferenceOperator(state, matr); };
1280 TEST_ON_CACHED_QUREG_AND_MATRIX( cachedSV, cachedMatrs, apiFunc, refSV, refMatr, refFunc);
1283 SECTION( LABEL_DENSMATR ) {
1285 auto refFunc = [&] (qmatrix& state, qmatrix matr) { applyReferenceOperator(state, matr); };
1287 TEST_ON_CACHED_QUREG_AND_MATRIX( cachedDM, cachedMatrs, apiFunc, refDM, refMatr, refFunc);
1295TEST_CASE(
"applyFullStateDiagMatrPower", TEST_CATEGORY LABEL_MIXED_DEPLOY_TAG ) {
1297 PREPARE_TEST( numQubits, cachedSV, cachedDM, refSV, refDM );
1299 auto cachedMatrs = getCachedFullStateDiagMatrs();
1301 SECTION( LABEL_CORRECTNESS ) {
1303 qmatrix refMatr = getRandomDiagonalUnitary(numQubits);
1307 bool testRealExp = GENERATE(
true,
false );
1308 qcomp exponent = (testRealExp)?
1316 CAPTURE( exponent );
1318 GENERATE( range(0, TEST_NUM_MIXED_DEPLOYMENT_REPETITIONS) );
1323 SECTION( LABEL_STATEVEC ) {
1325 auto refFunc = [&] (qvector& state, qmatrix matr) {
1326 matr = getPowerOfDiagonalMatrix(matr, exponent);
1327 applyReferenceOperator(state, matr);
1330 TEST_ON_CACHED_QUREG_AND_MATRIX( cachedSV, cachedMatrs, apiFunc, refSV, refMatr, refFunc);
1333 SECTION( LABEL_DENSMATR ) {
1335 auto refFunc = [&] (qmatrix& state, qmatrix matr) {
1336 matr = getPowerOfDiagonalMatrix(matr, exponent);
1337 applyReferenceOperator(state, matr);
1340 TEST_ON_CACHED_QUREG_AND_MATRIX( cachedDM, cachedMatrs, apiFunc, refDM, refMatr, refFunc);
1350TEST_CASE(
"multiplyPauliStrSum", TEST_CATEGORY LABEL_MIXED_DEPLOY_TAG ) {
1352 PREPARE_TEST( numQubits, statevecQuregs, densmatrQuregs, statevecRef, densmatrRef );
1354 SECTION( LABEL_CORRECTNESS ) {
1356 int numQubits = getNumCachedQubits();
1357 int numTerms = GENERATE_COPY( 1, 2, 10 );
1359 PauliStrSum sum = createRandomPauliStrSum(numQubits, numTerms);
1361 auto testFunc = [&](
Qureg qureg,
auto& ref) {
1368 ref = getMatrix(sum, numQubits) * ref;
1371 CAPTURE( numTerms );
1372 SECTION( LABEL_STATEVEC ) { TEST_ON_CACHED_QUREGS(statevecQuregs, statevecRef, testFunc); }
1373 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(densmatrQuregs, densmatrRef, testFunc); }
void setValidationEpsilonToDefault()
void setValidationEpsilon(qreal eps)
void initDebugState(Qureg qureg)
CompMatr createCompMatr(int numQubits)
DiagMatr createDiagMatr(int numQubits)
void destroyDiagMatr(DiagMatr matrix)
void destroyCompMatr(CompMatr matrix)
static CompMatr2 getCompMatr2(qcomp **in)
static CompMatr1 getCompMatr1(qcomp **in)
static DiagMatr2 getDiagMatr2(qcomp *in)
static DiagMatr1 getDiagMatr1(qcomp *in)
void setDiagMatr(DiagMatr out, qcomp *in)
void setCompMatr(CompMatr matr, qcomp **vals)
void setFullStateDiagMatr(FullStateDiagMatr out, qindex startInd, qcomp *in, qindex numElems)
void multiplyCompMatr1(Qureg qureg, int target, CompMatr1 matrix)
void multiplyCompMatr2(Qureg qureg, int target1, int target2, CompMatr2 matr)
void multiplyCompMatr(Qureg qureg, int *targets, int numTargets, CompMatr matr)
void multiplyDiagMatr1(Qureg qureg, int target, DiagMatr1 matr)
void multiplyDiagMatr2(Qureg qureg, int target1, int target2, DiagMatr2 matr)
void multiplyDiagMatr(Qureg qureg, int *targets, int numTargets, DiagMatr matrix)
void multiplyDiagMatrPower(Qureg qureg, int *targets, int numTargets, DiagMatr matrix, qcomp exponent)
void applyFullStateDiagMatr(Qureg qureg, FullStateDiagMatr matrix)
void multiplyFullStateDiagMatrPower(Qureg qureg, FullStateDiagMatr matrix, qcomp exponent)
void applyFullStateDiagMatrPower(Qureg qureg, FullStateDiagMatr matrix, qcomp exponent)
void multiplyFullStateDiagMatr(Qureg qureg, FullStateDiagMatr matrix)
qreal applyForcedQubitMeasurement(Qureg qureg, int target, int outcome)
qindex applyMultiQubitMeasurement(Qureg qureg, int *qubits, int numQubits)
int applyQubitMeasurement(Qureg qureg, int target)
qreal applyForcedMultiQubitMeasurement(Qureg qureg, int *qubits, int *outcomes, int numQubits)
qindex applyMultiQubitMeasurementAndGetProb(Qureg qureg, int *qubits, int numQubits, qreal *probability)
int applyQubitMeasurementAndGetProb(Qureg qureg, int target, qreal *probability)
void multiplyMultiQubitNot(Qureg qureg, int *targets, int numTargets)
void multiplyPauliGadget(Qureg qureg, PauliStr str, qreal angle)
void multiplyPauliStr(Qureg qureg, PauliStr str)
void multiplyPauliStrSum(Qureg qureg, PauliStrSum sum, Qureg workspace)
void applyTrotterizedPauliStrSumGadget(Qureg qureg, PauliStrSum sum, qreal angle, int order, int reps)
void applyMultiQubitPhaseShift(Qureg qureg, int *targets, int numTargets, qreal angle)
void applyTwoQubitPhaseShift(Qureg qureg, int target1, int target2, qreal angle)
void applyTwoQubitPhaseFlip(Qureg qureg, int target1, int target2)
void applyPhaseShift(Qureg qureg, int target, qreal angle)
void applyPhaseFlip(Qureg qureg, int target)
void multiplyPhaseGadget(Qureg qureg, int *targets, int numTargets, qreal angle)
void applyMultiQubitPhaseFlip(Qureg qureg, int *targets, int numTargets)
void applyMultiQubitProjector(Qureg qureg, int *qubits, int *outcomes, int numQubits)
void applyQubitProjector(Qureg qureg, int target, int outcome)
void applyFullQuantumFourierTransform(Qureg qureg)
void applyQuantumFourierTransform(Qureg qureg, int *targets, int numTargets)
Qureg createCloneQureg(Qureg qureg)
void destroyQureg(Qureg qureg)
qmatrix getKroneckerProduct(qmatrix a, qmatrix b)
qmatrix getExponentialOfPauliMatrix(qreal arg, qmatrix m)
qmatrix getZeroMatrix(size_t dim)
qmatrix getRandomUnitary(int numQb)
qreal getRandomReal(qreal min, qreal maxIncl)
vector< qreal > getRandomProbabilities(int numProbs)
int getRandomInt(int min, int maxExcl)
TEST_CASE("calcExpecPauliStr", TEST_CATEGORY)
TEST_ANY_CTRL_OPERATION(PauliStr, any, paulistr, nullptr)