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
1807
1808
1810
1811 auto testFunc = [&](
Qureg qureg,
auto& ref) {
1812
1813
1814
1815 setToRandomState(ref);
1816 setQuregToReference(qureg, ref);
1817
1818
1820 qreal refProb = getReferenceProbability(ref, targets, outcomes);
1821 REQUIRE_AGREE( apiProb, refProb );
1822
1823
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
1846
1847 SECTION( "qureg uninitialised" ) {
1848
1849 Qureg badQureg = qureg;
1850 badQureg.numQubits = -1;
1851 REQUIRE_THROWS_WITH(
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(
1862 ContainsSubstring("target")
1863 );
1864 }
1865
1866 SECTION( "duplicate target qubits" ) {
1867
1868 int dupTargets[] = {0, 1, 1};
1869 REQUIRE_THROWS_WITH(
1871 ContainsSubstring("duplicate")
1872 );
1873 }
1874
1875 SECTION( "invalid number of targets" ) {
1876
1877 int badNumTargs = GENERATE( -1, 0 );
1878 REQUIRE_THROWS_WITH(
1880 ContainsSubstring("targets")
1881 );
1882
1883 badNumTargs = qureg.numQubits + 1;
1884 REQUIRE_THROWS_WITH(
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(
1895 ContainsSubstring("outcome")
1896 );
1897 }
1898
1899 SECTION( "improbable outcomes" ) {
1900
1901
1903 int badOutcomes[] = {0, 0, 1};
1904 REQUIRE_THROWS_WITH(
1906 ContainsSubstring("impossibly unlikely")
1907 );
1908
1909
1910 qreal badTheta = 1E-8;
1912 REQUIRE_THROWS_WITH(
1914 ContainsSubstring("impossibly unlikely")
1915 );
1916
1917
1919 qreal goodTheta = 0.1;
1921 int goodOutcomes[] = {0, 0, 1};
1922 REQUIRE(
1924 );
1925 REQUIRE_NOTHROW(
1927 );
1928
1929
1931 }
1932
1933 SECTION( "targets mismatch outcomes (C++ only)") {
1934
1935 REQUIRE_THROWS_WITH(
1937 ContainsSubstring("inconsistent")
1938 );
1939 }
1940 }
1941}
qreal calcProbOfMultiQubitOutcome(Qureg qureg, int *qubits, int *outcomes, int numQubits)
void setQuESTValidationEpsilonToDefault()
qreal getQuESTValidationEpsilon()
void setQuESTValidationEpsilon(qreal eps)
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)