220 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
223 int maxNumTargs =
calcLog2(quregVec.numAmpsPerNode);
225 SECTION(
"correctness" ) {
228 int numTargs = GENERATE_COPY( range(1,maxNumTargs+1) );
229 int* targs = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numTargs) );
233 ComplexMatrixN matr = createComplexMatrixN(numTargs);
236 SECTION(
"state-vector" ) {
238 applyGateMatrixN(quregVec, targs, numTargs, matr);
240 REQUIRE(
areEqual(quregVec, refVec) );
242 SECTION(
"density-matrix" ) {
244 applyGateMatrixN(quregMatr, targs, numTargs, matr);
246 REQUIRE(
areEqual(quregMatr, refMatr, 1E4*REAL_EPS) );
248 destroyComplexMatrixN(matr);
250 SECTION(
"input validation" ) {
252 SECTION(
"number of targets" ) {
255 int numTargs = GENERATE( -1, 0, NUM_QUBITS+1 );
256 int targs[NUM_QUBITS+1];
257 ComplexMatrixN matr = createComplexMatrixN(NUM_QUBITS+1);
260 REQUIRE_THROWS_WITH( applyGateMatrixN(quregVec, targs, numTargs, matr), ContainsSubstring(
"number of target qubits") );
261 destroyComplexMatrixN(matr);
263 SECTION(
"repetition in targets" ) {
266 int targs[] = {1,2,2};
267 ComplexMatrixN matr = createComplexMatrixN(numTargs);
270 REQUIRE_THROWS_WITH( applyGateMatrixN(quregVec, targs, numTargs, matr), ContainsSubstring(
"target") && ContainsSubstring(
"unique") );
271 destroyComplexMatrixN(matr);
273 SECTION(
"qubit indices" ) {
276 int targs[] = {1,2,3};
277 ComplexMatrixN matr = createComplexMatrixN(numTargs);
280 int inv = GENERATE( -1, NUM_QUBITS );
281 targs[GENERATE_COPY( range(0,numTargs) )] = inv;
282 REQUIRE_THROWS_WITH( applyGateMatrixN(quregVec, targs, numTargs, matr), ContainsSubstring(
"Invalid target") );
284 destroyComplexMatrixN(matr);
286 SECTION(
"matrix creation" ) {
289 int targs[] = {1,2,3};
292 matr.cpuElems = NULL;
293 REQUIRE_THROWS_WITH( applyGateMatrixN(quregVec, targs, numTargs, matr), ContainsSubstring(
"created") );
295 SECTION(
"matrix dimensions" ) {
297 int targs[2] = {1,2};
298 ComplexMatrixN matr = createComplexMatrixN(3);
301 REQUIRE_THROWS_WITH( applyGateMatrixN(quregVec, targs, 2, matr), ContainsSubstring(
"matrix has an inconsistent size"));
302 destroyComplexMatrixN(matr);
304 SECTION(
"matrix fits in node" ) {
307 quregVec.isDistributed = 1;
308 quregVec.numAmpsPerNode = 1;
309 quregVec.logNumAmpsPerNode = 0;
312 ComplexMatrixN matr = createComplexMatrixN(2);
315 REQUIRE_THROWS_WITH( applyGateMatrixN(quregVec, qb, 2, matr), ContainsSubstring(
"communication buffer") && ContainsSubstring(
"cannot simultaneously store") );
317 destroyComplexMatrixN(matr);
320 CLEANUP_TEST( quregVec, quregMatr );
331 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
333 SECTION(
"correctness" ) {
336 int numTargs = GENERATE( range(1,NUM_QUBITS+1) );
337 int* targs = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numTargs) );
340 SubDiagonalOp op = createSubDiagonalOp(numTargs);
341 for (
long long int i=0; i<op.numElems; i++)
346 SECTION(
"state-vector" ) {
348 applyGateSubDiagonalOp(quregVec, targs, numTargs, op);
350 REQUIRE(
areEqual(quregVec, refVec) );
352 SECTION(
"density-matrix" ) {
354 applyGateSubDiagonalOp(quregMatr, targs, numTargs, op);
356 REQUIRE(
areEqual(quregMatr, refMatr, 1E4*REAL_EPS) );
359 destroySubDiagonalOp(op);
361 SECTION(
"input validation" ) {
363 SECTION(
"diagonal dimension" ) {
366 SubDiagonalOp op = createSubDiagonalOp(numTargs);
369 int badNumTargs = GENERATE_COPY( numTargs-1, numTargs+1 );
370 int badTargs[NUM_QUBITS+1];
371 for (
int i=0; i<NUM_QUBITS+1; i++)
374 REQUIRE_THROWS_WITH( applyGateSubDiagonalOp(quregVec, badTargs, badNumTargs, op), ContainsSubstring(
"inconsistent size") );
375 destroySubDiagonalOp(op);
377 SECTION(
"number of targets" ) {
380 SubDiagonalOp badOp = createSubDiagonalOp(NUM_QUBITS + 1);
381 int targs[NUM_QUBITS + 1];
382 for (
int t=0; t<badOp.numQubits; t++)
384 for (
int i=0; i<badOp.numElems; i++)
385 badOp.cpuElems[i] = qcomp(1, 0);
388 REQUIRE_THROWS_WITH( applyGateSubDiagonalOp(quregVec, targs, badOp.numQubits, badOp), ContainsSubstring(
"number of target qubits") && ContainsSubstring(
"exceeds") );
389 destroySubDiagonalOp(badOp);
391 SECTION(
"repetition in targets" ) {
394 SubDiagonalOp op = createSubDiagonalOp(3);
395 for (
int i=0; i<op.numElems; i++)
396 op.cpuElems[i] = qcomp(1, 0);
400 int targs[] = {2,1,2};
402 REQUIRE_THROWS_WITH( applyGateSubDiagonalOp(quregVec, targs, op.numQubits, op), ContainsSubstring(
"target qubits contained duplicates") );
403 destroySubDiagonalOp(op);
405 SECTION(
"qubit indices" ) {
408 SubDiagonalOp op = createSubDiagonalOp(3);
409 for (
int i=0; i<op.numElems; i++)
410 op.cpuElems[i] = qcomp(1,0);
413 int targs[] = {0,1,2};
416 int badIndex = GENERATE( range(0,3) );
417 int badValue = GENERATE( -1, NUM_QUBITS );
418 targs[badIndex] = badValue;
420 REQUIRE_THROWS_WITH( applyGateSubDiagonalOp(quregVec, targs, op.numQubits, op), ContainsSubstring(
"Invalid target qubit") );
421 destroySubDiagonalOp(op);
424 CLEANUP_TEST( quregVec, quregMatr );
435 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
441 SECTION(
"correctness" ) {
443 int target = GENERATE( range(0,NUM_QUBITS) );
448 int targs[] = {target};
451 SECTION(
"state-vector" ) {
453 applyMatrix2(quregVec, target, matr);
456 REQUIRE(
areEqual(quregVec, refVec) );
458 SECTION(
"density-matrix" ) {
460 applyMatrix2(quregMatr, target, matr);
463 REQUIRE(
areEqual(quregMatr, refMatr, 10*REAL_EPS) );
466 SECTION(
"input validation" ) {
468 SECTION(
"qubit indices" ) {
470 int target = GENERATE( -1, NUM_QUBITS );
471 REQUIRE_THROWS_WITH( applyMatrix2(quregVec, target, matr), ContainsSubstring(
"Invalid target") );
474 CLEANUP_TEST( quregVec, quregMatr );
485 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
488 REQUIRE( quregVec.numAmpsPerNode >= 4 );
494 SECTION(
"correctness" ) {
496 int targ1 = GENERATE( range(0,NUM_QUBITS) );
497 int targ2 = GENERATE_COPY( filter([=](
int t){
return t!=targ1; }, range(0,NUM_QUBITS)) );
502 int targs[] = {targ1, targ2};
505 SECTION(
"state-vector" ) {
507 applyMatrix4(quregVec, targ1, targ2, matr);
509 REQUIRE(
areEqual(quregVec, refVec) );
511 SECTION(
"density-matrix" ) {
513 applyMatrix4(quregMatr, targ1, targ2, matr);
515 REQUIRE(
areEqual(quregMatr, refMatr, 10*REAL_EPS) );
518 SECTION(
"input validation" ) {
520 SECTION(
"qubit indices" ) {
522 int targ1 = GENERATE( -1, NUM_QUBITS );
524 REQUIRE_THROWS_WITH( applyMatrix4(quregVec, targ1, targ2, matr), ContainsSubstring(
"Invalid target") );
525 REQUIRE_THROWS_WITH( applyMatrix4(quregVec, targ2, targ1, matr), ContainsSubstring(
"Invalid target") );
527 SECTION(
"repetition of targets" ) {
530 REQUIRE_THROWS_WITH( applyMatrix4(quregVec, qb, qb, matr), ContainsSubstring(
"target") && ContainsSubstring(
"unique") );
532 SECTION(
"matrix fits in node" ) {
535 quregVec.isDistributed = 1;
536 quregVec.numAmpsPerNode = 1;
537 quregVec.logNumAmpsPerNode = 0;
538 REQUIRE_THROWS_WITH( applyMatrix4(quregVec, 0, 1, matr), ContainsSubstring(
"communication buffer") && ContainsSubstring(
"cannot simultaneously store") );
541 CLEANUP_TEST( quregVec, quregMatr );
552 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
555 int maxNumTargs =
calcLog2(quregVec.numAmpsPerNode);
557 SECTION(
"correctness" ) {
560 int numTargs = GENERATE_COPY( range(1,maxNumTargs+1) );
561 int* targs = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numTargs) );
565 ComplexMatrixN matr = createComplexMatrixN(numTargs);
572 SECTION(
"state-vector" ) {
574 applyMatrixN(quregVec, targs, numTargs, matr);
576 REQUIRE(
areEqual(quregVec, refVec) );
578 SECTION(
"density-matrix" ) {
580 applyMatrixN(quregMatr, targs, numTargs, matr);
582 REQUIRE(
areEqual(quregMatr, refMatr, 100*REAL_EPS) );
584 destroyComplexMatrixN(matr);
586 SECTION(
"input validation" ) {
588 SECTION(
"number of targets" ) {
591 int numTargs = GENERATE( -1, 0, NUM_QUBITS+1 );
592 int targs[NUM_QUBITS+1];
593 ComplexMatrixN matr = createComplexMatrixN(NUM_QUBITS+1);
596 REQUIRE_THROWS_WITH( applyMatrixN(quregVec, targs, numTargs, matr), ContainsSubstring(
"number of target qubits") );
597 destroyComplexMatrixN(matr);
599 SECTION(
"repetition in targets" ) {
602 int targs[] = {1,2,2};
603 ComplexMatrixN matr = createComplexMatrixN(numTargs);
606 REQUIRE_THROWS_WITH( applyMatrixN(quregVec, targs, numTargs, matr), ContainsSubstring(
"target") && ContainsSubstring(
"unique") );
607 destroyComplexMatrixN(matr);
609 SECTION(
"qubit indices" ) {
612 int targs[] = {1,2,3};
613 ComplexMatrixN matr = createComplexMatrixN(numTargs);
616 int inv = GENERATE( -1, NUM_QUBITS );
617 targs[GENERATE_COPY( range(0,numTargs) )] = inv;
618 REQUIRE_THROWS_WITH( applyMatrixN(quregVec, targs, numTargs, matr), ContainsSubstring(
"Invalid target") );
620 destroyComplexMatrixN(matr);
622 SECTION(
"matrix creation" ) {
625 int targs[] = {1,2,3};
628 matr.cpuElems = NULL;
629 REQUIRE_THROWS_WITH( applyMatrixN(quregVec, targs, numTargs, matr), ContainsSubstring(
"created") );
631 SECTION(
"matrix dimensions" ) {
633 int targs[2] = {1,2};
634 ComplexMatrixN matr = createComplexMatrixN(3);
637 REQUIRE_THROWS_WITH( applyMatrixN(quregVec, targs, 2, matr), ContainsSubstring(
"matrix has an inconsistent size") );
638 destroyComplexMatrixN(matr);
640 SECTION(
"matrix fits in node" ) {
643 quregVec.isDistributed = 1;
644 quregVec.numAmpsPerNode = 1;
645 quregVec.logNumAmpsPerNode = 0;
647 ComplexMatrixN matr = createComplexMatrixN(2);
650 REQUIRE_THROWS_WITH( applyMatrixN(quregVec, qb, 2, matr), ContainsSubstring(
"communication buffer") && ContainsSubstring(
"cannot simultaneously store") );
652 destroyComplexMatrixN(matr);
655 CLEANUP_TEST( quregVec, quregMatr );
664TEST_CASE(
"applyMultiControlledGateMatrixN",
"[operators]" ) {
666 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
669 int maxNumTargs =
calcLog2(quregVec.numAmpsPerNode);
670 if (maxNumTargs >= NUM_QUBITS)
671 maxNumTargs = NUM_QUBITS - 1;
673 SECTION(
"correctness" ) {
676 int numTargs = GENERATE_COPY( range(1,maxNumTargs+1) );
677 int maxNumCtrls = NUM_QUBITS - numTargs;
678 int numCtrls = GENERATE_COPY( range(1,maxNumCtrls+1) );
681 int* targs = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numTargs) );
682 int* ctrls = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numCtrls, targs, numTargs) );
686 ComplexMatrixN matr = createComplexMatrixN(numTargs);
689 SECTION(
"state-vector" ) {
691 applyMultiControlledGateMatrixN(quregVec, ctrls, numCtrls, targs, numTargs, matr);
693 REQUIRE(
areEqual(quregVec, refVec) );
695 SECTION(
"density-matrix" ) {
697 applyMultiControlledGateMatrixN(quregMatr, ctrls, numCtrls, targs, numTargs, matr);
699 REQUIRE(
areEqual(quregMatr, refMatr, 1E4*REAL_EPS) );
701 destroyComplexMatrixN(matr);
703 SECTION(
"input validation" ) {
705 SECTION(
"number of targets" ) {
709 int numTargs = GENERATE( -1, 0, NUM_QUBITS+1 );
710 int targs[NUM_QUBITS+1];
712 ComplexMatrixN matr = createComplexMatrixN(NUM_QUBITS+1);
715 REQUIRE_THROWS_WITH( applyMultiControlledGateMatrixN(quregVec, ctrls, 1, targs, numTargs, matr), ContainsSubstring(
"number of target qubits") );
716 destroyComplexMatrixN(matr);
718 SECTION(
"repetition in targets" ) {
722 int targs[] = {1,2,2};
723 ComplexMatrixN matr = createComplexMatrixN(numTargs);
726 REQUIRE_THROWS_WITH( applyMultiControlledGateMatrixN(quregVec, ctrls, 1, targs, numTargs, matr), ContainsSubstring(
"target") && ContainsSubstring(
"unique"));
727 destroyComplexMatrixN(matr);
729 SECTION(
"number of controls" ) {
731 int numCtrls = GENERATE( -1, NUM_QUBITS+1 );
732 int ctrls[NUM_QUBITS+1];
734 ComplexMatrixN matr = createComplexMatrixN(1);
737 REQUIRE_THROWS_WITH( applyMultiControlledGateMatrixN(quregVec, ctrls, numCtrls, targs, 1, matr), ContainsSubstring(
"number of control qubits") );
738 destroyComplexMatrixN(matr);
740 SECTION(
"repetition in controls" ) {
742 int ctrls[] = {0,1,1};
744 ComplexMatrixN matr = createComplexMatrixN(1);
747 REQUIRE_THROWS_WITH( applyMultiControlledGateMatrixN(quregVec, ctrls, 3, targs, 1, matr), ContainsSubstring(
"control") && ContainsSubstring(
"unique") );
748 destroyComplexMatrixN(matr);
750 SECTION(
"control and target collision" ) {
753 int targs[] = {3,1,0};
754 ComplexMatrixN matr = createComplexMatrixN(3);
757 REQUIRE_THROWS_WITH( applyMultiControlledGateMatrixN(quregVec, ctrls, 1, targs, 3, matr), ContainsSubstring(
"control and target qubits") );
758 destroyComplexMatrixN(matr);
760 SECTION(
"qubit indices" ) {
766 ComplexMatrixN matr = createComplexMatrixN(numQb);
770 int inv = GENERATE( -1, NUM_QUBITS );
771 qb1[GENERATE_COPY(range(0,numQb))] = inv;
773 REQUIRE_THROWS_WITH( applyMultiControlledGateMatrixN(quregVec, qb1, numQb, qb2, numQb, matr), ContainsSubstring(
"Invalid control") );
774 REQUIRE_THROWS_WITH( applyMultiControlledGateMatrixN(quregVec, qb2, numQb, qb1, numQb, matr), ContainsSubstring(
"Invalid target") );
775 destroyComplexMatrixN(matr);
777 SECTION(
"matrix creation" ) {
780 int targs[3] = {1,2,3};
783 matr.cpuElems = NULL;
784 REQUIRE_THROWS_WITH( applyMultiControlledGateMatrixN(quregVec, ctrls, 1, targs, 3, matr), ContainsSubstring(
"created") );
786 SECTION(
"matrix dimensions" ) {
789 int targs[2] = {1,2};
790 ComplexMatrixN matr = createComplexMatrixN(3);
793 REQUIRE_THROWS_WITH( applyMultiControlledGateMatrixN(quregVec, ctrls, 1, targs, 2, matr), ContainsSubstring(
"matrix has an inconsistent size"));
794 destroyComplexMatrixN(matr);
796 SECTION(
"matrix fits in node" ) {
799 quregVec.isDistributed = 1;
800 quregVec.numAmpsPerNode = 1;
801 quregVec.logNumAmpsPerNode = 0;
803 int targs[2] = {1,2};
804 ComplexMatrixN matr = createComplexMatrixN(2);
807 REQUIRE_THROWS_WITH( applyMultiControlledGateMatrixN(quregVec, ctrls, 1, targs, 2, matr), ContainsSubstring(
"communication buffer") && ContainsSubstring(
"cannot simultaneously store") );
808 destroyComplexMatrixN(matr);
811 CLEANUP_TEST( quregVec, quregMatr );
3770 SECTION(
"correctness" ) {
3772 int qubit = GENERATE( range(0,NUM_QUBITS) );
3773 int outcome = GENERATE( 0, 1 );
3776 GENERATE( range(0,10) );
3778 SECTION(
"state-vector" ) {
3780 SECTION(
"normalised" ) {
3787 for (
size_t ind=0; ind<vecRef.size(); ind++) {
3788 int bit = (ind >> qubit) & 1;
3793 applyProjector(vec, qubit, outcome);
3796 SECTION(
"unnormalised" ) {
3803 for (
size_t ind=0; ind<vecRef.size(); ind++) {
3804 int bit = (ind >> qubit) & 1;
3809 applyProjector(vec, qubit, outcome);
3813 SECTION(
"density-matrix" ) {
3821 applyProjector(mat, qubit, outcome);
3824 for (
size_t r=0; r<matRef.size(); r++) {
3825 for (
size_t c=0; c<matRef.size(); c++) {
3826 int ketBit = (c >> qubit) & 1;
3827 int braBit = (r >> qubit) & 1;
3828 if (!(ketBit == outcome && braBit == outcome))
3835 SECTION(
"mixed" ) {
3840 applyProjector(mat, qubit, outcome);
3843 for (
size_t r=0; r<matRef.size(); r++) {
3844 for (
size_t c=0; c<matRef.size(); c++) {
3845 int ketBit = (c >> qubit) & 1;
3846 int braBit = (r >> qubit) & 1;
3847 if (!(ketBit == outcome && braBit == outcome))
3854 SECTION(
"unnormalised" ) {
3859 applyProjector(mat, qubit, outcome);
3862 for (
size_t r=0; r<matRef.size(); r++) {
3863 for (
size_t c=0; c<matRef.size(); c++) {
3864 int ketBit = (c >> qubit) & 1;
3865 int braBit = (r >> qubit) & 1;
3866 if (!(ketBit == outcome && braBit == outcome))
3875 SECTION(
"input validation" ) {
3877 SECTION(
"qubit index" ) {
3879 int qubit = GENERATE( -1, NUM_QUBITS );
3881 REQUIRE_THROWS_WITH( applyProjector(mat, qubit, outcome), ContainsSubstring(
"Invalid target qubit") );
3883 SECTION(
"outcome value" ) {
3886 int outcome = GENERATE( -1, 2 );
3887 REQUIRE_THROWS_WITH( applyProjector(mat, qubit, outcome), ContainsSubstring(
"measurement outcome") && ContainsSubstring(
"is invalid") );
3902 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
3904 SECTION(
"correctness" ) {
3907 int numQubits = GENERATE_COPY( range(1,NUM_QUBITS+1) );
3910 int* qubits = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numQubits) );
3912 SECTION(
"state-vector" ) {
3914 SECTION(
"normalised" ) {
3919 applyQFT(quregVec, qubits, numQubits);
3920 refVec =
getDFT(refVec, qubits, numQubits);
3922 REQUIRE(
areEqual(quregVec, refVec) );
3924 SECTION(
"unnormalised" ) {
3929 applyQFT(quregVec, qubits, numQubits);
3930 refVec =
getDFT(refVec, qubits, numQubits);
3932 REQUIRE(
areEqual(quregVec, refVec) );
3935 SECTION(
"density-matrix" ) {
3947 applyQFT(quregMatr, qubits, numQubits);
3948 refVec =
getDFT(refVec, qubits, numQubits);
3951 REQUIRE(
areEqual(quregMatr, refMatr) );
3953 SECTION(
"mixed" ) {
3961 int numStates = (1 << NUM_QUBITS)/4;
3962 std::vector<QVector> states = getRandomOrthonormalVectors(NUM_QUBITS, numStates);
3970 applyQFT(quregMatr, qubits, numQubits);
3974 for (
int i=0; i<numStates; i++) {
3979 REQUIRE(
areEqual(quregMatr, refMatr) );
3981 SECTION(
"unnormalised" ) {
3988 int numVecs = (1 << NUM_QUBITS)/4;
3989 std::vector<QVector> vecs;
3990 std::vector<qcomp> coeffs;
3991 for (
int i=0; i<numVecs; i++) {
3998 for (
int i=0; i<numVecs; i++)
4002 applyQFT(quregMatr, qubits, numQubits);
4006 for (
int i=0; i<numVecs; i++) {
4011 REQUIRE(
areEqual(quregMatr, refMatr) );
4015 SECTION(
"input validation" ) {
4017 SECTION(
"number of targets" ) {
4020 int numQubits = GENERATE( -1, 0);
4021 int qubits[NUM_QUBITS+1];
4023 REQUIRE_THROWS_WITH( applyQFT(quregVec, qubits, numQubits), ContainsSubstring(
"number of target qubits") && ContainsSubstring(
"invalid") );
4024 REQUIRE_THROWS_WITH( applyQFT(quregVec, qubits, NUM_QUBITS+1), ContainsSubstring(
"number of target qubits") && ContainsSubstring(
"exceeds") && ContainsSubstring(
"Qureg") );
4027 SECTION(
"repetition in targets" ) {
4030 int qubits[] = {1,2,2};
4032 REQUIRE_THROWS_WITH( applyQFT(quregVec, qubits, numQubits), ContainsSubstring(
"target") && ContainsSubstring(
"unique") );
4034 SECTION(
"qubit indices" ) {
4037 int qubits[] = {1,2,3};
4039 int inv = GENERATE( -1, NUM_QUBITS );
4040 qubits[GENERATE_COPY( range(0,numQubits) )] = inv;
4041 REQUIRE_THROWS_WITH( applyQFT(quregVec, qubits, numQubits), ContainsSubstring(
"Invalid target") );
4044 CLEANUP_TEST( quregVec, quregMatr );
4055 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
4057 SECTION(
"correctness" ) {
4060 int numTargs = GENERATE( range(1,NUM_QUBITS+1) );
4061 int* targs = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numTargs) );
4064 SubDiagonalOp op = createSubDiagonalOp(numTargs);
4065 for (
long long int i=0; i<op.numElems; i++)
4071 SECTION(
"state-vector" ) {
4073 applySubDiagonalOp(quregVec, targs, numTargs, op);
4075 REQUIRE(
areEqual(quregVec, refVec) );
4077 SECTION(
"density-matrix" ) {
4079 applySubDiagonalOp(quregMatr, targs, numTargs, op);
4081 REQUIRE(
areEqual(quregMatr, refMatr, 100*REAL_EPS) );
4084 destroySubDiagonalOp(op);
4086 SECTION(
"input validation" ) {
4088 SECTION(
"diagonal dimension" ) {
4091 SubDiagonalOp op = createSubDiagonalOp(numTargs);
4094 int badNumTargs = GENERATE_COPY( numTargs-1, numTargs+1 );
4095 int badTargs[NUM_QUBITS+1];
4096 for (
int i=0; i<NUM_QUBITS+1; i++)
4099 REQUIRE_THROWS_WITH( applySubDiagonalOp(quregVec, badTargs, badNumTargs, op), ContainsSubstring(
"inconsistent size") );
4100 destroySubDiagonalOp(op);
4102 SECTION(
"number of targets" ) {
4105 SubDiagonalOp badOp = createSubDiagonalOp(NUM_QUBITS + 1);
4106 int targs[NUM_QUBITS + 1];
4107 for (
int t=0; t<badOp.numQubits; t++)
4109 for (
int i=0; i<badOp.numElems; i++)
4110 badOp.cpuElems[i] = qcomp(1,0);
4113 REQUIRE_THROWS_WITH( applySubDiagonalOp(quregVec, targs, badOp.numQubits, badOp), ContainsSubstring(
"number of target qubits") && ContainsSubstring(
"exceeds") );
4114 destroySubDiagonalOp(badOp);
4116 SECTION(
"repetition in targets" ) {
4119 SubDiagonalOp op = createSubDiagonalOp(3);
4120 for (
int i=0; i<op.numElems; i++)
4121 op.cpuElems[i] = qcomp(1,0);
4125 int targs[] = {2,1,2};
4127 REQUIRE_THROWS_WITH( applySubDiagonalOp(quregVec, targs, op.numQubits, op), ContainsSubstring(
"target qubits contained duplicates") );
4128 destroySubDiagonalOp(op);
4130 SECTION(
"qubit indices" ) {
4133 SubDiagonalOp op = createSubDiagonalOp(3);
4134 for (
int i=0; i<op.numElems; i++)
4135 op.cpuElems[i] = qcomp(1,0);
4138 int targs[] = {0,1,2};
4141 int badIndex = GENERATE( range(0,3) );
4142 int badValue = GENERATE( -1, NUM_QUBITS );
4143 targs[badIndex] = badValue;
4145 REQUIRE_THROWS_WITH( applySubDiagonalOp(quregVec, targs, op.numQubits, op), ContainsSubstring(
"Invalid target qubit") );
4146 destroySubDiagonalOp(op);
4149 CLEANUP_TEST( quregVec, quregMatr );