226 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
229 int maxNumTargs =
calcLog2(quregVec.numAmpsPerNode);
231 SECTION(
"correctness" ) {
234 int numTargs = GENERATE_COPY( range(1,maxNumTargs+1) );
235 int* targs = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numTargs) );
239 ComplexMatrixN matr = createComplexMatrixN(numTargs);
242 SECTION(
"state-vector" ) {
244 applyGateMatrixN(quregVec, targs, numTargs, matr);
246 REQUIRE(
areEqual(quregVec, refVec) );
248 SECTION(
"density-matrix" ) {
250 applyGateMatrixN(quregMatr, targs, numTargs, matr);
252 REQUIRE(
areEqual(quregMatr, refMatr, 1E4*REAL_EPS) );
254 destroyComplexMatrixN(matr);
256 SECTION(
"input validation" ) {
258 SECTION(
"number of targets" ) {
261 int numTargs = GENERATE( -1, 0, NUM_QUBITS+1 );
262 int targs[NUM_QUBITS+1];
263 ComplexMatrixN matr = createComplexMatrixN(NUM_QUBITS+1);
266 REQUIRE_THROWS_WITH( applyGateMatrixN(quregVec, targs, numTargs, matr), ContainsSubstring(
"number of target qubits") );
267 destroyComplexMatrixN(matr);
269 SECTION(
"repetition in targets" ) {
272 int targs[] = {1,2,2};
273 ComplexMatrixN matr = createComplexMatrixN(numTargs);
276 REQUIRE_THROWS_WITH( applyGateMatrixN(quregVec, targs, numTargs, matr), ContainsSubstring(
"target") && ContainsSubstring(
"unique") );
277 destroyComplexMatrixN(matr);
279 SECTION(
"qubit indices" ) {
282 int targs[] = {1,2,3};
283 ComplexMatrixN matr = createComplexMatrixN(numTargs);
286 int inv = GENERATE( -1, NUM_QUBITS );
287 targs[GENERATE_COPY( range(0,numTargs) )] = inv;
288 REQUIRE_THROWS_WITH( applyGateMatrixN(quregVec, targs, numTargs, matr), ContainsSubstring(
"Invalid target") );
290 destroyComplexMatrixN(matr);
292 SECTION(
"matrix creation" ) {
295 int targs[] = {1,2,3};
298 matr.cpuElems = NULL;
299 REQUIRE_THROWS_WITH( applyGateMatrixN(quregVec, targs, numTargs, matr), ContainsSubstring(
"created") );
301 SECTION(
"matrix dimensions" ) {
303 int targs[2] = {1,2};
304 ComplexMatrixN matr = createComplexMatrixN(3);
307 REQUIRE_THROWS_WITH( applyGateMatrixN(quregVec, targs, 2, matr), ContainsSubstring(
"matrix has an inconsistent size"));
308 destroyComplexMatrixN(matr);
310 SECTION(
"matrix fits in node" ) {
313 quregVec.isDistributed = 1;
314 quregVec.numAmpsPerNode = 1;
315 quregVec.logNumAmpsPerNode = 0;
318 ComplexMatrixN matr = createComplexMatrixN(2);
321 REQUIRE_THROWS_WITH( applyGateMatrixN(quregVec, qb, 2, matr), ContainsSubstring(
"communication buffer") && ContainsSubstring(
"cannot simultaneously store") );
323 destroyComplexMatrixN(matr);
326 CLEANUP_TEST( quregVec, quregMatr );
337 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
339 SECTION(
"correctness" ) {
342 int numTargs = GENERATE( range(1,NUM_QUBITS+1) );
343 int* targs = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numTargs) );
346 SubDiagonalOp op = createSubDiagonalOp(numTargs);
347 for (
long long int i=0; i<op.numElems; i++)
352 SECTION(
"state-vector" ) {
354 applyGateSubDiagonalOp(quregVec, targs, numTargs, op);
356 REQUIRE(
areEqual(quregVec, refVec) );
358 SECTION(
"density-matrix" ) {
360 applyGateSubDiagonalOp(quregMatr, targs, numTargs, op);
362 REQUIRE(
areEqual(quregMatr, refMatr, 1E4*REAL_EPS) );
365 destroySubDiagonalOp(op);
367 SECTION(
"input validation" ) {
369 SECTION(
"diagonal dimension" ) {
372 SubDiagonalOp op = createSubDiagonalOp(numTargs);
375 int badNumTargs = GENERATE_COPY( numTargs-1, numTargs+1 );
376 int badTargs[NUM_QUBITS+1];
377 for (
int i=0; i<NUM_QUBITS+1; i++)
380 REQUIRE_THROWS_WITH( applyGateSubDiagonalOp(quregVec, badTargs, badNumTargs, op), ContainsSubstring(
"inconsistent size") );
381 destroySubDiagonalOp(op);
383 SECTION(
"number of targets" ) {
386 SubDiagonalOp badOp = createSubDiagonalOp(NUM_QUBITS + 1);
387 int targs[NUM_QUBITS + 1];
388 for (
int t=0; t<badOp.numQubits; t++)
390 for (
int i=0; i<badOp.numElems; i++)
391 badOp.cpuElems[i] = qcomp(1, 0);
394 REQUIRE_THROWS_WITH( applyGateSubDiagonalOp(quregVec, targs, badOp.numQubits, badOp), ContainsSubstring(
"number of target qubits") && ContainsSubstring(
"exceeds") );
395 destroySubDiagonalOp(badOp);
397 SECTION(
"repetition in targets" ) {
400 SubDiagonalOp op = createSubDiagonalOp(3);
401 for (
int i=0; i<op.numElems; i++)
402 op.cpuElems[i] = qcomp(1, 0);
406 int targs[] = {2,1,2};
408 REQUIRE_THROWS_WITH( applyGateSubDiagonalOp(quregVec, targs, op.numQubits, op), ContainsSubstring(
"target qubits contained duplicates") );
409 destroySubDiagonalOp(op);
411 SECTION(
"qubit indices" ) {
414 SubDiagonalOp op = createSubDiagonalOp(3);
415 for (
int i=0; i<op.numElems; i++)
416 op.cpuElems[i] = qcomp(1,0);
419 int targs[] = {0,1,2};
422 int badIndex = GENERATE( range(0,3) );
423 int badValue = GENERATE( -1, NUM_QUBITS );
424 targs[badIndex] = badValue;
426 REQUIRE_THROWS_WITH( applyGateSubDiagonalOp(quregVec, targs, op.numQubits, op), ContainsSubstring(
"Invalid target qubit") );
427 destroySubDiagonalOp(op);
430 CLEANUP_TEST( quregVec, quregMatr );
441 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
447 SECTION(
"correctness" ) {
449 int target = GENERATE( range(0,NUM_QUBITS) );
454 int targs[] = {target};
457 SECTION(
"state-vector" ) {
459 applyMatrix2(quregVec, target, matr);
462 REQUIRE(
areEqual(quregVec, refVec) );
464 SECTION(
"density-matrix" ) {
466 applyMatrix2(quregMatr, target, matr);
469 REQUIRE(
areEqual(quregMatr, refMatr, 10*REAL_EPS) );
472 SECTION(
"input validation" ) {
474 SECTION(
"qubit indices" ) {
476 int target = GENERATE( -1, NUM_QUBITS );
477 REQUIRE_THROWS_WITH( applyMatrix2(quregVec, target, matr), ContainsSubstring(
"Invalid target") );
480 CLEANUP_TEST( quregVec, quregMatr );
491 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
494 REQUIRE( quregVec.numAmpsPerNode >= 4 );
500 SECTION(
"correctness" ) {
502 int targ1 = GENERATE( range(0,NUM_QUBITS) );
503 int targ2 = GENERATE_COPY( filter([=](
int t){
return t!=targ1; }, range(0,NUM_QUBITS)) );
508 int targs[] = {targ1, targ2};
511 SECTION(
"state-vector" ) {
513 applyMatrix4(quregVec, targ1, targ2, matr);
515 REQUIRE(
areEqual(quregVec, refVec) );
517 SECTION(
"density-matrix" ) {
519 applyMatrix4(quregMatr, targ1, targ2, matr);
521 REQUIRE(
areEqual(quregMatr, refMatr, 10*REAL_EPS) );
524 SECTION(
"input validation" ) {
526 SECTION(
"qubit indices" ) {
528 int targ1 = GENERATE( -1, NUM_QUBITS );
530 REQUIRE_THROWS_WITH( applyMatrix4(quregVec, targ1, targ2, matr), ContainsSubstring(
"Invalid target") );
531 REQUIRE_THROWS_WITH( applyMatrix4(quregVec, targ2, targ1, matr), ContainsSubstring(
"Invalid target") );
533 SECTION(
"repetition of targets" ) {
536 REQUIRE_THROWS_WITH( applyMatrix4(quregVec, qb, qb, matr), ContainsSubstring(
"target") && ContainsSubstring(
"unique") );
538 SECTION(
"matrix fits in node" ) {
541 quregVec.isDistributed = 1;
542 quregVec.numAmpsPerNode = 1;
543 quregVec.logNumAmpsPerNode = 0;
544 REQUIRE_THROWS_WITH( applyMatrix4(quregVec, 0, 1, matr), ContainsSubstring(
"communication buffer") && ContainsSubstring(
"cannot simultaneously store") );
547 CLEANUP_TEST( quregVec, quregMatr );
558 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
561 int maxNumTargs =
calcLog2(quregVec.numAmpsPerNode);
563 SECTION(
"correctness" ) {
566 int numTargs = GENERATE_COPY( range(1,maxNumTargs+1) );
567 int* targs = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numTargs) );
571 ComplexMatrixN matr = createComplexMatrixN(numTargs);
578 SECTION(
"state-vector" ) {
580 applyMatrixN(quregVec, targs, numTargs, matr);
582 REQUIRE(
areEqual(quregVec, refVec) );
584 SECTION(
"density-matrix" ) {
586 applyMatrixN(quregMatr, targs, numTargs, matr);
588 REQUIRE(
areEqual(quregMatr, refMatr, 100*REAL_EPS) );
590 destroyComplexMatrixN(matr);
592 SECTION(
"input validation" ) {
594 SECTION(
"number of targets" ) {
597 int numTargs = GENERATE( -1, 0, NUM_QUBITS+1 );
598 int targs[NUM_QUBITS+1];
599 ComplexMatrixN matr = createComplexMatrixN(NUM_QUBITS+1);
602 REQUIRE_THROWS_WITH( applyMatrixN(quregVec, targs, numTargs, matr), ContainsSubstring(
"number of target qubits") );
603 destroyComplexMatrixN(matr);
605 SECTION(
"repetition in targets" ) {
608 int targs[] = {1,2,2};
609 ComplexMatrixN matr = createComplexMatrixN(numTargs);
612 REQUIRE_THROWS_WITH( applyMatrixN(quregVec, targs, numTargs, matr), ContainsSubstring(
"target") && ContainsSubstring(
"unique") );
613 destroyComplexMatrixN(matr);
615 SECTION(
"qubit indices" ) {
618 int targs[] = {1,2,3};
619 ComplexMatrixN matr = createComplexMatrixN(numTargs);
622 int inv = GENERATE( -1, NUM_QUBITS );
623 targs[GENERATE_COPY( range(0,numTargs) )] = inv;
624 REQUIRE_THROWS_WITH( applyMatrixN(quregVec, targs, numTargs, matr), ContainsSubstring(
"Invalid target") );
626 destroyComplexMatrixN(matr);
628 SECTION(
"matrix creation" ) {
631 int targs[] = {1,2,3};
634 matr.cpuElems = NULL;
635 REQUIRE_THROWS_WITH( applyMatrixN(quregVec, targs, numTargs, matr), ContainsSubstring(
"created") );
637 SECTION(
"matrix dimensions" ) {
639 int targs[2] = {1,2};
640 ComplexMatrixN matr = createComplexMatrixN(3);
643 REQUIRE_THROWS_WITH( applyMatrixN(quregVec, targs, 2, matr), ContainsSubstring(
"matrix has an inconsistent size") );
644 destroyComplexMatrixN(matr);
646 SECTION(
"matrix fits in node" ) {
649 quregVec.isDistributed = 1;
650 quregVec.numAmpsPerNode = 1;
651 quregVec.logNumAmpsPerNode = 0;
653 ComplexMatrixN matr = createComplexMatrixN(2);
656 REQUIRE_THROWS_WITH( applyMatrixN(quregVec, qb, 2, matr), ContainsSubstring(
"communication buffer") && ContainsSubstring(
"cannot simultaneously store") );
658 destroyComplexMatrixN(matr);
661 CLEANUP_TEST( quregVec, quregMatr );
670TEST_CASE(
"applyMultiControlledGateMatrixN",
"[operators]" ) {
672 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
675 int maxNumTargs =
calcLog2(quregVec.numAmpsPerNode);
676 if (maxNumTargs >= NUM_QUBITS)
677 maxNumTargs = NUM_QUBITS - 1;
679 SECTION(
"correctness" ) {
682 int numTargs = GENERATE_COPY( range(1,maxNumTargs+1) );
683 int maxNumCtrls = NUM_QUBITS - numTargs;
684 int numCtrls = GENERATE_COPY( range(1,maxNumCtrls+1) );
687 int* targs = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numTargs) );
688 int* ctrls = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numCtrls, targs, numTargs) );
692 ComplexMatrixN matr = createComplexMatrixN(numTargs);
695 SECTION(
"state-vector" ) {
697 applyMultiControlledGateMatrixN(quregVec, ctrls, numCtrls, targs, numTargs, matr);
699 REQUIRE(
areEqual(quregVec, refVec) );
701 SECTION(
"density-matrix" ) {
703 applyMultiControlledGateMatrixN(quregMatr, ctrls, numCtrls, targs, numTargs, matr);
705 REQUIRE(
areEqual(quregMatr, refMatr, 1E4*REAL_EPS) );
707 destroyComplexMatrixN(matr);
709 SECTION(
"input validation" ) {
711 SECTION(
"number of targets" ) {
715 int numTargs = GENERATE( -1, 0, NUM_QUBITS+1 );
716 int targs[NUM_QUBITS+1];
718 ComplexMatrixN matr = createComplexMatrixN(NUM_QUBITS+1);
721 REQUIRE_THROWS_WITH( applyMultiControlledGateMatrixN(quregVec, ctrls, 1, targs, numTargs, matr), ContainsSubstring(
"number of target qubits") );
722 destroyComplexMatrixN(matr);
724 SECTION(
"repetition in targets" ) {
728 int targs[] = {1,2,2};
729 ComplexMatrixN matr = createComplexMatrixN(numTargs);
732 REQUIRE_THROWS_WITH( applyMultiControlledGateMatrixN(quregVec, ctrls, 1, targs, numTargs, matr), ContainsSubstring(
"target") && ContainsSubstring(
"unique"));
733 destroyComplexMatrixN(matr);
735 SECTION(
"number of controls" ) {
737 int numCtrls = GENERATE( -1, NUM_QUBITS+1 );
738 int ctrls[NUM_QUBITS+1];
740 ComplexMatrixN matr = createComplexMatrixN(1);
743 REQUIRE_THROWS_WITH( applyMultiControlledGateMatrixN(quregVec, ctrls, numCtrls, targs, 1, matr), ContainsSubstring(
"number of control qubits") );
744 destroyComplexMatrixN(matr);
746 SECTION(
"repetition in controls" ) {
748 int ctrls[] = {0,1,1};
750 ComplexMatrixN matr = createComplexMatrixN(1);
753 REQUIRE_THROWS_WITH( applyMultiControlledGateMatrixN(quregVec, ctrls, 3, targs, 1, matr), ContainsSubstring(
"control") && ContainsSubstring(
"unique") );
754 destroyComplexMatrixN(matr);
756 SECTION(
"control and target collision" ) {
759 int targs[] = {3,1,0};
760 ComplexMatrixN matr = createComplexMatrixN(3);
763 REQUIRE_THROWS_WITH( applyMultiControlledGateMatrixN(quregVec, ctrls, 1, targs, 3, matr), ContainsSubstring(
"control and target qubits") );
764 destroyComplexMatrixN(matr);
766 SECTION(
"qubit indices" ) {
772 ComplexMatrixN matr = createComplexMatrixN(numQb);
776 int inv = GENERATE( -1, NUM_QUBITS );
777 qb1[GENERATE_COPY(range(0,numQb))] = inv;
779 REQUIRE_THROWS_WITH( applyMultiControlledGateMatrixN(quregVec, qb1, numQb, qb2, numQb, matr), ContainsSubstring(
"Invalid control") );
780 REQUIRE_THROWS_WITH( applyMultiControlledGateMatrixN(quregVec, qb2, numQb, qb1, numQb, matr), ContainsSubstring(
"Invalid target") );
781 destroyComplexMatrixN(matr);
783 SECTION(
"matrix creation" ) {
786 int targs[3] = {1,2,3};
789 matr.cpuElems = NULL;
790 REQUIRE_THROWS_WITH( applyMultiControlledGateMatrixN(quregVec, ctrls, 1, targs, 3, matr), ContainsSubstring(
"created") );
792 SECTION(
"matrix dimensions" ) {
795 int targs[2] = {1,2};
796 ComplexMatrixN matr = createComplexMatrixN(3);
799 REQUIRE_THROWS_WITH( applyMultiControlledGateMatrixN(quregVec, ctrls, 1, targs, 2, matr), ContainsSubstring(
"matrix has an inconsistent size"));
800 destroyComplexMatrixN(matr);
802 SECTION(
"matrix fits in node" ) {
805 quregVec.isDistributed = 1;
806 quregVec.numAmpsPerNode = 1;
807 quregVec.logNumAmpsPerNode = 0;
809 int targs[2] = {1,2};
810 ComplexMatrixN matr = createComplexMatrixN(2);
813 REQUIRE_THROWS_WITH( applyMultiControlledGateMatrixN(quregVec, ctrls, 1, targs, 2, matr), ContainsSubstring(
"communication buffer") && ContainsSubstring(
"cannot simultaneously store") );
814 destroyComplexMatrixN(matr);
817 CLEANUP_TEST( quregVec, quregMatr );
3776 SECTION(
"correctness" ) {
3778 int qubit = GENERATE( range(0,NUM_QUBITS) );
3779 int outcome = GENERATE( 0, 1 );
3782 GENERATE( range(0,10) );
3784 SECTION(
"state-vector" ) {
3786 SECTION(
"normalised" ) {
3793 for (
size_t ind=0; ind<vecRef.size(); ind++) {
3794 int bit = (ind >> qubit) & 1;
3799 applyProjector(vec, qubit, outcome);
3802 SECTION(
"unnormalised" ) {
3809 for (
size_t ind=0; ind<vecRef.size(); ind++) {
3810 int bit = (ind >> qubit) & 1;
3815 applyProjector(vec, qubit, outcome);
3819 SECTION(
"density-matrix" ) {
3827 applyProjector(mat, qubit, outcome);
3830 for (
size_t r=0; r<matRef.size(); r++) {
3831 for (
size_t c=0; c<matRef.size(); c++) {
3832 int ketBit = (c >> qubit) & 1;
3833 int braBit = (r >> qubit) & 1;
3834 if (!(ketBit == outcome && braBit == outcome))
3841 SECTION(
"mixed" ) {
3846 applyProjector(mat, qubit, outcome);
3849 for (
size_t r=0; r<matRef.size(); r++) {
3850 for (
size_t c=0; c<matRef.size(); c++) {
3851 int ketBit = (c >> qubit) & 1;
3852 int braBit = (r >> qubit) & 1;
3853 if (!(ketBit == outcome && braBit == outcome))
3860 SECTION(
"unnormalised" ) {
3865 applyProjector(mat, qubit, outcome);
3868 for (
size_t r=0; r<matRef.size(); r++) {
3869 for (
size_t c=0; c<matRef.size(); c++) {
3870 int ketBit = (c >> qubit) & 1;
3871 int braBit = (r >> qubit) & 1;
3872 if (!(ketBit == outcome && braBit == outcome))
3881 SECTION(
"input validation" ) {
3883 SECTION(
"qubit index" ) {
3885 int qubit = GENERATE( -1, NUM_QUBITS );
3887 REQUIRE_THROWS_WITH( applyProjector(mat, qubit, outcome), ContainsSubstring(
"Invalid target qubit") );
3889 SECTION(
"outcome value" ) {
3892 int outcome = GENERATE( -1, 2 );
3893 REQUIRE_THROWS_WITH( applyProjector(mat, qubit, outcome), ContainsSubstring(
"measurement outcome") && ContainsSubstring(
"is invalid") );
3908 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
3910 SECTION(
"correctness" ) {
3913 int numQubits = GENERATE_COPY( range(1,NUM_QUBITS+1) );
3916 int* qubits = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numQubits) );
3918 SECTION(
"state-vector" ) {
3920 SECTION(
"normalised" ) {
3925 applyQFT(quregVec, qubits, numQubits);
3926 refVec =
getDFT(refVec, qubits, numQubits);
3928 REQUIRE(
areEqual(quregVec, refVec) );
3930 SECTION(
"unnormalised" ) {
3935 applyQFT(quregVec, qubits, numQubits);
3936 refVec =
getDFT(refVec, qubits, numQubits);
3938 REQUIRE(
areEqual(quregVec, refVec) );
3941 SECTION(
"density-matrix" ) {
3953 applyQFT(quregMatr, qubits, numQubits);
3954 refVec =
getDFT(refVec, qubits, numQubits);
3957 REQUIRE(
areEqual(quregMatr, refMatr) );
3959 SECTION(
"mixed" ) {
3967 int numStates = (1 << NUM_QUBITS)/4;
3968 std::vector<QVector> states = getRandomOrthonormalVectors(NUM_QUBITS, numStates);
3976 applyQFT(quregMatr, qubits, numQubits);
3980 for (
int i=0; i<numStates; i++) {
3985 REQUIRE(
areEqual(quregMatr, refMatr) );
3987 SECTION(
"unnormalised" ) {
3994 int numVecs = (1 << NUM_QUBITS)/4;
3995 std::vector<QVector> vecs;
3996 std::vector<qcomp> coeffs;
3997 for (
int i=0; i<numVecs; i++) {
4004 for (
int i=0; i<numVecs; i++)
4008 applyQFT(quregMatr, qubits, numQubits);
4012 for (
int i=0; i<numVecs; i++) {
4017 REQUIRE(
areEqual(quregMatr, refMatr) );
4021 SECTION(
"input validation" ) {
4023 SECTION(
"number of targets" ) {
4026 int numQubits = GENERATE( -1, 0);
4027 int qubits[NUM_QUBITS+1];
4029 REQUIRE_THROWS_WITH( applyQFT(quregVec, qubits, numQubits), ContainsSubstring(
"number of target qubits") && ContainsSubstring(
"invalid") );
4030 REQUIRE_THROWS_WITH( applyQFT(quregVec, qubits, NUM_QUBITS+1), ContainsSubstring(
"number of target qubits") && ContainsSubstring(
"exceeds") && ContainsSubstring(
"Qureg") );
4033 SECTION(
"repetition in targets" ) {
4036 int qubits[] = {1,2,2};
4038 REQUIRE_THROWS_WITH( applyQFT(quregVec, qubits, numQubits), ContainsSubstring(
"target") && ContainsSubstring(
"unique") );
4040 SECTION(
"qubit indices" ) {
4043 int qubits[] = {1,2,3};
4045 int inv = GENERATE( -1, NUM_QUBITS );
4046 qubits[GENERATE_COPY( range(0,numQubits) )] = inv;
4047 REQUIRE_THROWS_WITH( applyQFT(quregVec, qubits, numQubits), ContainsSubstring(
"Invalid target") );
4050 CLEANUP_TEST( quregVec, quregMatr );
4061 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
4063 SECTION(
"correctness" ) {
4066 int numTargs = GENERATE( range(1,NUM_QUBITS+1) );
4067 int* targs = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numTargs) );
4070 SubDiagonalOp op = createSubDiagonalOp(numTargs);
4071 for (
long long int i=0; i<op.numElems; i++)
4077 SECTION(
"state-vector" ) {
4079 applySubDiagonalOp(quregVec, targs, numTargs, op);
4081 REQUIRE(
areEqual(quregVec, refVec) );
4083 SECTION(
"density-matrix" ) {
4085 applySubDiagonalOp(quregMatr, targs, numTargs, op);
4087 REQUIRE(
areEqual(quregMatr, refMatr, 100*REAL_EPS) );
4090 destroySubDiagonalOp(op);
4092 SECTION(
"input validation" ) {
4094 SECTION(
"diagonal dimension" ) {
4097 SubDiagonalOp op = createSubDiagonalOp(numTargs);
4100 int badNumTargs = GENERATE_COPY( numTargs-1, numTargs+1 );
4101 int badTargs[NUM_QUBITS+1];
4102 for (
int i=0; i<NUM_QUBITS+1; i++)
4105 REQUIRE_THROWS_WITH( applySubDiagonalOp(quregVec, badTargs, badNumTargs, op), ContainsSubstring(
"inconsistent size") );
4106 destroySubDiagonalOp(op);
4108 SECTION(
"number of targets" ) {
4111 SubDiagonalOp badOp = createSubDiagonalOp(NUM_QUBITS + 1);
4112 int targs[NUM_QUBITS + 1];
4113 for (
int t=0; t<badOp.numQubits; t++)
4115 for (
int i=0; i<badOp.numElems; i++)
4116 badOp.cpuElems[i] = qcomp(1,0);
4119 REQUIRE_THROWS_WITH( applySubDiagonalOp(quregVec, targs, badOp.numQubits, badOp), ContainsSubstring(
"number of target qubits") && ContainsSubstring(
"exceeds") );
4120 destroySubDiagonalOp(badOp);
4122 SECTION(
"repetition in targets" ) {
4125 SubDiagonalOp op = createSubDiagonalOp(3);
4126 for (
int i=0; i<op.numElems; i++)
4127 op.cpuElems[i] = qcomp(1,0);
4131 int targs[] = {2,1,2};
4133 REQUIRE_THROWS_WITH( applySubDiagonalOp(quregVec, targs, op.numQubits, op), ContainsSubstring(
"target qubits contained duplicates") );
4134 destroySubDiagonalOp(op);
4136 SECTION(
"qubit indices" ) {
4139 SubDiagonalOp op = createSubDiagonalOp(3);
4140 for (
int i=0; i<op.numElems; i++)
4141 op.cpuElems[i] = qcomp(1,0);
4144 int targs[] = {0,1,2};
4147 int badIndex = GENERATE( range(0,3) );
4148 int badValue = GENERATE( -1, NUM_QUBITS );
4149 targs[badIndex] = badValue;
4151 REQUIRE_THROWS_WITH( applySubDiagonalOp(quregVec, targs, op.numQubits, op), ContainsSubstring(
"Invalid target qubit") );
4152 destroySubDiagonalOp(op);
4155 CLEANUP_TEST( quregVec, quregMatr );