59 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
62 qcomp b = sqrt(1-abs(a)*abs(a)) * expI(
getRandomReal(0,2*M_PI));
63 Complex alpha; alpha.real = real(a); alpha.imag = imag(a);
64 Complex beta; beta.real = real(b); beta.imag = imag(b);
69 SECTION(
"correctness" ) {
71 int target = GENERATE( range(0,NUM_QUBITS) );
73 SECTION(
"state-vector" ) {
75 compactUnitary(quregVec, target, alpha, beta);
77 REQUIRE(
areEqual(quregVec, refVec) );
79 SECTION(
"density-matrix" ) {
81 compactUnitary(quregMatr, target, alpha, beta);
83 REQUIRE(
areEqual(quregMatr, refMatr, 10*REAL_EPS) );
86 SECTION(
"input validation" ) {
88 SECTION(
"qubit indices" ) {
90 int target = GENERATE( -1, NUM_QUBITS );
91 REQUIRE_THROWS_WITH( compactUnitary(quregVec, target, alpha, beta), ContainsSubstring(
"Invalid target") );
93 SECTION(
"unitarity" ) {
96 alpha.real=1; alpha.imag=2;
97 beta.real=3; beta.imag=4;
98 REQUIRE_THROWS_WITH( compactUnitary(quregVec, 0, alpha, beta), ContainsSubstring(
"unitary") );
101 CLEANUP_TEST( quregVec, quregMatr );
112 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
114 SECTION(
"correctness" ) {
117 int numTargs = GENERATE( range(1,NUM_QUBITS+1) );
118 int* targs = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numTargs) );
121 SubDiagonalOp op = createSubDiagonalOp(numTargs);
122 for (
long long int i=0; i<op.numElems; i++) {
125 op.cpuElems[i] = elem;
131 SECTION(
"state-vector" ) {
133 diagonalUnitary(quregVec, targs, numTargs, op);
135 REQUIRE(
areEqual(quregVec, refVec) );
137 SECTION(
"density-matrix" ) {
139 diagonalUnitary(quregMatr, targs, numTargs, op);
141 REQUIRE(
areEqual(quregMatr, refMatr, 100*REAL_EPS) );
144 destroySubDiagonalOp(op);
146 SECTION(
"input validation" ) {
148 SECTION(
"diagonal dimension" ) {
151 SubDiagonalOp op = createSubDiagonalOp(numTargs);
154 int badNumTargs = GENERATE_COPY( numTargs-1, numTargs+1 );
155 int badTargs[NUM_QUBITS+1];
156 for (
int i=0; i<NUM_QUBITS+1; i++)
159 REQUIRE_THROWS_WITH( diagonalUnitary(quregVec, badTargs, badNumTargs, op), ContainsSubstring(
"matrix has an inconsistent size") );
160 destroySubDiagonalOp(op);
162 SECTION(
"number of targets" ) {
165 SubDiagonalOp badOp = createSubDiagonalOp(NUM_QUBITS + 1);
166 int targs[NUM_QUBITS + 1];
167 for (
int t=0; t<badOp.numQubits; t++)
169 for (
int i=0; i<badOp.numElems; i++)
170 badOp.cpuElems[i] = 1;
173 REQUIRE_THROWS_WITH( diagonalUnitary(quregVec, targs, badOp.numQubits, badOp), ContainsSubstring(
"number of target qubits") );
174 destroySubDiagonalOp(badOp);
176 SECTION(
"repetition in targets" ) {
179 SubDiagonalOp op = createSubDiagonalOp(3);
180 for (
int i=0; i<op.numElems; i++)
185 int targs[] = {2,1,2};
187 REQUIRE_THROWS_WITH( diagonalUnitary(quregVec, targs, op.numQubits, op), ContainsSubstring(
"target qubits contained duplicates") );
188 destroySubDiagonalOp(op);
190 SECTION(
"qubit indices" ) {
193 SubDiagonalOp op = createSubDiagonalOp(3);
194 for (
int i=0; i<op.numElems; i++)
198 int targs[] = {0,1,2};
201 int badIndex = GENERATE( range(0,3) );
202 int badValue = GENERATE( -1, NUM_QUBITS );
203 targs[badIndex] = badValue;
205 REQUIRE_THROWS_WITH( diagonalUnitary(quregVec, targs, op.numQubits, op), ContainsSubstring(
"Invalid target qubit") );
206 destroySubDiagonalOp(op);
208 SECTION(
"unitarity" ) {
211 SubDiagonalOp op = createSubDiagonalOp(3);
212 int targs[] = {0,1,2};
213 for (
int i=0; i<op.numElems; i++)
218 op.cpuElems[2] = -9999.1;
219 REQUIRE_THROWS_WITH( diagonalUnitary(quregVec, targs, op.numQubits, op), ContainsSubstring(
"unitary") );
223 op.cpuElems[3] = -9999.5;
224 REQUIRE_THROWS_WITH( diagonalUnitary(quregVec, targs, op.numQubits, op), ContainsSubstring(
"unitary") );
226 destroySubDiagonalOp(op);
229 CLEANUP_TEST( quregVec, quregMatr );
240 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
243 qcomp b = sqrt(1-abs(a)*abs(a)) * expI(
getRandomReal(0,2*M_PI));
244 Complex alpha; alpha.real = real(a); alpha.imag = imag(a);
245 Complex beta; beta.real = real(b); beta.imag = imag(b);
250 SECTION(
"correctness" ) {
252 int target = GENERATE( range(0,NUM_QUBITS) );
253 int control = GENERATE_COPY( filter([=](
int c){
return c!=target; }, range(0,NUM_QUBITS)) );
255 SECTION(
"state-vector" ) {
257 controlledCompactUnitary(quregVec, control, target, alpha, beta);
259 REQUIRE(
areEqual(quregVec, refVec) );
261 SECTION(
"density-matrix" ) {
263 controlledCompactUnitary(quregMatr, control, target, alpha, beta);
265 REQUIRE(
areEqual(quregMatr, refMatr, 10*REAL_EPS) );
268 SECTION(
"input validation" ) {
270 SECTION(
"control and target collision" ) {
273 REQUIRE_THROWS_WITH( controlledCompactUnitary(quregVec, qb, qb, alpha, beta), ContainsSubstring(
"control and target") );
275 SECTION(
"qubit indices" ) {
277 int qb = GENERATE( -1, NUM_QUBITS );
278 REQUIRE_THROWS_WITH( controlledCompactUnitary(quregVec, qb, 0, alpha, beta), ContainsSubstring(
"Invalid control") );
279 REQUIRE_THROWS_WITH( controlledCompactUnitary(quregVec, 0, qb, alpha, beta), ContainsSubstring(
"Invalid target") );
281 SECTION(
"unitarity" ) {
284 alpha.real=1; alpha.imag=2;
285 beta.real=3; beta.imag=4;
286 REQUIRE_THROWS_WITH( controlledCompactUnitary(quregVec, 0, 1, alpha, beta), ContainsSubstring(
"unitary") );
289 CLEANUP_TEST( quregVec, quregMatr );
298TEST_CASE(
"controlledMultiQubitUnitary",
"[unitaries]" ) {
300 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
303 int maxNumTargs =
calcLog2(quregVec.numAmpsPerNode);
304 if (maxNumTargs >= NUM_QUBITS)
305 maxNumTargs = NUM_QUBITS - 1;
307 SECTION(
"correctness" ) {
310 int ctrl = GENERATE( range(0,NUM_QUBITS) );
311 int numTargs = GENERATE_COPY( range(1,maxNumTargs+1) );
312 int* targs = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numTargs, ctrl) );
316 ComplexMatrixN matr = createComplexMatrixN(numTargs);
319 SECTION(
"state-vector" ) {
321 controlledMultiQubitUnitary(quregVec, ctrl, targs, numTargs, matr);
323 REQUIRE(
areEqual(quregVec, refVec) );
325 SECTION(
"density-matrix" ) {
327 controlledMultiQubitUnitary(quregMatr, ctrl, targs, numTargs, matr);
329 REQUIRE(
areEqual(quregMatr, refMatr, 10*REAL_EPS) );
331 destroyComplexMatrixN(matr);
333 SECTION(
"input validation" ) {
335 SECTION(
"number of targets" ) {
339 int numTargs = GENERATE( -1, 0, NUM_QUBITS+1 );
340 int targs[NUM_QUBITS+1];
341 ComplexMatrixN matr = createComplexMatrixN(NUM_QUBITS+1);
344 REQUIRE_THROWS_WITH( controlledMultiQubitUnitary(quregVec, 0, targs, numTargs, matr), ContainsSubstring(
"number of target qubits"));
346 destroyComplexMatrixN(matr);
348 SECTION(
"repetition in targets" ) {
352 int targs[] = {1,2,2};
353 ComplexMatrixN matr = createComplexMatrixN(numTargs);
356 REQUIRE_THROWS_WITH( controlledMultiQubitUnitary(quregVec, ctrl, targs, numTargs, matr), ContainsSubstring(
"target") && ContainsSubstring(
"unique"));
357 destroyComplexMatrixN(matr);
359 SECTION(
"control and target collision" ) {
362 int targs[] = {0,1,2};
363 int ctrl = targs[GENERATE_COPY( range(0,numTargs) )];
364 ComplexMatrixN matr = createComplexMatrixN(numTargs);
367 REQUIRE_THROWS_WITH( controlledMultiQubitUnitary(quregVec, ctrl, targs, numTargs, matr), ContainsSubstring(
"control and target"));
368 destroyComplexMatrixN(matr);
370 SECTION(
"qubit indices" ) {
374 int targs[] = {1,2,3};
375 ComplexMatrixN matr = createComplexMatrixN(numTargs);
378 int inv = GENERATE( -1, NUM_QUBITS );
380 REQUIRE_THROWS_WITH( controlledMultiQubitUnitary(quregVec, ctrl, targs, numTargs, matr), ContainsSubstring(
"Invalid control") );
383 targs[GENERATE_COPY( range(0,numTargs) )] = inv;
384 REQUIRE_THROWS_WITH( controlledMultiQubitUnitary(quregVec, ctrl, targs, numTargs, matr), ContainsSubstring(
"Invalid target") );
386 destroyComplexMatrixN(matr);
388 SECTION(
"unitarity" ) {
391 int numTargs = GENERATE_COPY( range(1,maxNumTargs+1) );
392 ComplexMatrixN matr = createComplexMatrixN(numTargs);
395 int targs[NUM_QUBITS];
396 for (
int i=0; i<numTargs; i++)
399 REQUIRE_THROWS_WITH( controlledMultiQubitUnitary(quregVec, ctrl, targs, numTargs, matr), ContainsSubstring(
"unitary") );
400 destroyComplexMatrixN(matr);
402 SECTION(
"unitary creation" ) {
405 int targs[] = {1,2,3};
408 matr.cpuElems = NULL;
409 REQUIRE_THROWS_WITH( controlledMultiQubitUnitary(quregVec, 0, targs, numTargs, matr), ContainsSubstring(
"created") );
411 SECTION(
"unitary dimensions" ) {
414 int targs[2] = {1,2};
415 ComplexMatrixN matr = createComplexMatrixN(3);
418 REQUIRE_THROWS_WITH( controlledMultiQubitUnitary(quregVec, ctrl, targs, 2, matr), ContainsSubstring(
"matrix has an inconsistent size"));
419 destroyComplexMatrixN(matr);
421 SECTION(
"unitary fits in node" ) {
424 quregVec.isDistributed = 1;
425 quregVec.numAmpsPerNode = 1;
426 quregVec.logNumAmpsPerNode = 0;
429 ComplexMatrixN matr = createComplexMatrixN(2);
430 for (
int i=0; i<4; i++)
431 matr.cpuElems[i][i] = 1;
434 REQUIRE_THROWS_WITH( controlledMultiQubitUnitary(quregVec, 0, qb, 2, matr), ContainsSubstring(
"communication buffer") && ContainsSubstring(
"simultaneously store"));
435 destroyComplexMatrixN(matr);
438 CLEANUP_TEST( quregVec, quregMatr );
449 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
452 SECTION(
"correctness" ) {
454 int target = GENERATE( range(0,NUM_QUBITS) );
455 int control = GENERATE_COPY( filter([=](
int c){
return c!=target; }, range(0,NUM_QUBITS)) );
457 SECTION(
"state-vector" ) {
459 controlledNot(quregVec, control, target);
461 REQUIRE(
areEqual(quregVec, refVec) );
463 SECTION(
"density-matrix" ) {
465 controlledNot(quregMatr, control, target);
467 REQUIRE(
areEqual(quregMatr, refMatr) );
470 SECTION(
"input validation" ) {
472 SECTION(
"control and target collision" ) {
474 int qb = GENERATE( range(0,NUM_QUBITS) );
475 REQUIRE_THROWS_WITH( controlledNot(quregVec, qb, qb), ContainsSubstring(
"control and target") );
477 SECTION(
"qubit indices" ) {
479 int qb = GENERATE( -1, NUM_QUBITS );
480 REQUIRE_THROWS_WITH( controlledNot(quregVec, qb, 0), ContainsSubstring(
"Invalid control") );
481 REQUIRE_THROWS_WITH( controlledNot(quregVec, 0, qb), ContainsSubstring(
"Invalid target") );
484 CLEANUP_TEST( quregVec, quregMatr );
495 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
496 QMatrix op{{0,-qcomp(0,1)},{qcomp(0,1),0}};
498 SECTION(
"correctness" ) {
500 int target = GENERATE( range(0,NUM_QUBITS) );
501 int control = GENERATE_COPY( filter([=](
int c){
return c!=target; }, range(0,NUM_QUBITS)) );
503 SECTION(
"state-vector" ) {
505 controlledPauliY(quregVec, control, target);
507 REQUIRE(
areEqual(quregVec, refVec) );
509 SECTION(
"density-matrix" ) {
511 controlledPauliY(quregMatr, control, target);
513 REQUIRE(
areEqual(quregMatr, refMatr) );
516 SECTION(
"input validation" ) {
518 SECTION(
"control and target collision" ) {
520 int qb = GENERATE( range(0,NUM_QUBITS) );
521 REQUIRE_THROWS_WITH( controlledPauliY(quregVec, qb, qb), ContainsSubstring(
"control and target") );
523 SECTION(
"qubit indices" ) {
525 int qb = GENERATE( -1, NUM_QUBITS );
526 REQUIRE_THROWS_WITH( controlledPauliY(quregVec, qb, 0), ContainsSubstring(
"Invalid control") );
527 REQUIRE_THROWS_WITH( controlledPauliY(quregVec, 0, qb), ContainsSubstring(
"Invalid target") );
530 CLEANUP_TEST( quregVec, quregMatr );
541 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
544 SECTION(
"correctness" ) {
546 int target = GENERATE( range(0,NUM_QUBITS) );
547 int control = GENERATE_COPY( filter([=](
int c){
return c!=target; }, range(0,NUM_QUBITS)) );
549 SECTION(
"state-vector" ) {
551 controlledPhaseFlip(quregVec, control, target);
553 REQUIRE(
areEqual(quregVec, refVec) );
555 SECTION(
"density-matrix" ) {
557 controlledPhaseFlip(quregMatr, control, target);
559 REQUIRE(
areEqual(quregMatr, refMatr) );
562 SECTION(
"input validation" ) {
566 SECTION(
"target collision" ) {
568 int qb = GENERATE( range(0,NUM_QUBITS) );
569 REQUIRE_THROWS_WITH( controlledPhaseFlip(quregVec, qb, qb), ContainsSubstring(
"target qubits contained duplicates") );
572 SECTION(
"target indices" ) {
574 int qb = GENERATE( -1, NUM_QUBITS );
575 REQUIRE_THROWS_WITH( controlledPhaseFlip(quregVec, qb, 0), ContainsSubstring(
"Invalid target") );
576 REQUIRE_THROWS_WITH( controlledPhaseFlip(quregVec, 0, qb), ContainsSubstring(
"Invalid target") );
579 CLEANUP_TEST( quregVec, quregMatr );
590 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
592 QMatrix op{{1,0},{0,expI(param)}};
594 SECTION(
"correctness" ) {
596 int target = GENERATE( range(0,NUM_QUBITS) );
597 int control = GENERATE_COPY( filter([=](
int c){
return c!=target; }, range(0,NUM_QUBITS)) );
599 SECTION(
"state-vector" ) {
601 controlledPhaseShift(quregVec, control, target, param);
603 REQUIRE(
areEqual(quregVec, refVec) );
605 SECTION(
"density-matrix" ) {
607 controlledPhaseShift(quregMatr, control, target, param);
609 REQUIRE(
areEqual(quregMatr, refMatr) );
612 SECTION(
"input validation" ) {
616 SECTION(
"target collision" ) {
618 int qb = GENERATE( range(0,NUM_QUBITS) );
619 REQUIRE_THROWS_WITH( controlledPhaseShift(quregVec, qb, qb, param), ContainsSubstring(
"target qubits contained duplicates") );
621 SECTION(
"qubit indices" ) {
623 int qb = GENERATE( -1, NUM_QUBITS );
624 REQUIRE_THROWS_WITH( controlledPhaseShift(quregVec, qb, 0, param), ContainsSubstring(
"Invalid target") );
625 REQUIRE_THROWS_WITH( controlledPhaseShift(quregVec, 0, qb, param), ContainsSubstring(
"Invalid target") );
628 CLEANUP_TEST( quregVec, quregMatr );
637TEST_CASE(
"controlledRotateAroundAxis",
"[unitaries]" ) {
639 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
650 qreal c = cos(param/2);
651 qreal s = sin(param/2);
652 qreal m = sqrt(vec.x*vec.x + vec.y*vec.y + vec.z*vec.z);
653 QMatrix op{{c - qcomp(0,1)*vec.z*s/m, -(vec.y + qcomp(0,1)*vec.x)*s/m},
654 {(vec.y - qcomp(0,1)*vec.x)*s/m, c + qcomp(0,1)*vec.z*s/m}};
656 SECTION(
"correctness" ) {
658 int target = GENERATE( range(0,NUM_QUBITS) );
659 int control = GENERATE_COPY( filter([=](
int c){
return c!=target; }, range(0,NUM_QUBITS)) );
661 SECTION(
"state-vector" ) {
663 controlledRotateAroundAxis(quregVec, control, target, param, vec);
665 REQUIRE(
areEqual(quregVec, refVec) );
667 SECTION(
"density-matrix" ) {
669 controlledRotateAroundAxis(quregMatr, control, target, param, vec);
671 REQUIRE(
areEqual(quregMatr, refMatr, 10*REAL_EPS) );
674 SECTION(
"input validation" ) {
676 SECTION(
"control and target collision" ) {
678 int qb = GENERATE( range(0,NUM_QUBITS) );
679 REQUIRE_THROWS_WITH( controlledRotateAroundAxis(quregVec, qb, qb, param, vec), ContainsSubstring(
"control and target") );
681 SECTION(
"qubit indices" ) {
683 int qb = GENERATE( -1, NUM_QUBITS );
684 REQUIRE_THROWS_WITH( controlledRotateAroundAxis(quregVec, qb, 0, param, vec), ContainsSubstring(
"Invalid control") );
685 REQUIRE_THROWS_WITH( controlledRotateAroundAxis(quregVec, 0, qb, param, vec), ContainsSubstring(
"Invalid target") );
687 SECTION(
"zero rotation axis" ) {
689 vec.x=0; vec.y=0; vec.z=0;
690 REQUIRE_THROWS_WITH( controlledRotateAroundAxis(quregVec, 0, 1, param, vec), ContainsSubstring(
"axis") && ContainsSubstring(
"zero") );
693 CLEANUP_TEST( quregVec, quregMatr );
704 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
707 {cos(param/2), -sin(param/2)*qcomp(0,1)},
708 {-sin(param/2)*qcomp(0,1), cos(param/2)}};
710 SECTION(
"correctness" ) {
712 int target = GENERATE( range(0,NUM_QUBITS) );
713 int control = GENERATE_COPY( filter([=](
int c){
return c!=target; }, range(0,NUM_QUBITS)) );
715 SECTION(
"state-vector" ) {
717 controlledRotateX(quregVec, control, target, param);
719 REQUIRE(
areEqual(quregVec, refVec) );
721 SECTION(
"density-matrix" ) {
723 controlledRotateX(quregMatr, control, target, param);
725 REQUIRE(
areEqual(quregMatr, refMatr) );
728 SECTION(
"input validation" ) {
730 SECTION(
"control and target collision" ) {
732 int qb = GENERATE( range(0,NUM_QUBITS) );
733 REQUIRE_THROWS_WITH( controlledRotateX(quregVec, qb, qb, param), ContainsSubstring(
"control and target") );
735 SECTION(
"qubit indices" ) {
737 int qb = GENERATE( -1, NUM_QUBITS );
738 REQUIRE_THROWS_WITH( controlledRotateX(quregVec, qb, 0, param), ContainsSubstring(
"Invalid control") );
739 REQUIRE_THROWS_WITH( controlledRotateX(quregVec, 0, qb, param), ContainsSubstring(
"Invalid target") );
742 CLEANUP_TEST( quregVec, quregMatr );
753 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
755 QMatrix op{{cos(param/2), -sin(param/2)},{sin(param/2), cos(param/2)}};
757 SECTION(
"correctness" ) {
759 int target = GENERATE( range(0,NUM_QUBITS) );
760 int control = GENERATE_COPY( filter([=](
int c){
return c!=target; }, range(0,NUM_QUBITS)) );
762 SECTION(
"state-vector" ) {
764 controlledRotateY(quregVec, control, target, param);
766 REQUIRE(
areEqual(quregVec, refVec) );
768 SECTION(
"density-matrix" ) {
770 controlledRotateY(quregMatr, control, target, param);
772 REQUIRE(
areEqual(quregMatr, refMatr, 4*REAL_EPS) );
775 SECTION(
"input validation" ) {
777 SECTION(
"control and target collision" ) {
779 int qb = GENERATE( range(0,NUM_QUBITS) );
780 REQUIRE_THROWS_WITH( controlledRotateY(quregVec, qb, qb, param), ContainsSubstring(
"control and target") );
782 SECTION(
"qubit indices" ) {
784 int qb = GENERATE( -1, NUM_QUBITS );
785 REQUIRE_THROWS_WITH( controlledRotateY(quregVec, qb, 0, param), ContainsSubstring(
"Invalid control") );
786 REQUIRE_THROWS_WITH( controlledRotateY(quregVec, 0, qb, param), ContainsSubstring(
"Invalid target") );
789 CLEANUP_TEST( quregVec, quregMatr );
800 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
802 QMatrix op{{expI(-param/2.),0},{0,expI(param/2.)}};
804 SECTION(
"correctness" ) {
806 int target = GENERATE( range(0,NUM_QUBITS) );
807 int control = GENERATE_COPY( filter([=](
int c){
return c!=target; }, range(0,NUM_QUBITS)) );
809 SECTION(
"state-vector" ) {
811 controlledRotateZ(quregVec, control, target, param);
813 REQUIRE(
areEqual(quregVec, refVec) );
815 SECTION(
"density-matrix" ) {
817 controlledRotateZ(quregMatr, control, target, param);
819 REQUIRE(
areEqual(quregMatr, refMatr, 10*REAL_EPS) );
822 SECTION(
"input validation" ) {
824 SECTION(
"control and target collision" ) {
826 int qb = GENERATE( range(0,NUM_QUBITS) );
827 REQUIRE_THROWS_WITH( controlledRotateZ(quregVec, qb, qb, param), ContainsSubstring(
"control and target") );
829 SECTION(
"qubit indices" ) {
831 int qb = GENERATE( -1, NUM_QUBITS );
832 REQUIRE_THROWS_WITH( controlledRotateZ(quregVec, qb, 0, param), ContainsSubstring(
"Invalid control") );
833 REQUIRE_THROWS_WITH( controlledRotateZ(quregVec, 0, qb, param), ContainsSubstring(
"Invalid target") );
836 CLEANUP_TEST( quregVec, quregMatr );
845TEST_CASE(
"controlledTwoQubitUnitary",
"[unitaries]" ) {
847 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
850 REQUIRE( quregVec.numAmpsPerNode >= 4 );
856 SECTION(
"correctness" ) {
858 int targ1 = GENERATE( range(0,NUM_QUBITS) );
859 int targ2 = GENERATE_COPY( filter([=](
int t){
return t!=targ1; }, range(0,NUM_QUBITS)) );
860 int control = GENERATE_COPY( filter([=](
int c){
return c!=targ1 && c!=targ2; }, range(0,NUM_QUBITS)) );
862 SECTION(
"state-vector" ) {
864 controlledTwoQubitUnitary(quregVec, control, targ1, targ2, matr);
866 REQUIRE(
areEqual(quregVec, refVec) );
868 SECTION(
"density-matrix" ) {
870 controlledTwoQubitUnitary(quregMatr, control, targ1, targ2, matr);
872 REQUIRE(
areEqual(quregMatr, refMatr, 10*REAL_EPS) );
875 SECTION(
"input validation" ) {
877 SECTION(
"repetition of targets" ) {
880 REQUIRE_THROWS_WITH( controlledTwoQubitUnitary(quregVec, ctrl, targ, targ, matr), ContainsSubstring(
"target") && ContainsSubstring(
"unique") );
882 SECTION(
"control and target collision" ) {
886 int ctrl = GENERATE( 1,2 );
887 REQUIRE_THROWS_WITH( controlledTwoQubitUnitary(quregVec, ctrl, targ1, targ2, matr), ContainsSubstring(
"control and target") );
889 SECTION(
"qubit indices" ) {
896 int qb = GENERATE( -1, NUM_QUBITS );
897 REQUIRE_THROWS_WITH( controlledTwoQubitUnitary(quregVec, qb, targ1, targ2, matr), ContainsSubstring(
"Invalid control") );
898 REQUIRE_THROWS_WITH( controlledTwoQubitUnitary(quregVec, ctrl, qb, targ2, matr), ContainsSubstring(
"Invalid target") );
899 REQUIRE_THROWS_WITH( controlledTwoQubitUnitary(quregVec, ctrl, targ1, qb, matr), ContainsSubstring(
"Invalid target") );
901 SECTION(
"unitarity" ) {
903 matr.real[0][0] = 999;
904 REQUIRE_THROWS_WITH( controlledTwoQubitUnitary(quregVec, 0, 1, 2, matr), ContainsSubstring(
"unitary") );
906 SECTION(
"unitary fits in node" ) {
909 quregVec.isDistributed = 1;
910 quregVec.numAmpsPerNode = 1;
911 quregVec.logNumAmpsPerNode = 0;
913 REQUIRE_THROWS_WITH( controlledTwoQubitUnitary(quregVec, 0, 1, 2, matr), ContainsSubstring(
"communication buffer") && ContainsSubstring(
"simultaneously store"));
916 CLEANUP_TEST( quregVec, quregMatr );
927 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
931 SECTION(
"correctness" ) {
933 int target = GENERATE( range(0,NUM_QUBITS) );
934 int control = GENERATE_COPY( filter([=](
int c){
return c!=target; }, range(0,NUM_QUBITS)) );
936 SECTION(
"state-vector" ) {
938 controlledUnitary(quregVec, control, target, matr);
940 REQUIRE(
areEqual(quregVec, refVec) );
942 SECTION(
"density-matrix" ) {
944 controlledUnitary(quregMatr, control, target, matr);
946 REQUIRE(
areEqual(quregMatr, refMatr, 10*REAL_EPS) );
949 SECTION(
"input validation" ) {
951 SECTION(
"control and target collision" ) {
953 int qb = GENERATE( range(0,NUM_QUBITS) );
954 REQUIRE_THROWS_WITH( controlledUnitary(quregVec, qb, qb, matr), ContainsSubstring(
"control and target") );
956 SECTION(
"qubit indices" ) {
958 int qb = GENERATE( -1, NUM_QUBITS );
959 REQUIRE_THROWS_WITH( controlledUnitary(quregVec, qb, 0, matr), ContainsSubstring(
"Invalid control") );
960 REQUIRE_THROWS_WITH( controlledUnitary(quregVec, 0, qb, matr), ContainsSubstring(
"Invalid target") );
962 SECTION(
"unitarity" ) {
964 matr.real[0][0] = 9999;
965 REQUIRE_THROWS_WITH( controlledUnitary(quregVec, 0, 1, matr), ContainsSubstring(
"unitary") );
968 CLEANUP_TEST( quregVec, quregMatr );
1019 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
1021 SECTION(
"correctness" ) {
1024 int numTargs = GENERATE_COPY( range(1,NUM_QUBITS) );
1025 int maxNumCtrls = NUM_QUBITS - numTargs;
1026 int numCtrls = GENERATE_COPY( range(1,maxNumCtrls+1) );
1029 int* targs = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numTargs) );
1030 int* ctrls = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numCtrls, targs, numTargs) );
1035 SECTION(
"state-vector" ) {
1037 multiControlledMultiQubitNot(quregVec, ctrls, numCtrls, targs, numTargs);
1038 for (
int t=0; t<numTargs; t++)
1041 REQUIRE(
areEqual(quregVec, refVec) );
1043 SECTION(
"density-matrix" ) {
1045 multiControlledMultiQubitNot(quregMatr, ctrls, numCtrls, targs, numTargs);
1046 for (
int t=0; t<numTargs; t++)
1049 REQUIRE(
areEqual(quregMatr, refMatr) );
1052 SECTION(
"input validation" ) {
1054 SECTION(
"number of targets" ) {
1058 int numTargs = GENERATE( -1, 0, NUM_QUBITS+1 );
1059 int targs[NUM_QUBITS+1];
1061 REQUIRE_THROWS_WITH( multiControlledMultiQubitNot(quregVec, ctrls, 1, targs, numTargs), ContainsSubstring(
"number of target qubits"));
1063 SECTION(
"repetition in targets" ) {
1067 int targs[] = {1,2,2};
1068 REQUIRE_THROWS_WITH( multiControlledMultiQubitNot(quregVec, ctrls, 1, targs, numTargs), ContainsSubstring(
"target") && ContainsSubstring(
"unique"));
1070 SECTION(
"number of controls" ) {
1073 int numCtrls = GENERATE( -1, NUM_QUBITS+1 );
1074 int ctrls[NUM_QUBITS+1];
1075 for (
int i=0; i<NUM_QUBITS+1; i++)
1078 REQUIRE_THROWS_WITH( multiControlledMultiQubitNot(quregVec, ctrls, numCtrls, targs, 1), ContainsSubstring(
"number of control qubits"));
1080 SECTION(
"repetition in controls" ) {
1082 int ctrls[] = {0,1,1};
1084 REQUIRE_THROWS_WITH( multiControlledMultiQubitNot(quregVec, ctrls, 3, targs, 1), ContainsSubstring(
"control") && ContainsSubstring(
"unique"));
1086 SECTION(
"control and target collision" ) {
1088 int ctrls[] = {0,1,2};
1089 int targs[] = {3,1,4};
1090 REQUIRE_THROWS_WITH( multiControlledMultiQubitNot(quregVec, ctrls, 3, targs, 3), ContainsSubstring(
"control and target"));
1092 SECTION(
"qubit indices" ) {
1100 int inv = GENERATE( -1, NUM_QUBITS );
1101 qb1[GENERATE_COPY(range(0,numQb))] = inv;
1103 REQUIRE_THROWS_WITH( multiControlledMultiQubitNot(quregVec, qb1, numQb, qb2, numQb), ContainsSubstring(
"Invalid control") );
1104 REQUIRE_THROWS_WITH( multiControlledMultiQubitNot(quregVec, qb2, numQb, qb1, numQb), ContainsSubstring(
"Invalid target") );
1107 CLEANUP_TEST( quregVec, quregMatr );
1116TEST_CASE(
"multiControlledMultiQubitUnitary",
"[unitaries]" ) {
1118 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
1121 int maxNumTargs =
calcLog2(quregVec.numAmpsPerNode);
1122 if (maxNumTargs >= NUM_QUBITS)
1123 maxNumTargs = NUM_QUBITS - 1;
1125 SECTION(
"correctness" ) {
1128 int numTargs = GENERATE_COPY( range(1,maxNumTargs+1) );
1129 int maxNumCtrls = NUM_QUBITS - numTargs;
1130 int numCtrls = GENERATE_COPY( range(1,maxNumCtrls+1) );
1133 int* targs = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numTargs) );
1134 int* ctrls = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numCtrls, targs, numTargs) );
1138 ComplexMatrixN matr = createComplexMatrixN(numTargs);
1141 SECTION(
"state-vector" ) {
1143 multiControlledMultiQubitUnitary(quregVec, ctrls, numCtrls, targs, numTargs, matr);
1145 REQUIRE(
areEqual(quregVec, refVec) );
1147 SECTION(
"density-matrix" ) {
1149 multiControlledMultiQubitUnitary(quregMatr, ctrls, numCtrls, targs, numTargs, matr);
1151 REQUIRE(
areEqual(quregMatr, refMatr, 10*REAL_EPS) );
1153 destroyComplexMatrixN(matr);
1155 SECTION(
"input validation" ) {
1157 SECTION(
"number of targets" ) {
1161 int numTargs = GENERATE( -1, 0, NUM_QUBITS+1 );
1162 int targs[NUM_QUBITS+1];
1164 ComplexMatrixN matr = createComplexMatrixN(NUM_QUBITS+1);
1167 REQUIRE_THROWS_WITH( multiControlledMultiQubitUnitary(quregVec, ctrls, 1, targs, numTargs, matr), ContainsSubstring(
"number of target qubits"));
1168 destroyComplexMatrixN(matr);
1170 SECTION(
"repetition in targets" ) {
1174 int targs[] = {1,2,2};
1175 ComplexMatrixN matr = createComplexMatrixN(numTargs);
1178 REQUIRE_THROWS_WITH( multiControlledMultiQubitUnitary(quregVec, ctrls, 1, targs, numTargs, matr), ContainsSubstring(
"target") && ContainsSubstring(
"unique"));
1179 destroyComplexMatrixN(matr);
1181 SECTION(
"number of controls" ) {
1184 int numCtrls = GENERATE( -1, NUM_QUBITS+1 );
1185 int ctrls[NUM_QUBITS+1];
1186 for (
int i=0; i<NUM_QUBITS+1; i++)
1189 ComplexMatrixN matr = createComplexMatrixN(1);
1192 REQUIRE_THROWS_WITH( multiControlledMultiQubitUnitary(quregVec, ctrls, numCtrls, targs, 1, matr), ContainsSubstring(
"number of control qubits"));
1193 destroyComplexMatrixN(matr);
1195 SECTION(
"repetition in controls" ) {
1197 int ctrls[] = {0,1,1};
1199 ComplexMatrixN matr = createComplexMatrixN(1);
1202 REQUIRE_THROWS_WITH( multiControlledMultiQubitUnitary(quregVec, ctrls, 3, targs, 1, matr), ContainsSubstring(
"control") && ContainsSubstring(
"unique"));
1203 destroyComplexMatrixN(matr);
1205 SECTION(
"control and target collision" ) {
1207 int ctrls[] = {0,1,2};
1208 int targs[] = {3,1,4};
1209 ComplexMatrixN matr = createComplexMatrixN(3);
1212 REQUIRE_THROWS_WITH( multiControlledMultiQubitUnitary(quregVec, ctrls, 3, targs, 3, matr), ContainsSubstring(
"control and target"));
1213 destroyComplexMatrixN(matr);
1215 SECTION(
"qubit indices" ) {
1221 ComplexMatrixN matr = createComplexMatrixN(numQb);
1225 int inv = GENERATE( -1, NUM_QUBITS );
1226 qb1[GENERATE_COPY(range(0,numQb))] = inv;
1228 REQUIRE_THROWS_WITH( multiControlledMultiQubitUnitary(quregVec, qb1, numQb, qb2, numQb, matr), ContainsSubstring(
"Invalid control") );
1229 REQUIRE_THROWS_WITH( multiControlledMultiQubitUnitary(quregVec, qb2, numQb, qb1, numQb, matr), ContainsSubstring(
"Invalid target") );
1230 destroyComplexMatrixN(matr);
1232 SECTION(
"unitarity" ) {
1235 int numTargs = GENERATE_COPY( range(1,maxNumTargs+1) );
1236 int targs[NUM_QUBITS];
1237 for (
int i=0; i<numTargs; i++)
1240 ComplexMatrixN matr = createComplexMatrixN(numTargs);
1243 REQUIRE_THROWS_WITH( multiControlledMultiQubitUnitary(quregVec, ctrls, 1, targs, numTargs, matr), ContainsSubstring(
"unitary") );
1245 destroyComplexMatrixN(matr);
1247 SECTION(
"unitary creation" ) {
1250 int targs[3] = {1,2,3};
1252 ComplexMatrixN matr;
1253 matr.cpuElems = NULL;
1254 REQUIRE_THROWS_WITH( multiControlledMultiQubitUnitary(quregVec, ctrls, 1, targs, 3, matr), ContainsSubstring(
"created") );
1256 SECTION(
"unitary dimensions" ) {
1259 int targs[2] = {1,2};
1260 ComplexMatrixN matr = createComplexMatrixN(3);
1263 REQUIRE_THROWS_WITH( multiControlledMultiQubitUnitary(quregVec, ctrls, 1, targs, 2, matr), ContainsSubstring(
"matrix has an inconsistent size"));
1264 destroyComplexMatrixN(matr);
1266 SECTION(
"unitary fits in node" ) {
1269 quregVec.isDistributed = 1;
1270 quregVec.numAmpsPerNode = 1;
1271 quregVec.logNumAmpsPerNode = 0;
1274 int targs[2] = {1,2};
1275 ComplexMatrixN matr = createComplexMatrixN(2);
1276 for (
int i=0; i<4; i++)
1277 matr.cpuElems[i][i] = 1;
1280 REQUIRE_THROWS_WITH( multiControlledMultiQubitUnitary(quregVec, ctrls, 1, targs, 2, matr), ContainsSubstring(
"communication buffer") && ContainsSubstring(
"simultaneously store"));
1281 destroyComplexMatrixN(matr);
1284 CLEANUP_TEST( quregVec, quregMatr );
1293TEST_CASE(
"multiControlledMultiRotatePauli",
"[unitaries]" ) {
1295 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
1298 SECTION(
"correctness" ) {
1301 int numTargs = GENERATE_COPY( range(1,NUM_QUBITS) );
1302 int maxNumCtrls = NUM_QUBITS - numTargs;
1303 int numCtrls = GENERATE_COPY( range(1,maxNumCtrls+1) );
1306 int* targs = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numTargs) );
1307 int* ctrls = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numCtrls, targs, numTargs) );
1314 pauliOpType paulis[NUM_QUBITS];
1315 for (
int i=0; i<numTargs; i++)
1319 int refTargs[NUM_QUBITS];
1320 int numRefTargs = 0;
1323 QMatrix yMatr{{0,-qcomp(0,1)},{qcomp(0,1),0}};
1328 for (
int i=0; i<numTargs; i++) {
1330 if (paulis[i] == PAULI_I)
continue;
1331 if (paulis[i] == PAULI_X) fac = xMatr;
1332 if (paulis[i] == PAULI_Y) fac = yMatr;
1333 if (paulis[i] == PAULI_Z) fac = zMatr;
1337 refTargs[numRefTargs++] = targs[i];
1342 if (numRefTargs > 0)
1345 SECTION(
"state-vector" ) {
1347 multiControlledMultiRotatePauli(quregVec, ctrls, numCtrls, targs, paulis, numTargs, param);
1348 if (numRefTargs > 0)
1350 REQUIRE(
areEqual(quregVec, refVec) );
1352 SECTION(
"density-matrix" ) {
1354 multiControlledMultiRotatePauli(quregMatr, ctrls, numCtrls, targs, paulis, numTargs, param);
1355 if (numRefTargs > 0)
1357 REQUIRE(
areEqual(quregMatr, refMatr, 10*REAL_EPS) );
1360 SECTION(
"input validation" ) {
1365 Qureg regs[] = {quregVec, quregMatr};
1366 Qureg qureg = regs[GENERATE(0,1)];
1369 pauliOpType paulis[NUM_QUBITS+1];
1370 for (
int q=0; q<NUM_QUBITS+1; q++)
1371 paulis[q] = PAULI_I;
1373 SECTION(
"pauli codes" ) {
1378 int targs[3] = {0, 1, 2};
1381 paulis[GENERATE_COPY(range(0,numTargs))] = (pauliOpType) GENERATE( -1, 4 );
1383 REQUIRE_THROWS_WITH( multiControlledMultiRotatePauli(qureg, ctrls, numCtrls, targs, paulis, numTargs, param), ContainsSubstring(
"invalid Pauli code"));
1385 SECTION(
"number of targets" ) {
1391 int targs[NUM_QUBITS+1];
1392 for (
int i=0; i<NUM_QUBITS+1; i++)
1398 for (
int i=0; i<NUM_QUBITS; i++)
1399 paulis[i] = PAULI_X;
1401 REQUIRE_THROWS_WITH( multiControlledMultiRotatePauli(qureg, ctrls, numCtrls, targs, paulis, -1, param), ContainsSubstring(
"must contain at least one Pauli operator") );
1402 REQUIRE_THROWS_WITH( multiControlledMultiRotatePauli(qureg, ctrls, numCtrls, targs, paulis, NUM_QUBITS+1, param), ContainsSubstring(
"non-identity Pauli operator") && ContainsSubstring(
"exceeds the maximum target") );
1404 SECTION(
"repetition in targets" ) {
1409 int targs[] = {1,2,2};
1411 for (
int i=0; i<NUM_QUBITS; i++)
1412 paulis[i] = PAULI_X;
1414 REQUIRE_THROWS_WITH( multiControlledMultiRotatePauli(qureg, ctrls, numCtrls, targs, paulis, numTargs, param), ContainsSubstring(
"Pauli indices") && ContainsSubstring(
"duplicate"));
1416 SECTION(
"number of controls" ) {
1419 int numCtrls = GENERATE( -1, NUM_QUBITS+1 );
1421 int ctrls[NUM_QUBITS+1];
1422 for (
int i=0; i<NUM_QUBITS+1; i++)
1426 REQUIRE_THROWS_WITH( multiControlledMultiRotatePauli(qureg, ctrls, numCtrls, targs, paulis, numTargs, param), ContainsSubstring(
"number of control qubits"));
1428 SECTION(
"repetition in controls" ) {
1432 int ctrls[] = {0,1,1};
1435 REQUIRE_THROWS_WITH( multiControlledMultiRotatePauli(qureg, ctrls, numCtrls, targs, paulis, numTargs, param), ContainsSubstring(
"control") && ContainsSubstring(
"unique"));
1437 SECTION(
"control and target collision" ) {
1441 int ctrls[] = {0,1,2};
1442 int targs[] = {3,1,4};
1443 for (
int i=0; i<numTargs; i++)
1444 paulis[i] = PAULI_X;
1446 REQUIRE_THROWS_WITH( multiControlledMultiRotatePauli(qureg, ctrls, numCtrls, targs, paulis, numTargs, param), ContainsSubstring(
"control qubit overlaps a non-identity Pauli"));
1448 SECTION(
"qubit indices" ) {
1455 for (
int i=0; i<NUM_QUBITS; i++)
1456 paulis[i] = PAULI_X;
1459 int inv = GENERATE( -1, NUM_QUBITS );
1460 qb1[GENERATE_COPY(range(0,numQb))] = inv;
1462 REQUIRE_THROWS_WITH( multiControlledMultiRotatePauli(qureg, qb1, numQb, qb2, paulis, numQb, param), ContainsSubstring(
"Invalid control") );
1463 REQUIRE_THROWS_WITH( multiControlledMultiRotatePauli(qureg, qb2, numQb, qb1, paulis, numQb, param), ContainsSubstring(
"Invalid index") || ContainsSubstring(
"exceeds the maximum") );
1466 CLEANUP_TEST( quregVec, quregMatr );
1477 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
1480 SECTION(
"correctness" ) {
1483 int numTargs = GENERATE_COPY( range(1,NUM_QUBITS) );
1484 int maxNumCtrls = NUM_QUBITS - numTargs;
1485 int numCtrls = GENERATE_COPY( range(1,maxNumCtrls+1) );
1488 int* targs = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numTargs) );
1489 int* ctrls = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numCtrls, targs, numTargs) );
1494 for (
int t=0; t<numTargs-1; t++)
1500 SECTION(
"state-vector" ) {
1502 multiControlledMultiRotateZ(quregVec, ctrls, numCtrls, targs, numTargs, param);
1504 REQUIRE(
areEqual(quregVec, refVec) );
1506 SECTION(
"density-matrix" ) {
1508 multiControlledMultiRotateZ(quregMatr, ctrls, numCtrls, targs, numTargs, param);
1510 REQUIRE(
areEqual(quregMatr, refMatr, 2*REAL_EPS) );
1513 SECTION(
"input validation" ) {
1518 Qureg regs[] = {quregVec, quregMatr};
1519 Qureg qureg = regs[GENERATE(0,1)];
1521 SECTION(
"number of targets" ) {
1525 int numTargs = GENERATE( -1, 0, NUM_QUBITS+1 );
1527 int targs[NUM_QUBITS+1];
1530 REQUIRE_THROWS_WITH( multiControlledMultiRotateZ(qureg, ctrls, numCtrls, targs, numTargs, param), ContainsSubstring(
"number of target qubits") );
1532 SECTION(
"repetition in targets" ) {
1537 int targs[] = {1,2,2};
1539 REQUIRE_THROWS_WITH( multiControlledMultiRotateZ(qureg, ctrls, numCtrls, targs, numTargs, param), ContainsSubstring(
"target") && ContainsSubstring(
"unique"));
1541 SECTION(
"number of controls" ) {
1544 int numCtrls = GENERATE( -1, NUM_QUBITS+1 );
1546 int ctrls[NUM_QUBITS+1];
1547 for (
int i=0; i<NUM_QUBITS+1; i++)
1551 REQUIRE_THROWS_WITH( multiControlledMultiRotateZ(qureg, ctrls, numCtrls, targs, numTargs, param), ContainsSubstring(
"number of control qubits"));
1553 SECTION(
"repetition in controls" ) {
1557 int ctrls[] = {0,1,1};
1560 REQUIRE_THROWS_WITH( multiControlledMultiRotateZ(qureg, ctrls, numCtrls, targs, numTargs, param), ContainsSubstring(
"control") && ContainsSubstring(
"unique"));
1562 SECTION(
"control and target collision" ) {
1566 int ctrls[] = {0,1,2};
1567 int targs[] = {3,1,4};
1569 REQUIRE_THROWS_WITH( multiControlledMultiRotateZ(qureg, ctrls, numCtrls, targs, numTargs, param), ContainsSubstring(
"control and target"));
1571 SECTION(
"qubit indices" ) {
1579 int inv = GENERATE( -1, NUM_QUBITS );
1580 qb1[GENERATE_COPY(range(0,numQb))] = inv;
1582 REQUIRE_THROWS_WITH( multiControlledMultiRotateZ(qureg, qb1, numQb, qb2, numQb, param), ContainsSubstring(
"Invalid control") );
1583 REQUIRE_THROWS_WITH( multiControlledMultiRotateZ(qureg, qb2, numQb, qb1, numQb, param), ContainsSubstring(
"Invalid target") );
1586 CLEANUP_TEST( quregVec, quregMatr );
1597 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
1602 SECTION(
"correctness" ) {
1605 int numCtrls = GENERATE( range(1,NUM_QUBITS) );
1606 int* ctrls = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numCtrls) );
1608 SECTION(
"state-vector" ) {
1610 multiControlledPhaseFlip(quregVec, ctrls, numCtrls);
1612 REQUIRE(
areEqual(quregVec, refVec) );
1614 SECTION(
"density-matrix" ) {
1616 multiControlledPhaseFlip(quregMatr, ctrls, numCtrls);
1618 REQUIRE(
areEqual(quregMatr, refMatr) );
1621 SECTION(
"input validation" ) {
1623 SECTION(
"number of targets" ) {
1628 int numCtrls = GENERATE( -1, NUM_QUBITS+1 );
1629 int ctrls[NUM_QUBITS+1];
1630 REQUIRE_THROWS_WITH( multiControlledPhaseFlip(quregVec, ctrls, numCtrls), ContainsSubstring(
"number of target qubits"));
1632 SECTION(
"repetition of targets" ) {
1635 int ctrls[] = {0,1,1};
1636 REQUIRE_THROWS_WITH( multiControlledPhaseFlip(quregVec, ctrls, numCtrls), ContainsSubstring(
"qubits must be unique"));
1638 SECTION(
"qubit indices" ) {
1641 int ctrls[] = { 1, 2, GENERATE( -1, NUM_QUBITS ) };
1642 REQUIRE_THROWS_WITH( multiControlledPhaseFlip(quregVec, ctrls, numCtrls), ContainsSubstring(
"Invalid target qubit") );
1645 CLEANUP_TEST( quregVec, quregMatr );
1656 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
1658 QMatrix op{{1,0},{0,expI(param)}};
1660 SECTION(
"correctness" ) {
1663 int numCtrls = GENERATE( range(1,NUM_QUBITS) );
1664 int* ctrls = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numCtrls) );
1666 SECTION(
"state-vector" ) {
1668 multiControlledPhaseShift(quregVec, ctrls, numCtrls, param);
1670 REQUIRE(
areEqual(quregVec, refVec) );
1672 SECTION(
"density-matrix" ) {
1674 multiControlledPhaseShift(quregMatr, ctrls, numCtrls, param);
1676 REQUIRE(
areEqual(quregMatr, refMatr, 2*REAL_EPS) );
1679 SECTION(
"input validation" ) {
1683 SECTION(
"number of targets" ) {
1686 int numCtrls = GENERATE( -1, NUM_QUBITS+1 );
1687 int ctrls[NUM_QUBITS+1];
1688 REQUIRE_THROWS_WITH( multiControlledPhaseShift(quregVec, ctrls, numCtrls, param), ContainsSubstring(
"number of target qubits"));
1690 SECTION(
"repetition of targets" ) {
1693 int ctrls[] = {0,1,1};
1694 REQUIRE_THROWS_WITH( multiControlledPhaseShift(quregVec, ctrls, numCtrls, param), ContainsSubstring(
"qubits must be unique"));
1696 SECTION(
"qubit indices" ) {
1699 int ctrls[] = { 1, 2, GENERATE( -1, NUM_QUBITS ) };
1700 REQUIRE_THROWS_WITH( multiControlledPhaseShift(quregVec, ctrls, numCtrls, param), ContainsSubstring(
"Invalid target qubit") );
1703 CLEANUP_TEST( quregVec, quregMatr );
1712TEST_CASE(
"multiControlledTwoQubitUnitary",
"[unitaries]" ) {
1714 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
1717 REQUIRE( quregVec.numAmpsPerNode >= 4 );
1723 SECTION(
"correctness" ) {
1726 int targ1 = GENERATE( range(0,NUM_QUBITS) );
1727 int targ2 = GENERATE_COPY( filter([=](
int t){
return t!=targ1; }, range(0,NUM_QUBITS)) );
1728 int targs[] = {targ1, targ2};
1729 int numCtrls = GENERATE( range(1,NUM_QUBITS-1) );
1730 int* ctrls = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numCtrls, targs, 2) );
1732 SECTION(
"state-vector" ) {
1734 multiControlledTwoQubitUnitary(quregVec, ctrls, numCtrls, targ1, targ2, matr);
1736 REQUIRE(
areEqual(quregVec, refVec) );
1738 SECTION(
"density-matrix" ) {
1740 multiControlledTwoQubitUnitary(quregMatr, ctrls, numCtrls, targ1, targ2, matr);
1742 REQUIRE(
areEqual(quregMatr, refMatr, 10*REAL_EPS) );
1745 SECTION(
"input validation" ) {
1747 SECTION(
"number of controls" ) {
1752 int numCtrls = GENERATE( -1, NUM_QUBITS+1 );
1753 int ctrls[NUM_QUBITS+1];
1754 REQUIRE_THROWS_WITH( multiControlledTwoQubitUnitary(quregVec, ctrls, numCtrls, 0, 1, matr), ContainsSubstring(
"number of control qubits"));
1756 SECTION(
"repetition of controls" ) {
1759 int ctrls[] = {0,1,1};
1762 REQUIRE_THROWS_WITH( multiControlledTwoQubitUnitary(quregVec, ctrls, numCtrls, targ1, targ2, matr), ContainsSubstring(
"control") && ContainsSubstring(
"unique"));;
1764 SECTION(
"repetition of targets" ) {
1767 int ctrls[] = {0,1,2};
1770 REQUIRE_THROWS_WITH( multiControlledTwoQubitUnitary(quregVec, ctrls, numCtrls, targ1, targ2, matr), ContainsSubstring(
"target") && ContainsSubstring(
"unique"));
1772 SECTION(
"control and target collision" ) {
1775 int ctrls[] = {0,1,2};
1777 int targ2 = ctrls[GENERATE_COPY( range(0,numCtrls) )];
1778 REQUIRE_THROWS_WITH( multiControlledTwoQubitUnitary(quregVec, ctrls, numCtrls, targ1, targ2, matr), ContainsSubstring(
"control and target") );
1780 SECTION(
"qubit indices" ) {
1786 int ctrls[] = { 2, 3, 4 };
1788 int inv = GENERATE( -1, NUM_QUBITS );
1789 REQUIRE_THROWS_WITH( multiControlledTwoQubitUnitary(quregVec, ctrls, numCtrls, inv, targ2, matr), ContainsSubstring(
"Invalid target") );
1790 REQUIRE_THROWS_WITH( multiControlledTwoQubitUnitary(quregVec, ctrls, numCtrls, targ1, inv, matr), ContainsSubstring(
"Invalid target") );
1792 ctrls[numCtrls-1] = inv;
1793 REQUIRE_THROWS_WITH( multiControlledTwoQubitUnitary(quregVec, ctrls, numCtrls, targ1, targ2, matr), ContainsSubstring(
"Invalid control") );
1795 SECTION(
"unitarity " ) {
1798 matr.real[0][0] = 99999;
1799 REQUIRE_THROWS_WITH( multiControlledTwoQubitUnitary(quregVec, ctrls, 1, 1, 2, matr), ContainsSubstring(
"unitary") );
1801 SECTION(
"unitary fits in node" ) {
1804 quregVec.isDistributed = 1;
1805 quregVec.numAmpsPerNode = 1;
1806 quregVec.logNumAmpsPerNode = 0;
1809 REQUIRE_THROWS_WITH( multiControlledTwoQubitUnitary(quregVec, ctrls, 1, 1, 2, matr), ContainsSubstring(
"communication buffer") && ContainsSubstring(
"simultaneously store"));
1812 CLEANUP_TEST( quregVec, quregMatr );
1823 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
1829 SECTION(
"correctness" ) {
1831 int target = GENERATE( range(0,NUM_QUBITS) );
1832 int numCtrls = GENERATE( range(1,NUM_QUBITS) );
1833 int* ctrls = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numCtrls, target) );
1835 SECTION(
"state-vector" ) {
1837 multiControlledUnitary(quregVec, ctrls, numCtrls, target, matr);
1839 REQUIRE(
areEqual(quregVec, refVec) );
1841 SECTION(
"density-matrix" ) {
1843 multiControlledUnitary(quregMatr, ctrls, numCtrls, target, matr);
1845 REQUIRE(
areEqual(quregMatr, refMatr, 10*REAL_EPS) );
1848 SECTION(
"input validation" ) {
1850 SECTION(
"number of controls" ) {
1853 int numCtrls = GENERATE( -1, NUM_QUBITS+1 );
1854 int ctrls[NUM_QUBITS+1];
1855 REQUIRE_THROWS_WITH( multiControlledUnitary(quregVec, ctrls, numCtrls, 0, matr), ContainsSubstring(
"number of control qubits"));
1857 SECTION(
"repetition of controls" ) {
1859 int ctrls[] = {0,1,1};
1860 REQUIRE_THROWS_WITH( multiControlledUnitary(quregVec, ctrls, 3, 2, matr), ContainsSubstring(
"control") && ContainsSubstring(
"unique"));
1862 SECTION(
"control and target collision" ) {
1864 int ctrls[] = {0,1,2};
1865 int targ = ctrls[GENERATE( range(0,3) )];
1866 REQUIRE_THROWS_WITH( multiControlledUnitary(quregVec, ctrls, 3, targ, matr), ContainsSubstring(
"control and target") );
1868 SECTION(
"qubit indices" ) {
1870 int ctrls[] = { 1, 2, GENERATE( -1, NUM_QUBITS ) };
1871 REQUIRE_THROWS_WITH( multiControlledUnitary(quregVec, ctrls, 3, 0, matr), ContainsSubstring(
"Invalid control") );
1874 int targ = GENERATE( -1, NUM_QUBITS );
1875 REQUIRE_THROWS_WITH( multiControlledUnitary(quregVec, ctrls, 3, targ, matr), ContainsSubstring(
"Invalid target") );
1877 SECTION(
"unitarity" ) {
1879 matr.real[0][0] = 9999;
1881 REQUIRE_THROWS_WITH( multiControlledUnitary(quregVec, ctrls, 1, 1, matr), ContainsSubstring(
"unitary") );
1884 CLEANUP_TEST( quregVec, quregMatr );
1895 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
1897 SECTION(
"correctness" ) {
1900 int numTargs = GENERATE_COPY( range(1,NUM_QUBITS+1) );
1903 int* targs = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numTargs) );
1908 SECTION(
"state-vector" ) {
1910 multiQubitNot(quregVec, targs, numTargs);
1911 for (
int t=0; t<numTargs; t++)
1914 REQUIRE(
areEqual(quregVec, refVec) );
1916 SECTION(
"density-matrix" ) {
1918 multiQubitNot(quregMatr, targs, numTargs);
1919 for (
int t=0; t<numTargs; t++)
1922 REQUIRE(
areEqual(quregMatr, refMatr) );
1925 SECTION(
"input validation" ) {
1927 SECTION(
"number of targets" ) {
1930 int numTargs = GENERATE( -1, 0, NUM_QUBITS+1 );
1931 int targs[NUM_QUBITS+1];
1932 REQUIRE_THROWS_WITH( multiQubitNot(quregVec, targs, numTargs), ContainsSubstring(
"number of target qubits"));
1934 SECTION(
"repetition in targets" ) {
1937 int targs[] = {1,2,2};
1938 REQUIRE_THROWS_WITH( multiQubitNot(quregVec, targs, numTargs), ContainsSubstring(
"target") && ContainsSubstring(
"unique"));
1940 SECTION(
"target indices" ) {
1944 int qubits[] = {0,1,2,3,4};
1947 qubits[GENERATE_COPY(range(0,numQb))] = GENERATE( -1, NUM_QUBITS );
1948 REQUIRE_THROWS_WITH( multiQubitNot(quregVec, qubits, numQb), ContainsSubstring(
"Invalid target") );
1951 CLEANUP_TEST( quregVec, quregMatr );
1962 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
1965 int maxNumTargs =
calcLog2(quregVec.numAmpsPerNode);
1967 SECTION(
"correctness" ) {
1970 int numTargs = GENERATE_COPY( range(1,maxNumTargs+1) );
1971 int* targs = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numTargs) );
1975 ComplexMatrixN matr = createComplexMatrixN(numTargs);
1978 SECTION(
"state-vector" ) {
1980 multiQubitUnitary(quregVec, targs, numTargs, matr);
1982 REQUIRE(
areEqual(quregVec, refVec) );
1984 SECTION(
"density-matrix" ) {
1986 multiQubitUnitary(quregMatr, targs, numTargs, matr);
1988 REQUIRE(
areEqual(quregMatr, refMatr, 10*REAL_EPS) );
1990 destroyComplexMatrixN(matr);
1992 SECTION(
"input validation" ) {
1994 SECTION(
"number of targets" ) {
1997 int numTargs = GENERATE( -1, 0, NUM_QUBITS+1 );
1998 int targs[NUM_QUBITS+1];
1999 ComplexMatrixN matr = createComplexMatrixN(NUM_QUBITS+1);
2002 REQUIRE_THROWS_WITH( multiQubitUnitary(quregVec, targs, numTargs, matr), ContainsSubstring(
"number of target qubits"));
2003 destroyComplexMatrixN(matr);
2005 SECTION(
"repetition in targets" ) {
2008 int targs[] = {1,2,2};
2009 ComplexMatrixN matr = createComplexMatrixN(numTargs);
2012 REQUIRE_THROWS_WITH( multiQubitUnitary(quregVec, targs, numTargs, matr), ContainsSubstring(
"target") && ContainsSubstring(
"unique"));
2013 destroyComplexMatrixN(matr);
2015 SECTION(
"qubit indices" ) {
2018 int targs[] = {1,2,3};
2019 ComplexMatrixN matr = createComplexMatrixN(numTargs);
2022 int inv = GENERATE( -1, NUM_QUBITS );
2023 targs[GENERATE_COPY( range(0,numTargs) )] = inv;
2024 REQUIRE_THROWS_WITH( multiQubitUnitary(quregVec, targs, numTargs, matr), ContainsSubstring(
"Invalid target") );
2026 destroyComplexMatrixN(matr);
2028 SECTION(
"unitarity" ) {
2030 int numTargs = GENERATE_COPY( range(1,maxNumTargs) );
2031 int targs[NUM_QUBITS];
2032 for (
int i=0; i<numTargs; i++)
2035 ComplexMatrixN matr = createComplexMatrixN(numTargs);
2038 REQUIRE_THROWS_WITH( multiQubitUnitary(quregVec, targs, numTargs, matr), ContainsSubstring(
"unitary") );
2039 destroyComplexMatrixN(matr);
2041 SECTION(
"unitary creation" ) {
2044 int targs[] = {1,2,3};
2046 ComplexMatrixN matr;
2047 matr.cpuElems = NULL;
2048 REQUIRE_THROWS_WITH( multiQubitUnitary(quregVec, targs, numTargs, matr), ContainsSubstring(
"created") );
2050 SECTION(
"unitary dimensions" ) {
2052 int targs[2] = {1,2};
2053 ComplexMatrixN matr = createComplexMatrixN(3);
2056 REQUIRE_THROWS_WITH( multiQubitUnitary(quregVec, targs, 2, matr), ContainsSubstring(
"matrix has an inconsistent size"));
2057 destroyComplexMatrixN(matr);
2059 SECTION(
"unitary fits in node" ) {
2062 quregVec.isDistributed = 1;
2063 quregVec.numAmpsPerNode = 1;
2064 quregVec.logNumAmpsPerNode = 0;
2067 ComplexMatrixN matr = createComplexMatrixN(2);
2068 for (
int i=0; i<4; i++)
2069 matr.cpuElems[i][i] = 1;
2072 REQUIRE_THROWS_WITH( multiQubitUnitary(quregVec, qb, 2, matr), ContainsSubstring(
"communication buffer") && ContainsSubstring(
"simultaneously store"));
2073 destroyComplexMatrixN(matr);
2076 CLEANUP_TEST( quregVec, quregMatr );
2087 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
2090 SECTION(
"correctness" ) {
2092 int numTargs = GENERATE( range(1,NUM_QUBITS+1) );
2093 int* targs = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numTargs) );
2100 GENERATE( range(0,10) );
2101 pauliOpType paulis[NUM_QUBITS];
2102 for (
int i=0; i<numTargs; i++)
2106 int refTargs[NUM_QUBITS];
2107 int numRefTargs = 0;
2110 QMatrix yMatr{{0,-qcomp(0,1)},{qcomp(0,1),0}};
2115 for (
int i=0; i<numTargs; i++) {
2117 if (paulis[i] == PAULI_I)
continue;
2118 if (paulis[i] == PAULI_X) fac = xMatr;
2119 if (paulis[i] == PAULI_Y) fac = yMatr;
2120 if (paulis[i] == PAULI_Z) fac = zMatr;
2124 refTargs[numRefTargs++] = targs[i];
2129 if (numRefTargs > 0)
2132 SECTION(
"state-vector" ) {
2134 multiRotatePauli(quregVec, targs, paulis, numTargs, param);
2135 if (numRefTargs > 0)
2137 REQUIRE(
areEqual(quregVec, refVec) );
2139 SECTION(
"density-matrix" ) {
2141 multiRotatePauli(quregMatr, targs, paulis, numTargs, param);
2142 if (numRefTargs > 0)
2144 REQUIRE(
areEqual(quregMatr, refMatr, 10*REAL_EPS) );
2147 SECTION(
"input validation" ) {
2149 SECTION(
"number of targets" ) {
2151 int numTargs = GENERATE( -1, 0, NUM_QUBITS+1 );
2152 int targs[NUM_QUBITS+1];
2153 for (
int i=0; i<NUM_QUBITS+1; i++)
2155 pauliOpType paulis[NUM_QUBITS+1];
2156 for (
int i=0; i<NUM_QUBITS+1; i++)
2157 paulis[i] = PAULI_X;
2159 REQUIRE_THROWS_WITH( multiRotatePauli(quregVec, targs, paulis, numTargs, param), (ContainsSubstring(
"Pauli operator") && ContainsSubstring(
"exceeds the maximum target")) || ContainsSubstring(
"Invalid number of Paulis") );
2161 SECTION(
"repetition of targets" ) {
2164 int targs[3] = {0, 1, 1};
2165 pauliOpType paulis[3] = {PAULI_X, PAULI_X, PAULI_X};
2166 REQUIRE_THROWS_WITH( multiRotatePauli(quregVec, targs, paulis, numTargs, param), ContainsSubstring(
"Pauli indices contained a duplicate"));
2168 SECTION(
"qubit indices" ) {
2171 int targs[3] = {0, 1, 2};
2172 targs[GENERATE_COPY(range(0,numTargs))] = GENERATE( -1, NUM_QUBITS );
2173 pauliOpType paulis[NUM_QUBITS];
2174 for (
int i=0; i<NUM_QUBITS; i++)
2175 paulis[i] = PAULI_X;
2177 REQUIRE_THROWS_WITH( multiRotatePauli(quregVec, targs, paulis, numTargs, param), (ContainsSubstring(
"non-identity Pauli operator") && ContainsSubstring(
"exceeds the maximum")) || ContainsSubstring(
"Invalid index"));
2179 SECTION(
"pauli codes" ) {
2181 int targs[3] = {0, 1, 2};
2182 pauliOpType paulis[3] = {PAULI_X, PAULI_X, PAULI_X};
2183 paulis[GENERATE_COPY(range(0,numTargs))] = (pauliOpType) GENERATE( -1, 4 );
2184 REQUIRE_THROWS_WITH( multiRotatePauli(quregVec, targs, paulis, numTargs, param), ContainsSubstring(
"invalid Pauli code"));
2187 CLEANUP_TEST( quregVec, quregMatr );
2198 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
2201 SECTION(
"correctness" ) {
2203 int numTargs = GENERATE( range(1,NUM_QUBITS+1) );
2204 int* targs = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numTargs) );
2209 for (
int t=0; t<numTargs-1; t++)
2213 QMatrix expArg = qcomp(0, -param/2) *
2220 int allQubits[NUM_QUBITS];
2221 for (
int i=0; i<NUM_QUBITS; i++)
2224 SECTION(
"state-vector" ) {
2226 multiRotateZ(quregVec, targs, numTargs, param);
2228 REQUIRE(
areEqual(quregVec, refVec) );
2230 SECTION(
"density-matrix" ) {
2232 multiRotateZ(quregMatr, targs, numTargs, param);
2234 REQUIRE(
areEqual(quregMatr, refMatr, 2*REAL_EPS) );
2237 SECTION(
"input validation" ) {
2239 SECTION(
"number of targets" ) {
2241 int numTargs = GENERATE( -1, 0, NUM_QUBITS+1 );
2242 int targs[NUM_QUBITS+1];
2243 REQUIRE_THROWS_WITH( multiRotateZ(quregVec, targs, numTargs, param), ContainsSubstring(
"number of target qubits"));
2246 SECTION(
"repetition of targets" ) {
2249 int targs[3] = {0, 1, 1};
2250 REQUIRE_THROWS_WITH( multiRotateZ(quregVec, targs, numTargs, param), ContainsSubstring(
"target") && ContainsSubstring(
"unique"));
2252 SECTION(
"qubit indices" ) {
2255 int targs[3] = {0, 1, 2};
2256 targs[GENERATE_COPY(range(0,numTargs))] = GENERATE( -1, NUM_QUBITS );
2257 REQUIRE_THROWS_WITH( multiRotateZ(quregVec, targs, numTargs, param), ContainsSubstring(
"Invalid target"));
2260 CLEANUP_TEST( quregVec, quregMatr );
2271 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
2280 SECTION(
"correctness" ) {
2282 int target = GENERATE( range(0,NUM_QUBITS) );
2283 int numCtrls = GENERATE( range(1,NUM_QUBITS) );
2284 int* ctrls = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numCtrls, target) );
2285 int* ctrlState = GENERATE_COPY(
bitsets(numCtrls) );
2287 SECTION(
"state-vector" ) {
2289 multiStateControlledUnitary(quregVec, ctrls, ctrlState, numCtrls, target, matr);
2292 for (
int i=0; i<numCtrls; i++)
2293 if (ctrlState[i] == 0)
2296 for (
int i=0; i<numCtrls; i++)
2297 if (ctrlState[i] == 0)
2300 REQUIRE(
areEqual(quregVec, refVec) );
2302 SECTION(
"density-matrix" ) {
2304 multiStateControlledUnitary(quregMatr, ctrls, ctrlState, numCtrls, target, matr);
2307 for (
int i=0; i<numCtrls; i++)
2308 if (ctrlState[i] == 0)
2311 for (
int i=0; i<numCtrls; i++)
2312 if (ctrlState[i] == 0)
2315 REQUIRE(
areEqual(quregMatr, refMatr, 10*REAL_EPS) );
2318 SECTION(
"input validation" ) {
2320 SECTION(
"number of controls" ) {
2323 int numCtrls = GENERATE( -1, NUM_QUBITS+1 );
2324 int ctrls[NUM_QUBITS+1];
2325 int ctrlState[NUM_QUBITS+1] = {0};
2326 REQUIRE_THROWS_WITH( multiStateControlledUnitary(quregVec, ctrls, ctrlState, numCtrls, 0, matr), ContainsSubstring(
"number of control qubits"));
2328 SECTION(
"repetition of controls" ) {
2330 int ctrls[] = {0,1,1};
2331 int ctrlState[] = {0, 1, 0};
2332 REQUIRE_THROWS_WITH( multiStateControlledUnitary(quregVec, ctrls, ctrlState, 3, 2, matr), ContainsSubstring(
"control") && ContainsSubstring(
"unique"));
2334 SECTION(
"control and target collision" ) {
2336 int ctrls[] = {0,1,2};
2337 int ctrlState[] = {0, 1, 0};
2338 int targ = ctrls[GENERATE( range(0,3) )];
2339 REQUIRE_THROWS_WITH( multiStateControlledUnitary(quregVec, ctrls, ctrlState, 3, targ, matr), ContainsSubstring(
"control and target") );
2341 SECTION(
"qubit indices" ) {
2343 int ctrls[] = { 1, 2, GENERATE( -1, NUM_QUBITS ) };
2344 int ctrlState[] = {0, 1, 0};
2345 REQUIRE_THROWS_WITH( multiStateControlledUnitary(quregVec, ctrls, ctrlState, 3, 0, matr), ContainsSubstring(
"Invalid control") );
2348 int targ = GENERATE( -1, NUM_QUBITS );
2349 REQUIRE_THROWS_WITH( multiStateControlledUnitary(quregVec, ctrls, ctrlState, 3, targ, matr), ContainsSubstring(
"Invalid target") );
2351 SECTION(
"unitarity" ) {
2353 matr.real[0][0] = 99999;
2355 int ctrlState[1] = {0};
2356 REQUIRE_THROWS_WITH( multiStateControlledUnitary(quregVec, ctrls, ctrlState, 1, 1, matr), ContainsSubstring(
"unitary") );
2358 SECTION(
"control state bits" ) {
2361 int ctrls[] = {0, 1, 2};
2362 int ctrlState[] = {0, 0, 0};
2366 ctrlState[2] = GENERATE(-1, 2);
2367 REQUIRE_THROWS_WITH( multiStateControlledUnitary(quregVec, ctrls, ctrlState, 3, targ, matr), ContainsSubstring(
"state") );
2370 CLEANUP_TEST( quregVec, quregMatr );
2538 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
2549 qreal c = cos(param/2);
2550 qreal s = sin(param/2);
2551 qreal m = sqrt(vec.x*vec.x + vec.y*vec.y + vec.z*vec.z);
2554 QMatrix op{{c - (qcomp(0,1)*vec.z*s)/m, -((vec.y + qcomp(0,1)*vec.x)*s)/m},
2555 {((vec.y - qcomp(0,1)*vec.x)*s)/m, c + (qcomp(0,1)*vec.z*s)/m}};
2557 SECTION(
"correctness" ) {
2559 int target = GENERATE( range(0,NUM_QUBITS) );
2561 SECTION(
"state-vector ") {
2563 rotateAroundAxis(quregVec, target, param, vec);
2565 REQUIRE(
areEqual(quregVec, refVec, 10*REAL_EPS) );
2567 SECTION(
"density-matrix" ) {
2569 rotateAroundAxis(quregMatr, target, param, vec);
2571 REQUIRE(
areEqual(quregMatr, refMatr, 100*REAL_EPS) );
2574 SECTION(
"input validation" ) {
2576 SECTION(
"qubit indices" ) {
2578 int target = GENERATE( -1, NUM_QUBITS );
2579 REQUIRE_THROWS_WITH( rotateAroundAxis(quregVec, target, param, vec), ContainsSubstring(
"Invalid target") );
2581 SECTION(
"zero rotation axis" ) {
2584 vec.x=0; vec.y=0; vec.z=0;
2585 REQUIRE_THROWS_WITH( rotateAroundAxis(quregVec, target, param, vec), ContainsSubstring(
"axis") && ContainsSubstring(
"zero") );
2588 CLEANUP_TEST( quregVec, quregMatr );
2599 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
2602 {cos(param/2), - sin(param/2)*qcomp(0,1)},
2603 {- sin(param/2)*qcomp(0,1), cos(param/2)}};
2605 SECTION(
"correctness" ) {
2607 int target = GENERATE( range(0,NUM_QUBITS) );
2609 SECTION(
"state-vector ") {
2611 rotateX(quregVec, target, param);
2613 REQUIRE(
areEqual(quregVec, refVec) );
2615 SECTION(
"density-matrix" ) {
2617 rotateX(quregMatr, target, param);
2619 REQUIRE(
areEqual(quregMatr, refMatr, 2*REAL_EPS) );
2622 SECTION(
"input validation" ) {
2624 SECTION(
"qubit indices" ) {
2626 int target = GENERATE( -1, NUM_QUBITS );
2627 REQUIRE_THROWS_WITH( rotateX(quregVec, target, param), ContainsSubstring(
"Invalid target") );
2630 CLEANUP_TEST( quregVec, quregMatr );
2760 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
2761 qcomp a = qcomp(.5, .5);
2762 qcomp b = qcomp(.5, -.5);
2763 QMatrix op{{1,0,0,0},{0,a,b,0},{0,b,a,0},{0,0,0,1}};
2765 SECTION(
"correctness" ) {
2767 int targ1 = GENERATE( range(0,NUM_QUBITS) );
2768 int targ2 = GENERATE_COPY( filter([=](
int t){
return t!=targ1; }, range(0,NUM_QUBITS)) );
2769 int targs[] = {targ1, targ2};
2771 SECTION(
"state-vector" ) {
2773 sqrtSwapGate(quregVec, targ1, targ2);
2775 REQUIRE(
areEqual(quregVec, refVec) );
2777 SECTION(
"density-matrix" ) {
2779 sqrtSwapGate(quregMatr, targ1, targ2);
2781 REQUIRE(
areEqual(quregMatr, refMatr) );
2784 SECTION(
"input validation" ) {
2786 SECTION(
"qubit indices" ) {
2788 int targ1 = GENERATE( -1, NUM_QUBITS );
2790 REQUIRE_THROWS_WITH( sqrtSwapGate(quregVec, targ1, targ2), ContainsSubstring(
"Invalid target") );
2791 REQUIRE_THROWS_WITH( sqrtSwapGate(quregVec, targ2, targ1), ContainsSubstring(
"Invalid target") );
2793 SECTION(
"repetition of targets" ) {
2796 REQUIRE_THROWS_WITH( sqrtSwapGate(quregVec, qb, qb), ContainsSubstring(
"target") && ContainsSubstring(
"unique") );
2799 CLEANUP_TEST( quregVec, quregMatr );
2810 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
2811 QMatrix op{{1,0,0,0},{0,0,1,0},{0,1,0,0},{0,0,0,1}};
2813 SECTION(
"correctness" ) {
2815 int targ1 = GENERATE( range(0,NUM_QUBITS) );
2816 int targ2 = GENERATE_COPY( filter([=](
int t){
return t!=targ1; }, range(0,NUM_QUBITS)) );
2817 int targs[] = {targ1, targ2};
2819 SECTION(
"state-vector" ) {
2821 swapGate(quregVec, targ1, targ2);
2823 REQUIRE(
areEqual(quregVec, refVec) );
2825 SECTION(
"density-matrix" ) {
2827 swapGate(quregMatr, targ1, targ2);
2829 REQUIRE(
areEqual(quregMatr, refMatr) );
2832 SECTION(
"input validation" ) {
2834 SECTION(
"qubit indices" ) {
2836 int targ1 = GENERATE( -1, NUM_QUBITS );
2838 REQUIRE_THROWS_WITH( swapGate(quregVec, targ1, targ2), ContainsSubstring(
"Invalid target") );
2839 REQUIRE_THROWS_WITH( swapGate(quregVec, targ2, targ1), ContainsSubstring(
"Invalid target") );
2841 SECTION(
"repetition of targets" ) {
2844 REQUIRE_THROWS_WITH( swapGate(quregVec, qb, qb), ContainsSubstring(
"target") && ContainsSubstring(
"unique") );
2847 CLEANUP_TEST( quregVec, quregMatr );
2897 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
2900 REQUIRE( quregVec.numAmpsPerNode >= 4 );
2906 SECTION(
"correctness" ) {
2908 int targ1 = GENERATE( range(0,NUM_QUBITS) );
2909 int targ2 = GENERATE_COPY( filter([=](
int t){
return t!=targ1; }, range(0,NUM_QUBITS)) );
2910 int targs[] = {targ1, targ2};
2912 SECTION(
"state-vector" ) {
2914 twoQubitUnitary(quregVec, targ1, targ2, matr);
2916 REQUIRE(
areEqual(quregVec, refVec) );
2918 SECTION(
"density-matrix" ) {
2920 twoQubitUnitary(quregMatr, targ1, targ2, matr);
2922 REQUIRE(
areEqual(quregMatr, refMatr, 10*REAL_EPS) );
2925 SECTION(
"input validation" ) {
2927 SECTION(
"qubit indices" ) {
2929 int targ1 = GENERATE( -1, NUM_QUBITS );
2931 REQUIRE_THROWS_WITH( twoQubitUnitary(quregVec, targ1, targ2, matr), ContainsSubstring(
"Invalid target") );
2932 REQUIRE_THROWS_WITH( twoQubitUnitary(quregVec, targ2, targ1, matr), ContainsSubstring(
"Invalid target") );
2934 SECTION(
"repetition of targets" ) {
2937 REQUIRE_THROWS_WITH( twoQubitUnitary(quregVec, qb, qb, matr), ContainsSubstring(
"target") && ContainsSubstring(
"unique") );
2939 SECTION(
"unitarity" ) {
2941 matr.real[0][0] = 9999;
2942 REQUIRE_THROWS_WITH( twoQubitUnitary(quregVec, 0, 1, matr), ContainsSubstring(
"unitary") );
2944 SECTION(
"unitary fits in node" ) {
2947 quregVec.isDistributed = 1;
2948 quregVec.numAmpsPerNode = 1;
2949 quregVec.logNumAmpsPerNode = 0;
2950 REQUIRE_THROWS_WITH( twoQubitUnitary(quregVec, 0, 1, matr), ContainsSubstring(
"communication buffer") && ContainsSubstring(
"cannot simultaneously store") );
2953 CLEANUP_TEST( quregVec, quregMatr );