The Quantum Exact Simulation Toolkit v4.3.0
Loading...
Searching...
No Matches
 TEST_ALL_CTRL_OPERATIONS (PauliStr, any, paulistr, nullptr)
 
 TEST_ALL_CTRL_OPERATIONS (PauliGadget, any, pauligad, nullptr)
 
 TEST_ALL_CTRL_OPERATIONS (CompMatr1, one, compmatr, nullptr)
 
 TEST_ALL_CTRL_OPERATIONS (CompMatr2, two, compmatr, nullptr)
 
 TEST_ALL_CTRL_OPERATIONS (CompMatr, any, compmatr, nullptr)
 
 TEST_ALL_CTRL_OPERATIONS (DiagMatr1, one, diagmatr, nullptr)
 
 TEST_ALL_CTRL_OPERATIONS (DiagMatr2, two, diagmatr, nullptr)
 
 TEST_ALL_CTRL_OPERATIONS (DiagMatr, any, diagmatr, nullptr)
 
 TEST_ALL_CTRL_OPERATIONS (DiagMatrPower, any, diagpower, nullptr)
 
 TEST_ALL_CTRL_OPERATIONS (Hadamard, one, none, FixedMatrices::H)
 
 TEST_ALL_CTRL_OPERATIONS (PauliX, one, none, FixedMatrices::X)
 
 TEST_ALL_CTRL_OPERATIONS (PauliY, one, none, FixedMatrices::Y)
 
 TEST_ALL_CTRL_OPERATIONS (PauliZ, one, none, FixedMatrices::Z)
 
 TEST_ALL_CTRL_OPERATIONS (T, one, none, FixedMatrices::T)
 
 TEST_ALL_CTRL_OPERATIONS (S, one, none, FixedMatrices::S)
 
 TEST_ALL_CTRL_OPERATIONS (Swap, two, none, FixedMatrices::SWAP)
 
 TEST_ALL_CTRL_OPERATIONS (SqrtSwap, two, none, FixedMatrices::sqrtSWAP)
 
 TEST_ALL_CTRL_OPERATIONS (RotateX, one, scalar, ParameterisedMatrices::Rx)
 
 TEST_ALL_CTRL_OPERATIONS (RotateY, one, scalar, ParameterisedMatrices::Ry)
 
 TEST_ALL_CTRL_OPERATIONS (RotateZ, one, scalar, ParameterisedMatrices::Rz)
 
 TEST_ALL_CTRL_OPERATIONS (RotateAroundAxis, one, axisrots, nullptr)
 
 TEST_ALL_CTRL_OPERATIONS (MultiQubitNot, any, none, VariableSizeMatrices::X)
 
 TEST_ALL_CTRL_OPERATIONS (PhaseGadget, any, scalar, VariableSizeParameterisedMatrices::Z)
 
 TEST_CASE ("applyPhaseFlip", TEST_CATEGORY_OPS)
 
 TEST_CASE ("applyTwoQubitPhaseFlip", TEST_CATEGORY_OPS)
 
 TEST_CASE ("applyPhaseShift", TEST_CATEGORY_OPS)
 
 TEST_CASE ("applyTwoQubitPhaseShift", TEST_CATEGORY_OPS)
 
 TEST_CASE ("applyMultiQubitPhaseFlip", TEST_CATEGORY_OPS)
 
 TEST_CASE ("applyMultiQubitPhaseShift", TEST_CATEGORY_OPS)
 
 TEST_CASE ("applyQuantumFourierTransform", TEST_CATEGORY_OPS)
 
 TEST_CASE ("applyFullQuantumFourierTransform", TEST_CATEGORY_OPS)
 
 TEST_CASE ("applyQubitProjector", TEST_CATEGORY_OPS)
 
 TEST_CASE ("applyMultiQubitProjector", TEST_CATEGORY_OPS)
 
 TEST_CASE ("applyForcedQubitMeasurement", TEST_CATEGORY_OPS)
 
 TEST_CASE ("applyForcedMultiQubitMeasurement", TEST_CATEGORY_OPS)
 
 TEST_CASE ("applyMultiQubitMeasurement", TEST_CATEGORY_OPS)
 
 TEST_CASE ("applyMultiQubitMeasurementAndGetProb", TEST_CATEGORY_OPS)
 
 TEST_CASE ("applyQubitMeasurement", TEST_CATEGORY_OPS)
 
 TEST_CASE ("applyQubitMeasurementAndGetProb", TEST_CATEGORY_OPS)
 
 TEST_CASE ("applyFullStateDiagMatr", TEST_CATEGORY_OPS LABEL_MIXED_DEPLOY_TAG)
 
 TEST_CASE ("applyFullStateDiagMatrPower", TEST_CATEGORY_OPS LABEL_MIXED_DEPLOY_TAG)
 
 TEST_CASE ("applyNonUnitaryPauliGadget", TEST_CATEGORY_OPS)
 

Detailed Description

Function Documentation

◆ TEST_ALL_CTRL_OPERATIONS()

TEST_ALL_CTRL_OPERATIONS ( PauliStr ,
any ,
paulistr ,
nullptr  )

OPERATOR TESTS

◆ TEST_CASE() [1/19]

TEST_CASE ( "applyForcedMultiQubitMeasurement" ,
TEST_CATEGORY_OPS  )

Definition at line 1794 of file operations.cpp.

1794 {
1795
1796 PREPARE_TEST( numQubits, statevecQuregs, densmatrQuregs, statevecRef, densmatrRef );
1797
1798 SECTION( LABEL_CORRECTNESS ) {
1799
1800 int numTargs = GENERATE_COPY( range(1,numQubits+1) );
1801 auto targets = GENERATE_TARGS( numQubits, numTargs );
1802 auto outcomes = getRandomOutcomes(numTargs);
1803
1804 qmatrix projector = getProjector(targets, outcomes, numQubits);
1805
1806 // this test may randomly request a measurement outcome which
1807 // is illegally unlikely, triggering validation; we merely
1808 // disable such validation and hope divergences don't break the test!
1810
1811 auto testFunc = [&](Qureg qureg, auto& ref) {
1812
1813 // overwrite caller's setting of initDebugState, since
1814 // that precludes outcomes=|0><0| due to zero-probability
1815 setToRandomState(ref);
1816 setQuregToReference(qureg, ref);
1817
1818 // compare the probabilities...
1819 qreal apiProb = applyForcedMultiQubitMeasurement(qureg, targets.data(), outcomes.data(), numTargs);
1820 qreal refProb = getReferenceProbability(ref, targets, outcomes);
1821 REQUIRE_AGREE( apiProb, refProb );
1822
1823 // and the post-measurement states (caller calls subsequent REQUIRE_AGREE)
1824 applyReferenceOperator(ref, projector);
1825 ref /= (qureg.isDensityMatrix)?
1826 refProb : std::sqrt(refProb);
1827 };
1828
1829 CAPTURE( targets, outcomes );
1830 SECTION( LABEL_STATEVEC ) { TEST_ON_CACHED_QUREGS(statevecQuregs, statevecRef, testFunc); }
1831 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(densmatrQuregs, densmatrRef, testFunc); }
1832
1834 }
1835
1836 SECTION( LABEL_VALIDATION ) {
1837
1838 Qureg qureg = getArbitraryCachedStatevec();
1839 int targets[] = {0, 1, 2};
1840 int outcomes[] = {0, 1, 0};
1841 int numTargets = 3;
1842
1843 // below validation tests assume the above parameters are valid (not impossibly unlikely)
1844 initDebugState(qureg);
1845 REQUIRE( calcProbOfMultiQubitOutcome(qureg, targets, outcomes, numTargets) > getQuESTValidationEpsilon() );
1846
1847 SECTION( "qureg uninitialised" ) {
1848
1849 Qureg badQureg = qureg;
1850 badQureg.numQubits = -1;
1851 REQUIRE_THROWS_WITH(
1852 applyForcedMultiQubitMeasurement(badQureg, targets, outcomes, numTargets),
1853 ContainsSubstring("invalid Qureg")
1854 );
1855 }
1856
1857 SECTION( "invalid target qubits" ) {
1858
1859 int badTargets[] = {0, 1, GENERATE_COPY( -1, qureg.numQubits )};
1860 REQUIRE_THROWS_WITH(
1861 applyForcedMultiQubitMeasurement(qureg, badTargets, outcomes, numTargets),
1862 ContainsSubstring("target")
1863 );
1864 }
1865
1866 SECTION( "duplicate target qubits" ) {
1867
1868 int dupTargets[] = {0, 1, 1};
1869 REQUIRE_THROWS_WITH(
1870 applyForcedMultiQubitMeasurement(qureg, dupTargets, outcomes, numTargets),
1871 ContainsSubstring("duplicate")
1872 );
1873 }
1874
1875 SECTION( "invalid number of targets" ) {
1876
1877 int badNumTargs = GENERATE( -1, 0 );
1878 REQUIRE_THROWS_WITH(
1879 applyForcedMultiQubitMeasurement(qureg, targets, outcomes, badNumTargs),
1880 ContainsSubstring("targets")
1881 );
1882
1883 badNumTargs = qureg.numQubits + 1;
1884 REQUIRE_THROWS_WITH(
1885 applyForcedMultiQubitMeasurement(qureg, targets, outcomes, badNumTargs),
1886 ContainsSubstring("exceeds the number of qubits in the Qureg")
1887 );
1888 }
1889
1890 SECTION( "invalid outcomes" ) {
1891
1892 int badOutcomes[] = {0, 1, GENERATE( -1, 2 )};
1893 REQUIRE_THROWS_WITH(
1894 applyForcedMultiQubitMeasurement(qureg, targets, badOutcomes, numTargets),
1895 ContainsSubstring("outcome")
1896 );
1897 }
1898
1899 SECTION( "improbable outcomes" ) {
1900
1901 // impossible outcome
1902 initZeroState(qureg);
1903 int badOutcomes[] = {0, 0, 1};
1904 REQUIRE_THROWS_WITH(
1905 applyForcedMultiQubitMeasurement(qureg, targets, badOutcomes, numTargets),
1906 ContainsSubstring("impossibly unlikely")
1907 );
1908
1909 // outcome of non-zero probability smaller than epsilon
1910 qreal badTheta = 1E-8;
1911 applyRotateX(qureg, targets[2], badTheta);
1912 REQUIRE_THROWS_WITH(
1913 applyForcedMultiQubitMeasurement(qureg, targets, badOutcomes, numTargets),
1914 ContainsSubstring("impossibly unlikely")
1915 );
1916
1917 // confirm that >epsilon probability is fine
1918 initZeroState(qureg);
1919 qreal goodTheta = 0.1;
1920 applyRotateX(qureg, targets[2], goodTheta);
1921 int goodOutcomes[] = {0, 0, 1};
1922 REQUIRE(
1923 calcProbOfMultiQubitOutcome(qureg, targets, goodOutcomes, numTargets) > getQuESTValidationEpsilon()
1924 );
1925 REQUIRE_NOTHROW(
1926 applyForcedMultiQubitMeasurement(qureg, targets, goodOutcomes, numTargets)
1927 );
1928
1929 // restore qureg state
1930 initDebugState(qureg);
1931 }
1932
1933 SECTION( "targets mismatch outcomes (C++ only)") {
1934
1935 REQUIRE_THROWS_WITH(
1936 applyForcedMultiQubitMeasurement(qureg, {0,1}, {0,1,1}),
1937 ContainsSubstring("inconsistent")
1938 );
1939 }
1940 }
1941}
qreal calcProbOfMultiQubitOutcome(Qureg qureg, int *qubits, int *outcomes, int numQubits)
void setQuESTValidationEpsilonToDefault()
Definition debug.cpp:108
qreal getQuESTValidationEpsilon()
Definition debug.cpp:115
void setQuESTValidationEpsilon(qreal eps)
Definition debug.cpp:100
void initZeroState(Qureg qureg)
void initDebugState(Qureg qureg)
qreal applyForcedMultiQubitMeasurement(Qureg qureg, int *qubits, int *outcomes, int numQubits)
void applyRotateX(Qureg qureg, int target, qreal angle)
Definition qureg.h:49

◆ TEST_CASE() [2/19]

TEST_CASE ( "applyForcedQubitMeasurement" ,
TEST_CATEGORY_OPS  )

Definition at line 1685 of file operations.cpp.

1685 {
1686
1687 PREPARE_TEST( numQubits, statevecQuregs, densmatrQuregs, statevecRef, densmatrRef );
1688
1689 SECTION( LABEL_CORRECTNESS ) {
1690
1691 GENERATE( range(0,10) );
1692 int target = GENERATE_COPY( range(0,numQubits) );
1693 int outcome = GENERATE( 0, 1 );
1694
1695 qmatrix projector = getProjector(outcome);
1696
1697 auto testFunc = [&](Qureg qureg, auto& ref) {
1698
1699 // overwrite caller's setting of initDebugState, since
1700 // that precludes outcomes=|0><0| due to zero-probability
1701 setToRandomState(ref);
1702 setQuregToReference(qureg, ref);
1703
1704 // compare the probabilities...
1705 qreal apiProb = applyForcedQubitMeasurement(qureg, target, outcome);
1706 qreal refProb = getReferenceProbability(ref, {target}, {outcome});
1707 REQUIRE_AGREE( apiProb, refProb );
1708
1709 // and the post-projection states (caller calls subsequent REQUIRE_AGREE)
1710 applyReferenceOperator(ref, {target}, projector);
1711 ref /= (qureg.isDensityMatrix)?
1712 refProb : std::sqrt(refProb);
1713 };
1714
1715 CAPTURE( target, outcome );
1716 SECTION( LABEL_STATEVEC ) { TEST_ON_CACHED_QUREGS(statevecQuregs, statevecRef, testFunc); }
1717 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(densmatrQuregs, densmatrRef, testFunc); }
1718 }
1719
1720 SECTION( LABEL_VALIDATION ) {
1721
1722 Qureg qureg = getArbitraryCachedStatevec();
1723
1724 // below validation tests assume qubit 0 can collapse to either outcome
1725 // (which does not require normalisation; qureg can be in the debug state)
1726 initDebugState(qureg);
1727 REQUIRE( calcProbOfQubitOutcome(qureg, 0, 0) > getQuESTValidationEpsilon() );
1728 REQUIRE( calcProbOfQubitOutcome(qureg, 0, 1) > getQuESTValidationEpsilon() );
1729
1730 SECTION( "qureg uninitialised" ) {
1731
1732 Qureg badQureg = qureg;
1733 badQureg.numQubits = -1;
1734 REQUIRE_THROWS_WITH(
1735 applyForcedQubitMeasurement(badQureg, 0, 0),
1736 ContainsSubstring("invalid Qureg")
1737 );
1738 }
1739
1740 SECTION( "invalid target qubit" ) {
1741
1742 int badTarget = GENERATE_COPY( -1, qureg.numQubits );
1743 REQUIRE_THROWS_WITH(
1744 applyForcedQubitMeasurement(qureg, badTarget, 0),
1745 ContainsSubstring("target")
1746 );
1747 }
1748
1749 SECTION( "invalid outcome" ) {
1750
1751 int badOutcome = GENERATE_COPY( -1, 2 );
1752 REQUIRE_THROWS_WITH(
1753 applyForcedQubitMeasurement(qureg, 0, badOutcome),
1754 ContainsSubstring("outcome")
1755 );
1756 }
1757
1758 SECTION( "improbable outcome" ) {
1759
1760 // precisely zero probability outcome
1761 initZeroState(qureg);
1762 int badOutcome = 1; // impossible
1763 REQUIRE_THROWS_WITH(
1764 applyForcedQubitMeasurement(qureg, 0, badOutcome),
1765 ContainsSubstring("impossibly unlikely")
1766 );
1767
1768 // outcome of non-zero probability smaller than epsilon
1769 qreal badTheta = 1E-8;
1770 applyRotateX(qureg, 0, badTheta); // causes prob(1) = sin^2(theta) ~ 2.5E-17
1771 REQUIRE_THROWS_WITH(
1772 applyForcedQubitMeasurement(qureg, 0, badOutcome),
1773 ContainsSubstring("impossibly unlikely")
1774 );
1775
1776 // confirm that >epsilon probability is fine
1777 initZeroState(qureg);
1778 qreal goodTheta = 0.1;
1779 applyRotateX(qureg, 0, goodTheta);
1780 REQUIRE(
1781 calcProbOfQubitOutcome(qureg, 0, badOutcome) > getQuESTValidationEpsilon()
1782 );
1783 REQUIRE_NOTHROW(
1784 applyForcedQubitMeasurement(qureg, 0, badOutcome)
1785 );
1786
1787 // restore qureg state
1788 initDebugState(qureg);
1789 }
1790 }
1791}
qreal calcProbOfQubitOutcome(Qureg qureg, int qubit, int outcome)
qreal applyForcedQubitMeasurement(Qureg qureg, int target, int outcome)

◆ TEST_CASE() [3/19]

TEST_CASE ( "applyFullQuantumFourierTransform" ,
TEST_CATEGORY_OPS  )

Definition at line 1470 of file operations.cpp.

1470 {
1471
1472 PREPARE_TEST( numQubits, statevecQuregs, densmatrQuregs, statevecRef, densmatrRef );
1473
1474 SECTION( LABEL_CORRECTNESS ) {
1475
1476 GENERATE( range(0,10) );
1477 bool inverse = GENERATE(false, true);
1478
1479 SECTION( LABEL_STATEVEC ) {
1480
1481 auto testFunc = [&](Qureg qureg, qvector& ref) {
1482 applyFullQuantumFourierTransform(qureg, inverse);
1483 ref = getDiscreteFourierTransform(ref, inverse);
1484 };
1485
1486 CAPTURE(inverse);
1487 TEST_ON_CACHED_QUREGS(statevecQuregs, statevecRef, testFunc);
1488 }
1489
1490 SECTION( LABEL_DENSMATR ) {
1491
1492 // prepare a random mixture
1493 auto states = getRandomOrthonormalStateVectors(numQubits, getRandomInt(1,10));
1494 auto probs = getRandomProbabilities(states.size());
1495
1496 auto testFunc = [&](Qureg qureg, qmatrix& ref) {
1497
1498 // overwrite the Qureg debug state set by caller to above mixture
1499 setQuregToReference(qureg, getMixture(states, probs));
1500 applyFullQuantumFourierTransform(qureg, inverse);
1501
1502 ref = getZeroMatrix(ref.size());
1503 for (size_t i=0; i<states.size(); i++) {
1504 qvector vec = getDiscreteFourierTransform(states[i], inverse);
1505 ref += probs[i] * getOuterProduct(vec, vec);
1506 }
1507 };
1508
1509 CAPTURE(inverse);
1510 TEST_ON_CACHED_QUREGS(densmatrQuregs, densmatrRef, testFunc);
1511 }
1512 }
1513
1514 SECTION( LABEL_VALIDATION ) {
1515
1516 Qureg qureg = getArbitraryCachedStatevec();
1517 bool inverse = false;
1518
1519 SECTION( "qureg uninitialised" ) {
1520
1521 Qureg badQureg = qureg;
1522 badQureg.numQubits = -1;
1523 REQUIRE_THROWS_WITH(
1524 applyFullQuantumFourierTransform(badQureg, inverse),
1525 ContainsSubstring("invalid Qureg")
1526 );
1527 }
1528 }
1529}
void applyFullQuantumFourierTransform(Qureg qureg, bool inverse)
qmatrix getZeroMatrix(size_t dim)
Definition qmatrix.cpp:18
vector< qreal > getRandomProbabilities(int numProbs)
Definition random.cpp:160
int getRandomInt(int min, int maxExcl)
Definition random.cpp:90

◆ TEST_CASE() [4/19]

TEST_CASE ( "applyFullStateDiagMatr" ,
TEST_CATEGORY_OPS LABEL_MIXED_DEPLOY_TAG )

Definition at line 2236 of file operations.cpp.

2236 {
2237
2238 PREPARE_TEST( numQubits, cachedSV, cachedDM, refSV, refDM );
2239
2240 auto cachedMatrs = getCachedFullStateDiagMatrs();
2241
2242 SECTION( LABEL_CORRECTNESS ) {
2243
2244 qmatrix refMatr = getRandomDiagonalUnitary(numQubits);
2245 auto apiFunc = applyFullStateDiagMatr;
2246
2247 GENERATE( range(0, getNumTestedMixedDeploymentRepetitions()) );
2248
2249 SECTION( LABEL_STATEVEC ) {
2250
2251 auto refFunc = [&] (qvector& state, qmatrix matr) { applyReferenceOperator(state, matr); };
2252
2253 TEST_ON_CACHED_QUREG_AND_MATRIX( cachedSV, cachedMatrs, apiFunc, refSV, refMatr, refFunc);
2254 }
2255
2256 SECTION( LABEL_DENSMATR ) {
2257
2258 auto refFunc = [&] (qmatrix& state, qmatrix matr) { applyReferenceOperator(state, matr); };
2259
2260 TEST_ON_CACHED_QUREG_AND_MATRIX( cachedDM, cachedMatrs, apiFunc, refDM, refMatr, refFunc);
2261 }
2262 }
2263
2264 /// @todo input validation
2265}
void applyFullStateDiagMatr(Qureg qureg, FullStateDiagMatr matrix)

◆ TEST_CASE() [5/19]

TEST_CASE ( "applyFullStateDiagMatrPower" ,
TEST_CATEGORY_OPS LABEL_MIXED_DEPLOY_TAG )

Definition at line 2268 of file operations.cpp.

2268 {
2269
2270 PREPARE_TEST( numQubits, cachedSV, cachedDM, refSV, refDM );
2271
2272 auto cachedMatrs = getCachedFullStateDiagMatrs();
2273
2274 SECTION( LABEL_CORRECTNESS ) {
2275
2276 qmatrix refMatr = getRandomDiagonalUnitary(numQubits);
2277
2278 // supplying a complex exponent requires disabling
2279 // numerical validation to relax unitarity
2280 bool testRealExp = GENERATE( true, false );
2281 qcomp exponent = (testRealExp)?
2282 qcomp(getRandomReal(-2, 2), 0):
2284
2285 auto apiFunc = [&](Qureg qureg, FullStateDiagMatr matr) {
2286 return applyFullStateDiagMatrPower(qureg, matr, exponent);
2287 };
2288
2289 CAPTURE( exponent );
2290
2291 GENERATE( range(0, getNumTestedMixedDeploymentRepetitions()) );
2292
2293 if (!testRealExp)
2295
2296 SECTION( LABEL_STATEVEC ) {
2297
2298 auto refFunc = [&] (qvector& state, qmatrix matr) {
2299 matr = getPowerOfDiagonalMatrix(matr, exponent);
2300 applyReferenceOperator(state, matr);
2301 };
2302
2303 TEST_ON_CACHED_QUREG_AND_MATRIX( cachedSV, cachedMatrs, apiFunc, refSV, refMatr, refFunc);
2304 }
2305
2306 SECTION( LABEL_DENSMATR ) {
2307
2308 auto refFunc = [&] (qmatrix& state, qmatrix matr) {
2309 matr = getPowerOfDiagonalMatrix(matr, exponent);
2310 applyReferenceOperator(state, matr);
2311 };
2312
2313 TEST_ON_CACHED_QUREG_AND_MATRIX( cachedDM, cachedMatrs, apiFunc, refDM, refMatr, refFunc);
2314 }
2315
2317 }
2318
2319 /// @todo input validation
2320}
void applyFullStateDiagMatrPower(Qureg qureg, FullStateDiagMatr matrix, qcomp exponent)
qcomp getRandomComplex()
Definition random.cpp:107
qreal getRandomReal(qreal min, qreal maxExcl)
Definition random.cpp:63

◆ TEST_CASE() [6/19]

TEST_CASE ( "applyMultiQubitMeasurement" ,
TEST_CATEGORY_OPS  )

Definition at line 1944 of file operations.cpp.

1944 {
1945
1946 PREPARE_TEST( numQubits, statevecQuregs, densmatrQuregs, statevecRef, densmatrRef );
1947
1948 SECTION( LABEL_CORRECTNESS ) {
1949
1950 int numTargs = GENERATE_COPY( range(1,numQubits+1) );
1951 auto targets = GENERATE_TARGS( numQubits, numTargs );
1952
1953 auto testFunc = [&](Qureg qureg, auto& ref) {
1954
1955 // overwrite caller's setting of initDebugState, since
1956 // sampling requires the outcome probs are normalised
1957 setToRandomState(ref);
1958 setQuregToReference(qureg, ref);
1959
1960 // the output API state...
1961 qindex apiOut = applyMultiQubitMeasurement(qureg, targets.data(), numTargs);
1962
1963 // informs the projector which determines the post-measurement reference
1964 auto apiOutBits = getBits(apiOut, numTargs);
1965 qmatrix projector = getProjector(targets, apiOutBits, numQubits);
1966 applyReferenceOperator(ref, projector);
1967 qreal refProb = getReferenceProbability(ref, targets, apiOutBits);
1968 ref /= (qureg.isDensityMatrix)?
1969 refProb : std::sqrt(refProb);
1970 };
1971
1972 CAPTURE( targets );
1973 SECTION( LABEL_STATEVEC ) { TEST_ON_CACHED_QUREGS(statevecQuregs, statevecRef, testFunc); }
1974 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(densmatrQuregs, densmatrRef, testFunc); }
1975 }
1976
1977 SECTION( LABEL_VALIDATION ) {
1978
1979 Qureg qureg = getArbitraryCachedStatevec();
1980 int targets[] = {0, 1, 2};
1981 int numTargets = 3;
1982
1983 SECTION( "qureg uninitialised" ) {
1984
1985 Qureg badQureg = qureg;
1986 badQureg.numQubits = -1;
1987 REQUIRE_THROWS_WITH(
1988 applyMultiQubitMeasurement(badQureg, targets, numTargets),
1989 ContainsSubstring("invalid Qureg")
1990 );
1991 }
1992
1993 SECTION( "invalid target qubits" ) {
1994
1995 int badTargets[] = {0, 1, GENERATE_COPY(-1, qureg.numQubits)};
1996 REQUIRE_THROWS_WITH(
1997 applyMultiQubitMeasurement(qureg, badTargets, numTargets),
1998 ContainsSubstring("target")
1999 );
2000 }
2001
2002 SECTION( "duplicate target qubits" ) {
2003
2004 int dupTargets[] = {0, 1, 1};
2005 REQUIRE_THROWS_WITH(
2006 applyMultiQubitMeasurement(qureg, dupTargets, numTargets),
2007 ContainsSubstring("duplicate")
2008 );
2009 }
2010
2011 SECTION( "invalid number of targets" ) {
2012
2013 int badNumTargs = GENERATE( -1, 0 );
2014 REQUIRE_THROWS_WITH(
2015 applyMultiQubitMeasurement(qureg, targets, badNumTargs),
2016 ContainsSubstring("targets")
2017 );
2018
2019 badNumTargs = qureg.numQubits + 1;
2020 REQUIRE_THROWS_WITH(
2021 applyMultiQubitMeasurement(qureg, targets, badNumTargs),
2022 ContainsSubstring("exceeds the number of qubits in the Qureg")
2023 );
2024 }
2025 }
2026}
qindex applyMultiQubitMeasurement(Qureg qureg, int *qubits, int numQubits)

◆ TEST_CASE() [7/19]

TEST_CASE ( "applyMultiQubitMeasurementAndGetProb" ,
TEST_CATEGORY_OPS  )

Definition at line 2029 of file operations.cpp.

2029 {
2030
2031 PREPARE_TEST( numQubits, statevecQuregs, densmatrQuregs, statevecRef, densmatrRef );
2032
2033 SECTION( LABEL_CORRECTNESS ) {
2034
2035 int numTargs = GENERATE_COPY( range(1,numQubits+1) );
2036 auto targets = GENERATE_TARGS( numQubits, numTargs );
2037
2038 auto testFunc = [&](Qureg qureg, auto& ref) {
2039
2040 // overwrite caller's setting of initDebugState, since
2041 // sampling requires the outcome probs are normalised
2042 setToRandomState(ref);
2043 setQuregToReference(qureg, ref);
2044
2045 // compare the measurement probability...
2046 qreal apiProb = -1;
2047 qindex apiOut = applyMultiQubitMeasurementAndGetProb(qureg, targets.data(), numTargs, &apiProb);
2048 auto apiOutBits = getBits(apiOut, numTargs);
2049 qreal refProb = getReferenceProbability(ref, targets, apiOutBits);
2050 REQUIRE_AGREE( apiProb, refProb );
2051
2052 // and the post-measurement states (caller calls subsequent REQUIRE_AGREE)
2053 qmatrix projector = getProjector(targets, apiOutBits, numQubits);
2054 applyReferenceOperator(ref, projector);
2055 ref /= (qureg.isDensityMatrix)?
2056 refProb : std::sqrt(refProb);
2057 };
2058
2059 CAPTURE( targets );
2060 SECTION( LABEL_STATEVEC ) { TEST_ON_CACHED_QUREGS(statevecQuregs, statevecRef, testFunc); }
2061 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(densmatrQuregs, densmatrRef, testFunc); }
2062 }
2063
2064 SECTION( LABEL_VALIDATION ) {
2065
2066 Qureg qureg = getArbitraryCachedStatevec();
2067 int targets[] = {0, 1, 2};
2068 int numTargets = 3;
2069 qreal outProb = 0;
2070
2071 SECTION( "qureg uninitialised" ) {
2072
2073 Qureg badQureg = qureg;
2074 badQureg.numQubits = -1;
2075 REQUIRE_THROWS_WITH(
2076 applyMultiQubitMeasurementAndGetProb(badQureg, targets, numTargets, nullptr),
2077 ContainsSubstring("invalid Qureg")
2078 );
2079 }
2080
2081 SECTION( "invalid target qubits" ) {
2082
2083 int badTargets[] = {0, 1, GENERATE_COPY( -1, qureg.numQubits )};
2084 REQUIRE_THROWS_WITH(
2085 applyMultiQubitMeasurementAndGetProb(qureg, badTargets, numTargets, &outProb),
2086 ContainsSubstring("target")
2087 );
2088 }
2089
2090 SECTION( "duplicate target qubits" ) {
2091
2092 int dupTargets[] = {0, 1, 1};
2093 REQUIRE_THROWS_WITH(
2094 applyMultiQubitMeasurementAndGetProb(qureg, dupTargets, numTargets, &outProb),
2095 ContainsSubstring("duplicate")
2096 );
2097 }
2098
2099 SECTION( "invalid number of targets" ) {
2100
2101 int badNumTargs = GENERATE( -1, 0 );
2102 REQUIRE_THROWS_WITH(
2103 applyMultiQubitMeasurementAndGetProb(qureg, targets, badNumTargs, &outProb),
2104 ContainsSubstring("targets")
2105 );
2106
2107 badNumTargs = qureg.numQubits + 1;
2108 REQUIRE_THROWS_WITH(
2109 applyMultiQubitMeasurementAndGetProb(qureg, targets, badNumTargs, &outProb),
2110 ContainsSubstring("exceeds the number of qubits in the Qureg")
2111 );
2112 }
2113 }
2114}
qindex applyMultiQubitMeasurementAndGetProb(Qureg qureg, int *qubits, int numQubits, qreal *probability)

◆ TEST_CASE() [8/19]

TEST_CASE ( "applyMultiQubitPhaseFlip" ,
TEST_CATEGORY_OPS  )

Definition at line 1355 of file operations.cpp.

1355 {
1356 auto func = static_cast<void(*)(Qureg, int*, int)>(applyMultiQubitPhaseFlip);
1357 testOperation<zero,any,none,apply>(func, VariableSizeMatrices::PF);
1358}
void applyMultiQubitPhaseFlip(Qureg qureg, int *targets, int numTargets)

◆ TEST_CASE() [9/19]

TEST_CASE ( "applyMultiQubitPhaseShift" ,
TEST_CATEGORY_OPS  )

Definition at line 1360 of file operations.cpp.

1360 {
1361 auto func = static_cast<void(*)(Qureg, int*, int, qreal)>(applyMultiQubitPhaseShift);
1362 testOperation<zero,any,scalar,apply>(func, VariableSizeParameterisedMatrices::PS);
1363}
void applyMultiQubitPhaseShift(Qureg qureg, int *targets, int numTargets, qreal angle)

◆ TEST_CASE() [10/19]

TEST_CASE ( "applyMultiQubitProjector" ,
TEST_CATEGORY_OPS  )

Definition at line 1591 of file operations.cpp.

1591 {
1592
1593 PREPARE_TEST( numQubits, statevecQuregs, densmatrQuregs, statevecRef, densmatrRef );
1594
1595 SECTION( LABEL_CORRECTNESS ) {
1596
1597 int numTargs = GENERATE_COPY( range(1,numQubits+1) );
1598 auto targets = GENERATE_TARGS( numQubits, numTargs );
1599 auto outcomes = getRandomOutcomes(numTargs);
1600
1601 qmatrix projector = getProjector(targets, outcomes, numQubits);
1602
1603 auto testFunc = [&](Qureg qureg, auto& ref) {
1604 applyMultiQubitProjector(qureg, targets.data(), outcomes.data(), numTargs);
1605 applyReferenceOperator(ref, projector);
1606 };
1607
1608 CAPTURE( targets, outcomes );
1609 SECTION( LABEL_STATEVEC ) { TEST_ON_CACHED_QUREGS(statevecQuregs, statevecRef, testFunc); }
1610 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(densmatrQuregs, densmatrRef, testFunc); }
1611 }
1612
1613 SECTION( LABEL_VALIDATION ) {
1614
1615 Qureg qureg = getArbitraryCachedStatevec();
1616 int targets[] = {0, 1, 2};
1617 int outcomes[] = {0, 1, 0};
1618 int numTargets = 3;
1619
1620 SECTION( "qureg uninitialised" ) {
1621
1622 Qureg badQureg = qureg;
1623 badQureg.numQubits = -1;
1624 REQUIRE_THROWS_WITH(
1625 applyMultiQubitProjector(badQureg, targets, outcomes, numTargets),
1626 ContainsSubstring("invalid Qureg")
1627 );
1628 }
1629
1630 SECTION( "invalid target qubits" ) {
1631
1632 int badTargets[] = {0, 1, GENERATE_COPY( -1, qureg.numQubits) };
1633 REQUIRE_THROWS_WITH(
1634 applyMultiQubitProjector(qureg, badTargets, outcomes, numTargets),
1635 ContainsSubstring("target")
1636 );
1637 }
1638
1639 SECTION( "duplicate target qubits" ) {
1640
1641 int dupTargets[] = {0, 1, 1};
1642 REQUIRE_THROWS_WITH(
1643 applyMultiQubitProjector(qureg, dupTargets, outcomes, numTargets),
1644 ContainsSubstring("duplicate")
1645 );
1646 }
1647
1648 SECTION( "invalid number of targets" ) {
1649
1650 int badNumTargs = GENERATE( 0, -1 );
1651 REQUIRE_THROWS_WITH(
1652 applyMultiQubitProjector(qureg, targets, outcomes, badNumTargs),
1653 ContainsSubstring("targets")
1654 );
1655
1656 badNumTargs = qureg.numQubits + 1;
1657 REQUIRE_THROWS_WITH(
1658 applyMultiQubitProjector(qureg, targets, outcomes, badNumTargs),
1659 ContainsSubstring("exceeds the number of qubits in the Qureg")
1660 );
1661 }
1662
1663 SECTION( "invalid outcomes" ) {
1664
1665 int badOutcomes[] = {0, 1, GENERATE( -1, 2 ) };
1666 REQUIRE_THROWS_WITH(
1667 applyMultiQubitProjector(qureg, targets, badOutcomes, numTargets),
1668 ContainsSubstring("outcome")
1669 );
1670 }
1671
1672 SECTION( "targets mismatch outcomes (C++ only)" ) {
1673
1674 REQUIRE_THROWS_WITH(
1675 applyMultiQubitProjector(qureg, {0,1,2}, {0,1}),
1676 ContainsSubstring("outcomes") && ContainsSubstring("inconsistent with the given number of qubits")
1677 );
1678 }
1679
1680 // projector does NOT validate outcome probability
1681 }
1682}
void applyMultiQubitProjector(Qureg qureg, int *qubits, int *outcomes, int numQubits)

◆ TEST_CASE() [11/19]

TEST_CASE ( "applyNonUnitaryPauliGadget" ,
TEST_CATEGORY_OPS  )

Definition at line 2323 of file operations.cpp.

2323 {
2324
2325 PREPARE_TEST( numQubits, statevecQuregs, densmatrQuregs, statevecRef, densmatrRef );
2326
2327 SECTION( LABEL_CORRECTNESS ) {
2328
2329 // prepare a random Pauli string and angle
2330 int numTargs = GENERATE_COPY( range(1, numQubits+1) );
2331 auto targs = GENERATE_TARGS( numQubits, numTargs );
2332 PauliStr str = getRandomPauliStr(targs);
2333 qcomp angle = getRandomComplex();
2334
2335 // prepare the corresponding reference matrix exp(-i angle pauli)
2336 auto matrRef = getExponentialOfPauliMatrix(angle, getMatrix(str, numQubits));
2337
2338 auto testFunc = [&](Qureg qureg, auto& stateRef) {
2339 applyNonUnitaryPauliGadget(qureg, str, angle);
2340 applyReferenceOperator(stateRef, matrRef);
2341 };
2342
2343 CAPTURE( targs, angle );
2344 SECTION( LABEL_STATEVEC ) { TEST_ON_CACHED_QUREGS(statevecQuregs, statevecRef, testFunc); }
2345 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(densmatrQuregs, densmatrRef, testFunc); }
2346 }
2347
2348 SECTION( LABEL_VALIDATION ) {
2349
2350 Qureg qureg = getArbitraryCachedStatevec();
2351 PauliStr str = getPauliStr("XY", {0, 1});
2352
2353 SECTION( "qureg uninitialised" ) {
2354
2355 Qureg badQureg = qureg;
2356 badQureg.numQubits = -1;
2357 REQUIRE_THROWS_WITH(
2358 applyNonUnitaryPauliGadget(badQureg, str, qcomp(0.5, 0)),
2359 ContainsSubstring("invalid Qureg")
2360 );
2361 }
2362
2363 /// @todo remaining input validation
2364 }
2365}
void applyNonUnitaryPauliGadget(Qureg qureg, PauliStr str, qcomp angle)
PauliStr getPauliStr(const char *paulis, int *indices, int numPaulis)
Definition paulis.cpp:76

◆ TEST_CASE() [12/19]

TEST_CASE ( "applyPhaseFlip" ,
TEST_CATEGORY_OPS  )

Definition at line 1342 of file operations.cpp.

1342{ testOperation<zero,one,none,apply> (applyPhaseFlip, VariableSizeMatrices::PF(1)); }
void applyPhaseFlip(Qureg qureg, int target)

◆ TEST_CASE() [13/19]

TEST_CASE ( "applyPhaseShift" ,
TEST_CATEGORY_OPS  )

Definition at line 1344 of file operations.cpp.

1344{ testOperation<zero,one,scalar,apply>(applyPhaseShift, ParameterisedMatrices::PS ); }
void applyPhaseShift(Qureg qureg, int target, qreal angle)

◆ TEST_CASE() [14/19]

TEST_CASE ( "applyQuantumFourierTransform" ,
TEST_CATEGORY_OPS  )

Definition at line 1370 of file operations.cpp.

1370 {
1371
1372 PREPARE_TEST( numQubits, statevecQuregs, densmatrQuregs, statevecRef, densmatrRef );
1373
1374 SECTION( LABEL_CORRECTNESS ) {
1375
1376 int numTargs = GENERATE_COPY( range(1,numQubits+1) );
1377 auto targs = GENERATE_TARGS( numQubits, numTargs );
1378 bool inverse = GENERATE(false, true);
1379
1380 CAPTURE( targs );
1381
1382 SECTION( LABEL_STATEVEC ) {
1383
1384 auto testFunc = [&](Qureg qureg, qvector& ref) {
1385 applyQuantumFourierTransform(qureg, targs.data(), targs.size(), inverse);
1386 ref = getDiscreteFourierTransform(ref, targs, inverse);
1387 };
1388
1389 CAPTURE(inverse);
1390 TEST_ON_CACHED_QUREGS(statevecQuregs, statevecRef, testFunc);
1391 }
1392
1393 SECTION( LABEL_DENSMATR ) {
1394
1395 // prepare a random mixture
1396 auto states = getRandomOrthonormalStateVectors(numQubits, getRandomInt(1,10));
1397 auto probs = getRandomProbabilities(states.size());
1398
1399 auto testFunc = [&](Qureg qureg, qmatrix& ref) {
1400
1401 // overwrite the Qureg debug state set by caller to above mixture
1402 setQuregToReference(qureg, getMixture(states, probs));
1403 applyQuantumFourierTransform(qureg, targs.data(), targs.size(), inverse);
1404
1405 ref = getZeroMatrix(ref.size());
1406 for (size_t i=0; i<states.size(); i++) {
1407 qvector vec = getDiscreteFourierTransform(states[i], targs, inverse);
1408 ref += probs[i] * getOuterProduct(vec, vec);
1409 }
1410 };
1411
1412 CAPTURE(inverse);
1413 TEST_ON_CACHED_QUREGS(densmatrQuregs, densmatrRef, testFunc);
1414 }
1415 }
1416
1417 SECTION( LABEL_VALIDATION ) {
1418
1419 Qureg qureg = getArbitraryCachedStatevec();
1420 int targs[] = {0, 1, 2};
1421 int numTargs = 3;
1422 bool inverse = false;
1423
1424 SECTION( "qureg uninitialised" ) {
1425
1426 Qureg badQureg = qureg;
1427 badQureg.numQubits = -1;
1428 REQUIRE_THROWS_WITH(
1429 applyQuantumFourierTransform(badQureg, targs, numTargs, inverse),
1430 ContainsSubstring("invalid Qureg")
1431 );
1432 }
1433
1434 SECTION( "invalid target qubits" ) {
1435
1436 int badTargs[] = {0, 1, qureg.numQubits}; // latter is too large
1437 REQUIRE_THROWS_WITH(
1438 applyQuantumFourierTransform(qureg, badTargs, 3, inverse),
1439 ContainsSubstring("target")
1440 );
1441 }
1442
1443 SECTION( "duplicate target qubits" ) {
1444
1445 int dupTargs[] = {0, 1, 1};
1446 REQUIRE_THROWS_WITH(
1447 applyQuantumFourierTransform(qureg, dupTargs, 3, inverse),
1448 ContainsSubstring("duplicate")
1449 );
1450 }
1451
1452 SECTION( "invalid number of targets" ) {
1453
1454 int badNumTargs = GENERATE_COPY( -1, 0 );
1455 REQUIRE_THROWS_WITH(
1456 applyQuantumFourierTransform(qureg, targs, badNumTargs, inverse),
1457 ContainsSubstring("targets") || ContainsSubstring("target qubits")
1458 );
1459
1460 badNumTargs = qureg.numQubits+1;
1461 REQUIRE_THROWS_WITH(
1462 applyQuantumFourierTransform(qureg, targs, badNumTargs, inverse),
1463 ContainsSubstring("exceeds the number of qubits in the Qureg")
1464 );
1465 }
1466 }
1467}
void applyQuantumFourierTransform(Qureg qureg, int *targets, int numTargets, bool inverse)

◆ TEST_CASE() [15/19]

TEST_CASE ( "applyQubitMeasurement" ,
TEST_CATEGORY_OPS  )

Definition at line 2117 of file operations.cpp.

2117 {
2118
2119 PREPARE_TEST( numQubits, statevecQuregs, densmatrQuregs, statevecRef, densmatrRef );
2120
2121 SECTION( LABEL_CORRECTNESS ) {
2122
2123 GENERATE( range(0,10) );
2124 int target = GENERATE_COPY( range(0,numQubits) );
2125
2126 auto testFunc = [&](Qureg qureg, auto& ref) {
2127
2128 // overwrite caller's setting of initDebugState, since
2129 // sampling requires the outcome probs are normalised
2130 setToRandomState(ref);
2131 setQuregToReference(qureg, ref);
2132
2133 // the output API state...
2134 int apiOut = applyQubitMeasurement(qureg, target);
2135
2136 // informs the projector which determines the post-measurement reference
2137 qmatrix projector = getProjector(apiOut);
2138 applyReferenceOperator(ref, {target}, projector);
2139 qreal refProb = getReferenceProbability(ref, {target}, {apiOut});
2140 ref /= (qureg.isDensityMatrix)?
2141 refProb : std::sqrt(refProb);
2142 };
2143
2144 CAPTURE( target );
2145 SECTION( LABEL_STATEVEC ) { TEST_ON_CACHED_QUREGS(statevecQuregs, statevecRef, testFunc); }
2146 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(densmatrQuregs, densmatrRef, testFunc); }
2147 }
2148
2149 SECTION( LABEL_VALIDATION ) {
2150
2151 Qureg qureg = getArbitraryCachedStatevec();
2152
2153 SECTION( "qureg uninitialised" ) {
2154
2155 Qureg badQureg = qureg;
2156 badQureg.numQubits = -1;
2157 REQUIRE_THROWS_WITH(
2158 applyQubitMeasurement(badQureg, 0),
2159 ContainsSubstring("invalid Qureg")
2160 );
2161 }
2162
2163 SECTION( "invalid target qubit" ) {
2164
2165 int badTarget = GENERATE_COPY( -1, qureg.numQubits );
2166 REQUIRE_THROWS_WITH(
2167 applyQubitMeasurement(qureg, badTarget),
2168 ContainsSubstring("target")
2169 );
2170 }
2171 }
2172}
int applyQubitMeasurement(Qureg qureg, int target)

◆ TEST_CASE() [16/19]

TEST_CASE ( "applyQubitMeasurementAndGetProb" ,
TEST_CATEGORY_OPS  )

Definition at line 2175 of file operations.cpp.

2175 {
2176
2177 PREPARE_TEST( numQubits, statevecQuregs, densmatrQuregs, statevecRef, densmatrRef );
2178
2179 SECTION( LABEL_CORRECTNESS ) {
2180
2181 GENERATE( range(0,10) );
2182 int target = GENERATE_COPY( range(0,numQubits) );
2183
2184 auto testFunc = [&](Qureg qureg, auto& ref) {
2185
2186 // overwrite caller's setting of initDebugState, since
2187 // sampling requires the outcome probs are normalised
2188 setToRandomState(ref);
2189 setQuregToReference(qureg, ref);
2190
2191 // compare the measurement probability...
2192 qreal apiProb = -1;
2193 int apiOut = applyQubitMeasurementAndGetProb(qureg, target, &apiProb);
2194 qreal refProb = getReferenceProbability(ref, {target}, {apiOut});
2195 REQUIRE_AGREE( apiProb, refProb );
2196
2197 // and the post-measurement states (caller calls subsequent REQUIRE_AGREE)
2198 qmatrix projector = getProjector(apiOut);
2199 applyReferenceOperator(ref, {target}, projector);
2200 ref /= (qureg.isDensityMatrix)?
2201 refProb : std::sqrt(refProb);
2202 };
2203
2204 CAPTURE( target );
2205 SECTION( LABEL_STATEVEC ) { TEST_ON_CACHED_QUREGS(statevecQuregs, statevecRef, testFunc); }
2206 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(densmatrQuregs, densmatrRef, testFunc); }
2207 }
2208
2209 SECTION( LABEL_VALIDATION ) {
2210
2211 Qureg qureg = getArbitraryCachedStatevec();
2212 qreal outProb = 0;
2213
2214 SECTION( "qureg uninitialised" ) {
2215
2216 Qureg badQureg = qureg;
2217 badQureg.numQubits = -1;
2218 REQUIRE_THROWS_WITH(
2219 applyQubitMeasurementAndGetProb(badQureg, 0, &outProb),
2220 ContainsSubstring("invalid Qureg")
2221 );
2222 }
2223
2224 SECTION( "invalid target qubit" ) {
2225
2226 int badTarget = GENERATE_COPY( -1, qureg.numQubits );
2227 REQUIRE_THROWS_WITH(
2228 applyQubitMeasurementAndGetProb(qureg, badTarget, &outProb),
2229 ContainsSubstring("target")
2230 );
2231 }
2232 }
2233}
int applyQubitMeasurementAndGetProb(Qureg qureg, int target, qreal *probability)

◆ TEST_CASE() [17/19]

TEST_CASE ( "applyQubitProjector" ,
TEST_CATEGORY_OPS  )

Definition at line 1532 of file operations.cpp.

1532 {
1533
1534 PREPARE_TEST( numQubits, statevecQuregs, densmatrQuregs, statevecRef, densmatrRef );
1535
1536 SECTION( LABEL_CORRECTNESS ) {
1537
1538 GENERATE( range(0,10) );
1539 int target = GENERATE_COPY( range(0,numQubits) );
1540 int outcome = GENERATE( 0, 1 );
1541
1542 qmatrix projector = getProjector(outcome);
1543
1544 auto testFunc = [&](Qureg qureg, auto& ref) {
1545 applyQubitProjector(qureg, target, outcome);
1546 applyReferenceOperator(ref, {target}, projector);
1547 };
1548
1549 CAPTURE( target, outcome );
1550 SECTION( LABEL_STATEVEC ) { TEST_ON_CACHED_QUREGS(statevecQuregs, statevecRef, testFunc); }
1551 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(densmatrQuregs, densmatrRef, testFunc); }
1552 }
1553
1554 SECTION( LABEL_VALIDATION ) {
1555
1556 Qureg qureg = getArbitraryCachedStatevec();
1557
1558 SECTION( "qureg uninitialised" ) {
1559
1560 Qureg badQureg = qureg;
1561 badQureg.numQubits = -1;
1562 REQUIRE_THROWS_WITH(
1563 applyQubitProjector(badQureg, 0, 0),
1564 ContainsSubstring("invalid Qureg")
1565 );
1566 }
1567
1568 SECTION( "invalid target qubit" ) {
1569
1570 int badTarget = GENERATE_COPY( -1, qureg.numQubits );
1571 REQUIRE_THROWS_WITH(
1572 applyQubitProjector(qureg, badTarget, 0),
1573 ContainsSubstring("target")
1574 );
1575 }
1576
1577 SECTION( "invalid outcome" ) {
1578
1579 int badOutcome = GENERATE_COPY( -1, 2 );
1580 REQUIRE_THROWS_WITH(
1581 applyQubitProjector(qureg, 0, badOutcome),
1582 ContainsSubstring("outcome")
1583 );
1584 }
1585
1586 // projector does NOT validate outcome probability
1587 }
1588}
void applyQubitProjector(Qureg qureg, int target, int outcome)

◆ TEST_CASE() [18/19]

TEST_CASE ( "applyTwoQubitPhaseFlip" ,
TEST_CATEGORY_OPS  )

Definition at line 1343 of file operations.cpp.

1343{ testOperation<zero,two,none,apply> (applyTwoQubitPhaseFlip, VariableSizeMatrices::PF(2)); }
void applyTwoQubitPhaseFlip(Qureg qureg, int target1, int target2)

◆ TEST_CASE() [19/19]

TEST_CASE ( "applyTwoQubitPhaseShift" ,
TEST_CATEGORY_OPS  )

Definition at line 1345 of file operations.cpp.

1345{ testOperation<zero,two,scalar,apply>(applyTwoQubitPhaseShift, ParameterisedMatrices::PS2 ); }
void applyTwoQubitPhaseShift(Qureg qureg, int target1, int target2, qreal angle)