53 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
56 qcomp b = sqrt(1-abs(a)*abs(a)) * expI(
getRandomReal(0,2*M_PI));
57 Complex alpha; alpha.real = real(a); alpha.imag = imag(a);
58 Complex beta; beta.real = real(b); beta.imag = imag(b);
63 SECTION(
"correctness" ) {
65 int target = GENERATE( range(0,NUM_QUBITS) );
67 SECTION(
"state-vector" ) {
69 compactUnitary(quregVec, target, alpha, beta);
71 REQUIRE(
areEqual(quregVec, refVec) );
73 SECTION(
"density-matrix" ) {
75 compactUnitary(quregMatr, target, alpha, beta);
77 REQUIRE(
areEqual(quregMatr, refMatr, 10*REAL_EPS) );
80 SECTION(
"input validation" ) {
82 SECTION(
"qubit indices" ) {
84 int target = GENERATE( -1, NUM_QUBITS );
85 REQUIRE_THROWS_WITH( compactUnitary(quregVec, target, alpha, beta), ContainsSubstring(
"Invalid target") );
87 SECTION(
"unitarity" ) {
90 alpha.real=1; alpha.imag=2;
91 beta.real=3; beta.imag=4;
92 REQUIRE_THROWS_WITH( compactUnitary(quregVec, 0, alpha, beta), ContainsSubstring(
"unitary") );
95 CLEANUP_TEST( quregVec, quregMatr );
106 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
108 SECTION(
"correctness" ) {
111 int numTargs = GENERATE( range(1,NUM_QUBITS+1) );
112 int* targs = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numTargs) );
115 SubDiagonalOp op = createSubDiagonalOp(numTargs);
116 for (
long long int i=0; i<op.numElems; i++) {
119 op.cpuElems[i] = elem;
125 SECTION(
"state-vector" ) {
127 diagonalUnitary(quregVec, targs, numTargs, op);
129 REQUIRE(
areEqual(quregVec, refVec) );
131 SECTION(
"density-matrix" ) {
133 diagonalUnitary(quregMatr, targs, numTargs, op);
135 REQUIRE(
areEqual(quregMatr, refMatr, 100*REAL_EPS) );
138 destroySubDiagonalOp(op);
140 SECTION(
"input validation" ) {
142 SECTION(
"diagonal dimension" ) {
145 SubDiagonalOp op = createSubDiagonalOp(numTargs);
148 int badNumTargs = GENERATE_COPY( numTargs-1, numTargs+1 );
149 int badTargs[NUM_QUBITS+1];
150 for (
int i=0; i<NUM_QUBITS+1; i++)
153 REQUIRE_THROWS_WITH( diagonalUnitary(quregVec, badTargs, badNumTargs, op), ContainsSubstring(
"matrix has an inconsistent size") );
154 destroySubDiagonalOp(op);
156 SECTION(
"number of targets" ) {
159 SubDiagonalOp badOp = createSubDiagonalOp(NUM_QUBITS + 1);
160 int targs[NUM_QUBITS + 1];
161 for (
int t=0; t<badOp.numQubits; t++)
163 for (
int i=0; i<badOp.numElems; i++)
164 badOp.cpuElems[i] = 1;
167 REQUIRE_THROWS_WITH( diagonalUnitary(quregVec, targs, badOp.numQubits, badOp), ContainsSubstring(
"number of target qubits") );
168 destroySubDiagonalOp(badOp);
170 SECTION(
"repetition in targets" ) {
173 SubDiagonalOp op = createSubDiagonalOp(3);
174 for (
int i=0; i<op.numElems; i++)
179 int targs[] = {2,1,2};
181 REQUIRE_THROWS_WITH( diagonalUnitary(quregVec, targs, op.numQubits, op), ContainsSubstring(
"target qubits contained duplicates") );
182 destroySubDiagonalOp(op);
184 SECTION(
"qubit indices" ) {
187 SubDiagonalOp op = createSubDiagonalOp(3);
188 for (
int i=0; i<op.numElems; i++)
192 int targs[] = {0,1,2};
195 int badIndex = GENERATE( range(0,3) );
196 int badValue = GENERATE( -1, NUM_QUBITS );
197 targs[badIndex] = badValue;
199 REQUIRE_THROWS_WITH( diagonalUnitary(quregVec, targs, op.numQubits, op), ContainsSubstring(
"Invalid target qubit") );
200 destroySubDiagonalOp(op);
202 SECTION(
"unitarity" ) {
205 SubDiagonalOp op = createSubDiagonalOp(3);
206 int targs[] = {0,1,2};
207 for (
int i=0; i<op.numElems; i++)
212 op.cpuElems[2] = -9999.1;
213 REQUIRE_THROWS_WITH( diagonalUnitary(quregVec, targs, op.numQubits, op), ContainsSubstring(
"unitary") );
217 op.cpuElems[3] = -9999.5;
218 REQUIRE_THROWS_WITH( diagonalUnitary(quregVec, targs, op.numQubits, op), ContainsSubstring(
"unitary") );
220 destroySubDiagonalOp(op);
223 CLEANUP_TEST( quregVec, quregMatr );
234 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
237 qcomp b = sqrt(1-abs(a)*abs(a)) * expI(
getRandomReal(0,2*M_PI));
238 Complex alpha; alpha.real = real(a); alpha.imag = imag(a);
239 Complex beta; beta.real = real(b); beta.imag = imag(b);
244 SECTION(
"correctness" ) {
246 int target = GENERATE( range(0,NUM_QUBITS) );
247 int control = GENERATE_COPY( filter([=](
int c){
return c!=target; }, range(0,NUM_QUBITS)) );
249 SECTION(
"state-vector" ) {
251 controlledCompactUnitary(quregVec, control, target, alpha, beta);
253 REQUIRE(
areEqual(quregVec, refVec) );
255 SECTION(
"density-matrix" ) {
257 controlledCompactUnitary(quregMatr, control, target, alpha, beta);
259 REQUIRE(
areEqual(quregMatr, refMatr, 10*REAL_EPS) );
262 SECTION(
"input validation" ) {
264 SECTION(
"control and target collision" ) {
267 REQUIRE_THROWS_WITH( controlledCompactUnitary(quregVec, qb, qb, alpha, beta), ContainsSubstring(
"control and target") );
269 SECTION(
"qubit indices" ) {
271 int qb = GENERATE( -1, NUM_QUBITS );
272 REQUIRE_THROWS_WITH( controlledCompactUnitary(quregVec, qb, 0, alpha, beta), ContainsSubstring(
"Invalid control") );
273 REQUIRE_THROWS_WITH( controlledCompactUnitary(quregVec, 0, qb, alpha, beta), ContainsSubstring(
"Invalid target") );
275 SECTION(
"unitarity" ) {
278 alpha.real=1; alpha.imag=2;
279 beta.real=3; beta.imag=4;
280 REQUIRE_THROWS_WITH( controlledCompactUnitary(quregVec, 0, 1, alpha, beta), ContainsSubstring(
"unitary") );
283 CLEANUP_TEST( quregVec, quregMatr );
292TEST_CASE(
"controlledMultiQubitUnitary",
"[unitaries]" ) {
294 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
297 int maxNumTargs =
calcLog2(quregVec.numAmpsPerNode);
298 if (maxNumTargs >= NUM_QUBITS)
299 maxNumTargs = NUM_QUBITS - 1;
301 SECTION(
"correctness" ) {
304 int ctrl = GENERATE( range(0,NUM_QUBITS) );
305 int numTargs = GENERATE_COPY( range(1,maxNumTargs+1) );
306 int* targs = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numTargs, ctrl) );
310 ComplexMatrixN matr = createComplexMatrixN(numTargs);
313 SECTION(
"state-vector" ) {
315 controlledMultiQubitUnitary(quregVec, ctrl, targs, numTargs, matr);
317 REQUIRE(
areEqual(quregVec, refVec) );
319 SECTION(
"density-matrix" ) {
321 controlledMultiQubitUnitary(quregMatr, ctrl, targs, numTargs, matr);
323 REQUIRE(
areEqual(quregMatr, refMatr, 10*REAL_EPS) );
325 destroyComplexMatrixN(matr);
327 SECTION(
"input validation" ) {
329 SECTION(
"number of targets" ) {
333 int numTargs = GENERATE( -1, 0, NUM_QUBITS+1 );
334 int targs[NUM_QUBITS+1];
335 ComplexMatrixN matr = createComplexMatrixN(NUM_QUBITS+1);
338 REQUIRE_THROWS_WITH( controlledMultiQubitUnitary(quregVec, 0, targs, numTargs, matr), ContainsSubstring(
"number of target qubits"));
340 destroyComplexMatrixN(matr);
342 SECTION(
"repetition in targets" ) {
346 int targs[] = {1,2,2};
347 ComplexMatrixN matr = createComplexMatrixN(numTargs);
350 REQUIRE_THROWS_WITH( controlledMultiQubitUnitary(quregVec, ctrl, targs, numTargs, matr), ContainsSubstring(
"target") && ContainsSubstring(
"unique"));
351 destroyComplexMatrixN(matr);
353 SECTION(
"control and target collision" ) {
356 int targs[] = {0,1,2};
357 int ctrl = targs[GENERATE_COPY( range(0,numTargs) )];
358 ComplexMatrixN matr = createComplexMatrixN(numTargs);
361 REQUIRE_THROWS_WITH( controlledMultiQubitUnitary(quregVec, ctrl, targs, numTargs, matr), ContainsSubstring(
"control and target"));
362 destroyComplexMatrixN(matr);
364 SECTION(
"qubit indices" ) {
368 int targs[] = {1,2,3};
369 ComplexMatrixN matr = createComplexMatrixN(numTargs);
372 int inv = GENERATE( -1, NUM_QUBITS );
374 REQUIRE_THROWS_WITH( controlledMultiQubitUnitary(quregVec, ctrl, targs, numTargs, matr), ContainsSubstring(
"Invalid control") );
377 targs[GENERATE_COPY( range(0,numTargs) )] = inv;
378 REQUIRE_THROWS_WITH( controlledMultiQubitUnitary(quregVec, ctrl, targs, numTargs, matr), ContainsSubstring(
"Invalid target") );
380 destroyComplexMatrixN(matr);
382 SECTION(
"unitarity" ) {
385 int numTargs = GENERATE_COPY( range(1,maxNumTargs+1) );
386 ComplexMatrixN matr = createComplexMatrixN(numTargs);
389 int targs[NUM_QUBITS];
390 for (
int i=0; i<numTargs; i++)
393 REQUIRE_THROWS_WITH( controlledMultiQubitUnitary(quregVec, ctrl, targs, numTargs, matr), ContainsSubstring(
"unitary") );
394 destroyComplexMatrixN(matr);
396 SECTION(
"unitary creation" ) {
399 int targs[] = {1,2,3};
402 matr.cpuElems = NULL;
403 REQUIRE_THROWS_WITH( controlledMultiQubitUnitary(quregVec, 0, targs, numTargs, matr), ContainsSubstring(
"created") );
405 SECTION(
"unitary dimensions" ) {
408 int targs[2] = {1,2};
409 ComplexMatrixN matr = createComplexMatrixN(3);
412 REQUIRE_THROWS_WITH( controlledMultiQubitUnitary(quregVec, ctrl, targs, 2, matr), ContainsSubstring(
"matrix has an inconsistent size"));
413 destroyComplexMatrixN(matr);
415 SECTION(
"unitary fits in node" ) {
418 quregVec.isDistributed = 1;
419 quregVec.numAmpsPerNode = 1;
420 quregVec.logNumAmpsPerNode = 0;
423 ComplexMatrixN matr = createComplexMatrixN(2);
424 for (
int i=0; i<4; i++)
425 matr.cpuElems[i][i] = 1;
428 REQUIRE_THROWS_WITH( controlledMultiQubitUnitary(quregVec, 0, qb, 2, matr), ContainsSubstring(
"communication buffer") && ContainsSubstring(
"simultaneously store"));
429 destroyComplexMatrixN(matr);
432 CLEANUP_TEST( quregVec, quregMatr );
443 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
446 SECTION(
"correctness" ) {
448 int target = GENERATE( range(0,NUM_QUBITS) );
449 int control = GENERATE_COPY( filter([=](
int c){
return c!=target; }, range(0,NUM_QUBITS)) );
451 SECTION(
"state-vector" ) {
453 controlledNot(quregVec, control, target);
455 REQUIRE(
areEqual(quregVec, refVec) );
457 SECTION(
"density-matrix" ) {
459 controlledNot(quregMatr, control, target);
461 REQUIRE(
areEqual(quregMatr, refMatr) );
464 SECTION(
"input validation" ) {
466 SECTION(
"control and target collision" ) {
468 int qb = GENERATE( range(0,NUM_QUBITS) );
469 REQUIRE_THROWS_WITH( controlledNot(quregVec, qb, qb), ContainsSubstring(
"control and target") );
471 SECTION(
"qubit indices" ) {
473 int qb = GENERATE( -1, NUM_QUBITS );
474 REQUIRE_THROWS_WITH( controlledNot(quregVec, qb, 0), ContainsSubstring(
"Invalid control") );
475 REQUIRE_THROWS_WITH( controlledNot(quregVec, 0, qb), ContainsSubstring(
"Invalid target") );
478 CLEANUP_TEST( quregVec, quregMatr );
489 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
490 QMatrix op{{0,-qcomp(0,1)},{qcomp(0,1),0}};
492 SECTION(
"correctness" ) {
494 int target = GENERATE( range(0,NUM_QUBITS) );
495 int control = GENERATE_COPY( filter([=](
int c){
return c!=target; }, range(0,NUM_QUBITS)) );
497 SECTION(
"state-vector" ) {
499 controlledPauliY(quregVec, control, target);
501 REQUIRE(
areEqual(quregVec, refVec) );
503 SECTION(
"density-matrix" ) {
505 controlledPauliY(quregMatr, control, target);
507 REQUIRE(
areEqual(quregMatr, refMatr) );
510 SECTION(
"input validation" ) {
512 SECTION(
"control and target collision" ) {
514 int qb = GENERATE( range(0,NUM_QUBITS) );
515 REQUIRE_THROWS_WITH( controlledPauliY(quregVec, qb, qb), ContainsSubstring(
"control and target") );
517 SECTION(
"qubit indices" ) {
519 int qb = GENERATE( -1, NUM_QUBITS );
520 REQUIRE_THROWS_WITH( controlledPauliY(quregVec, qb, 0), ContainsSubstring(
"Invalid control") );
521 REQUIRE_THROWS_WITH( controlledPauliY(quregVec, 0, qb), ContainsSubstring(
"Invalid target") );
524 CLEANUP_TEST( quregVec, quregMatr );
535 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
538 SECTION(
"correctness" ) {
540 int target = GENERATE( range(0,NUM_QUBITS) );
541 int control = GENERATE_COPY( filter([=](
int c){
return c!=target; }, range(0,NUM_QUBITS)) );
543 SECTION(
"state-vector" ) {
545 controlledPhaseFlip(quregVec, control, target);
547 REQUIRE(
areEqual(quregVec, refVec) );
549 SECTION(
"density-matrix" ) {
551 controlledPhaseFlip(quregMatr, control, target);
553 REQUIRE(
areEqual(quregMatr, refMatr) );
556 SECTION(
"input validation" ) {
560 SECTION(
"target collision" ) {
562 int qb = GENERATE( range(0,NUM_QUBITS) );
563 REQUIRE_THROWS_WITH( controlledPhaseFlip(quregVec, qb, qb), ContainsSubstring(
"target qubits contained duplicates") );
566 SECTION(
"target indices" ) {
568 int qb = GENERATE( -1, NUM_QUBITS );
569 REQUIRE_THROWS_WITH( controlledPhaseFlip(quregVec, qb, 0), ContainsSubstring(
"Invalid target") );
570 REQUIRE_THROWS_WITH( controlledPhaseFlip(quregVec, 0, qb), ContainsSubstring(
"Invalid target") );
573 CLEANUP_TEST( quregVec, quregMatr );
584 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
586 QMatrix op{{1,0},{0,expI(param)}};
588 SECTION(
"correctness" ) {
590 int target = GENERATE( range(0,NUM_QUBITS) );
591 int control = GENERATE_COPY( filter([=](
int c){
return c!=target; }, range(0,NUM_QUBITS)) );
593 SECTION(
"state-vector" ) {
595 controlledPhaseShift(quregVec, control, target, param);
597 REQUIRE(
areEqual(quregVec, refVec) );
599 SECTION(
"density-matrix" ) {
601 controlledPhaseShift(quregMatr, control, target, param);
603 REQUIRE(
areEqual(quregMatr, refMatr) );
606 SECTION(
"input validation" ) {
610 SECTION(
"target collision" ) {
612 int qb = GENERATE( range(0,NUM_QUBITS) );
613 REQUIRE_THROWS_WITH( controlledPhaseShift(quregVec, qb, qb, param), ContainsSubstring(
"target qubits contained duplicates") );
615 SECTION(
"qubit indices" ) {
617 int qb = GENERATE( -1, NUM_QUBITS );
618 REQUIRE_THROWS_WITH( controlledPhaseShift(quregVec, qb, 0, param), ContainsSubstring(
"Invalid target") );
619 REQUIRE_THROWS_WITH( controlledPhaseShift(quregVec, 0, qb, param), ContainsSubstring(
"Invalid target") );
622 CLEANUP_TEST( quregVec, quregMatr );
631TEST_CASE(
"controlledRotateAroundAxis",
"[unitaries]" ) {
633 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
644 qreal c = cos(param/2);
645 qreal s = sin(param/2);
646 qreal m = sqrt(vec.x*vec.x + vec.y*vec.y + vec.z*vec.z);
647 QMatrix op{{c - qcomp(0,1)*vec.z*s/m, -(vec.y + qcomp(0,1)*vec.x)*s/m},
648 {(vec.y - qcomp(0,1)*vec.x)*s/m, c + qcomp(0,1)*vec.z*s/m}};
650 SECTION(
"correctness" ) {
652 int target = GENERATE( range(0,NUM_QUBITS) );
653 int control = GENERATE_COPY( filter([=](
int c){
return c!=target; }, range(0,NUM_QUBITS)) );
655 SECTION(
"state-vector" ) {
657 controlledRotateAroundAxis(quregVec, control, target, param, vec);
659 REQUIRE(
areEqual(quregVec, refVec) );
661 SECTION(
"density-matrix" ) {
663 controlledRotateAroundAxis(quregMatr, control, target, param, vec);
665 REQUIRE(
areEqual(quregMatr, refMatr, 10*REAL_EPS) );
668 SECTION(
"input validation" ) {
670 SECTION(
"control and target collision" ) {
672 int qb = GENERATE( range(0,NUM_QUBITS) );
673 REQUIRE_THROWS_WITH( controlledRotateAroundAxis(quregVec, qb, qb, param, vec), ContainsSubstring(
"control and target") );
675 SECTION(
"qubit indices" ) {
677 int qb = GENERATE( -1, NUM_QUBITS );
678 REQUIRE_THROWS_WITH( controlledRotateAroundAxis(quregVec, qb, 0, param, vec), ContainsSubstring(
"Invalid control") );
679 REQUIRE_THROWS_WITH( controlledRotateAroundAxis(quregVec, 0, qb, param, vec), ContainsSubstring(
"Invalid target") );
681 SECTION(
"zero rotation axis" ) {
683 vec.x=0; vec.y=0; vec.z=0;
684 REQUIRE_THROWS_WITH( controlledRotateAroundAxis(quregVec, 0, 1, param, vec), ContainsSubstring(
"axis") && ContainsSubstring(
"zero") );
687 CLEANUP_TEST( quregVec, quregMatr );
698 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
701 {cos(param/2), -sin(param/2)*qcomp(0,1)},
702 {-sin(param/2)*qcomp(0,1), cos(param/2)}};
704 SECTION(
"correctness" ) {
706 int target = GENERATE( range(0,NUM_QUBITS) );
707 int control = GENERATE_COPY( filter([=](
int c){
return c!=target; }, range(0,NUM_QUBITS)) );
709 SECTION(
"state-vector" ) {
711 controlledRotateX(quregVec, control, target, param);
713 REQUIRE(
areEqual(quregVec, refVec) );
715 SECTION(
"density-matrix" ) {
717 controlledRotateX(quregMatr, control, target, param);
719 REQUIRE(
areEqual(quregMatr, refMatr) );
722 SECTION(
"input validation" ) {
724 SECTION(
"control and target collision" ) {
726 int qb = GENERATE( range(0,NUM_QUBITS) );
727 REQUIRE_THROWS_WITH( controlledRotateX(quregVec, qb, qb, param), ContainsSubstring(
"control and target") );
729 SECTION(
"qubit indices" ) {
731 int qb = GENERATE( -1, NUM_QUBITS );
732 REQUIRE_THROWS_WITH( controlledRotateX(quregVec, qb, 0, param), ContainsSubstring(
"Invalid control") );
733 REQUIRE_THROWS_WITH( controlledRotateX(quregVec, 0, qb, param), ContainsSubstring(
"Invalid target") );
736 CLEANUP_TEST( quregVec, quregMatr );
747 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
749 QMatrix op{{cos(param/2), -sin(param/2)},{sin(param/2), cos(param/2)}};
751 SECTION(
"correctness" ) {
753 int target = GENERATE( range(0,NUM_QUBITS) );
754 int control = GENERATE_COPY( filter([=](
int c){
return c!=target; }, range(0,NUM_QUBITS)) );
756 SECTION(
"state-vector" ) {
758 controlledRotateY(quregVec, control, target, param);
760 REQUIRE(
areEqual(quregVec, refVec) );
762 SECTION(
"density-matrix" ) {
764 controlledRotateY(quregMatr, control, target, param);
766 REQUIRE(
areEqual(quregMatr, refMatr, 4*REAL_EPS) );
769 SECTION(
"input validation" ) {
771 SECTION(
"control and target collision" ) {
773 int qb = GENERATE( range(0,NUM_QUBITS) );
774 REQUIRE_THROWS_WITH( controlledRotateY(quregVec, qb, qb, param), ContainsSubstring(
"control and target") );
776 SECTION(
"qubit indices" ) {
778 int qb = GENERATE( -1, NUM_QUBITS );
779 REQUIRE_THROWS_WITH( controlledRotateY(quregVec, qb, 0, param), ContainsSubstring(
"Invalid control") );
780 REQUIRE_THROWS_WITH( controlledRotateY(quregVec, 0, qb, param), ContainsSubstring(
"Invalid target") );
783 CLEANUP_TEST( quregVec, quregMatr );
794 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
796 QMatrix op{{expI(-param/2.),0},{0,expI(param/2.)}};
798 SECTION(
"correctness" ) {
800 int target = GENERATE( range(0,NUM_QUBITS) );
801 int control = GENERATE_COPY( filter([=](
int c){
return c!=target; }, range(0,NUM_QUBITS)) );
803 SECTION(
"state-vector" ) {
805 controlledRotateZ(quregVec, control, target, param);
807 REQUIRE(
areEqual(quregVec, refVec) );
809 SECTION(
"density-matrix" ) {
811 controlledRotateZ(quregMatr, control, target, param);
813 REQUIRE(
areEqual(quregMatr, refMatr, 10*REAL_EPS) );
816 SECTION(
"input validation" ) {
818 SECTION(
"control and target collision" ) {
820 int qb = GENERATE( range(0,NUM_QUBITS) );
821 REQUIRE_THROWS_WITH( controlledRotateZ(quregVec, qb, qb, param), ContainsSubstring(
"control and target") );
823 SECTION(
"qubit indices" ) {
825 int qb = GENERATE( -1, NUM_QUBITS );
826 REQUIRE_THROWS_WITH( controlledRotateZ(quregVec, qb, 0, param), ContainsSubstring(
"Invalid control") );
827 REQUIRE_THROWS_WITH( controlledRotateZ(quregVec, 0, qb, param), ContainsSubstring(
"Invalid target") );
830 CLEANUP_TEST( quregVec, quregMatr );
839TEST_CASE(
"controlledTwoQubitUnitary",
"[unitaries]" ) {
841 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
844 REQUIRE( quregVec.numAmpsPerNode >= 4 );
850 SECTION(
"correctness" ) {
852 int targ1 = GENERATE( range(0,NUM_QUBITS) );
853 int targ2 = GENERATE_COPY( filter([=](
int t){
return t!=targ1; }, range(0,NUM_QUBITS)) );
854 int control = GENERATE_COPY( filter([=](
int c){
return c!=targ1 && c!=targ2; }, range(0,NUM_QUBITS)) );
856 SECTION(
"state-vector" ) {
858 controlledTwoQubitUnitary(quregVec, control, targ1, targ2, matr);
860 REQUIRE(
areEqual(quregVec, refVec) );
862 SECTION(
"density-matrix" ) {
864 controlledTwoQubitUnitary(quregMatr, control, targ1, targ2, matr);
866 REQUIRE(
areEqual(quregMatr, refMatr, 10*REAL_EPS) );
869 SECTION(
"input validation" ) {
871 SECTION(
"repetition of targets" ) {
874 REQUIRE_THROWS_WITH( controlledTwoQubitUnitary(quregVec, ctrl, targ, targ, matr), ContainsSubstring(
"target") && ContainsSubstring(
"unique") );
876 SECTION(
"control and target collision" ) {
880 int ctrl = GENERATE( 1,2 );
881 REQUIRE_THROWS_WITH( controlledTwoQubitUnitary(quregVec, ctrl, targ1, targ2, matr), ContainsSubstring(
"control and target") );
883 SECTION(
"qubit indices" ) {
890 int qb = GENERATE( -1, NUM_QUBITS );
891 REQUIRE_THROWS_WITH( controlledTwoQubitUnitary(quregVec, qb, targ1, targ2, matr), ContainsSubstring(
"Invalid control") );
892 REQUIRE_THROWS_WITH( controlledTwoQubitUnitary(quregVec, ctrl, qb, targ2, matr), ContainsSubstring(
"Invalid target") );
893 REQUIRE_THROWS_WITH( controlledTwoQubitUnitary(quregVec, ctrl, targ1, qb, matr), ContainsSubstring(
"Invalid target") );
895 SECTION(
"unitarity" ) {
897 matr.real[0][0] = 999;
898 REQUIRE_THROWS_WITH( controlledTwoQubitUnitary(quregVec, 0, 1, 2, matr), ContainsSubstring(
"unitary") );
900 SECTION(
"unitary fits in node" ) {
903 quregVec.isDistributed = 1;
904 quregVec.numAmpsPerNode = 1;
905 quregVec.logNumAmpsPerNode = 0;
907 REQUIRE_THROWS_WITH( controlledTwoQubitUnitary(quregVec, 0, 1, 2, matr), ContainsSubstring(
"communication buffer") && ContainsSubstring(
"simultaneously store"));
910 CLEANUP_TEST( quregVec, quregMatr );
921 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
925 SECTION(
"correctness" ) {
927 int target = GENERATE( range(0,NUM_QUBITS) );
928 int control = GENERATE_COPY( filter([=](
int c){
return c!=target; }, range(0,NUM_QUBITS)) );
930 SECTION(
"state-vector" ) {
932 controlledUnitary(quregVec, control, target, matr);
934 REQUIRE(
areEqual(quregVec, refVec) );
936 SECTION(
"density-matrix" ) {
938 controlledUnitary(quregMatr, control, target, matr);
940 REQUIRE(
areEqual(quregMatr, refMatr, 10*REAL_EPS) );
943 SECTION(
"input validation" ) {
945 SECTION(
"control and target collision" ) {
947 int qb = GENERATE( range(0,NUM_QUBITS) );
948 REQUIRE_THROWS_WITH( controlledUnitary(quregVec, qb, qb, matr), ContainsSubstring(
"control and target") );
950 SECTION(
"qubit indices" ) {
952 int qb = GENERATE( -1, NUM_QUBITS );
953 REQUIRE_THROWS_WITH( controlledUnitary(quregVec, qb, 0, matr), ContainsSubstring(
"Invalid control") );
954 REQUIRE_THROWS_WITH( controlledUnitary(quregVec, 0, qb, matr), ContainsSubstring(
"Invalid target") );
956 SECTION(
"unitarity" ) {
958 matr.real[0][0] = 9999;
959 REQUIRE_THROWS_WITH( controlledUnitary(quregVec, 0, 1, matr), ContainsSubstring(
"unitary") );
962 CLEANUP_TEST( quregVec, quregMatr );
1013 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
1015 SECTION(
"correctness" ) {
1018 int numTargs = GENERATE_COPY( range(1,NUM_QUBITS) );
1019 int maxNumCtrls = NUM_QUBITS - numTargs;
1020 int numCtrls = GENERATE_COPY( range(1,maxNumCtrls+1) );
1023 int* targs = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numTargs) );
1024 int* ctrls = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numCtrls, targs, numTargs) );
1029 SECTION(
"state-vector" ) {
1031 multiControlledMultiQubitNot(quregVec, ctrls, numCtrls, targs, numTargs);
1032 for (
int t=0; t<numTargs; t++)
1035 REQUIRE(
areEqual(quregVec, refVec) );
1037 SECTION(
"density-matrix" ) {
1039 multiControlledMultiQubitNot(quregMatr, ctrls, numCtrls, targs, numTargs);
1040 for (
int t=0; t<numTargs; t++)
1043 REQUIRE(
areEqual(quregMatr, refMatr) );
1046 SECTION(
"input validation" ) {
1048 SECTION(
"number of targets" ) {
1052 int numTargs = GENERATE( -1, 0, NUM_QUBITS+1 );
1053 int targs[NUM_QUBITS+1];
1055 REQUIRE_THROWS_WITH( multiControlledMultiQubitNot(quregVec, ctrls, 1, targs, numTargs), ContainsSubstring(
"number of target qubits"));
1057 SECTION(
"repetition in targets" ) {
1061 int targs[] = {1,2,2};
1062 REQUIRE_THROWS_WITH( multiControlledMultiQubitNot(quregVec, ctrls, 1, targs, numTargs), ContainsSubstring(
"target") && ContainsSubstring(
"unique"));
1064 SECTION(
"number of controls" ) {
1067 int numCtrls = GENERATE( -1, NUM_QUBITS+1 );
1068 int ctrls[NUM_QUBITS+1];
1069 for (
int i=0; i<NUM_QUBITS+1; i++)
1072 REQUIRE_THROWS_WITH( multiControlledMultiQubitNot(quregVec, ctrls, numCtrls, targs, 1), ContainsSubstring(
"number of control qubits"));
1074 SECTION(
"repetition in controls" ) {
1076 int ctrls[] = {0,1,1};
1078 REQUIRE_THROWS_WITH( multiControlledMultiQubitNot(quregVec, ctrls, 3, targs, 1), ContainsSubstring(
"control") && ContainsSubstring(
"unique"));
1080 SECTION(
"control and target collision" ) {
1082 int ctrls[] = {0,1,2};
1083 int targs[] = {3,1,4};
1084 REQUIRE_THROWS_WITH( multiControlledMultiQubitNot(quregVec, ctrls, 3, targs, 3), ContainsSubstring(
"control and target"));
1086 SECTION(
"qubit indices" ) {
1094 int inv = GENERATE( -1, NUM_QUBITS );
1095 qb1[GENERATE_COPY(range(0,numQb))] = inv;
1097 REQUIRE_THROWS_WITH( multiControlledMultiQubitNot(quregVec, qb1, numQb, qb2, numQb), ContainsSubstring(
"Invalid control") );
1098 REQUIRE_THROWS_WITH( multiControlledMultiQubitNot(quregVec, qb2, numQb, qb1, numQb), ContainsSubstring(
"Invalid target") );
1101 CLEANUP_TEST( quregVec, quregMatr );
1110TEST_CASE(
"multiControlledMultiQubitUnitary",
"[unitaries]" ) {
1112 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
1115 int maxNumTargs =
calcLog2(quregVec.numAmpsPerNode);
1116 if (maxNumTargs >= NUM_QUBITS)
1117 maxNumTargs = NUM_QUBITS - 1;
1119 SECTION(
"correctness" ) {
1122 int numTargs = GENERATE_COPY( range(1,maxNumTargs+1) );
1123 int maxNumCtrls = NUM_QUBITS - numTargs;
1124 int numCtrls = GENERATE_COPY( range(1,maxNumCtrls+1) );
1127 int* targs = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numTargs) );
1128 int* ctrls = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numCtrls, targs, numTargs) );
1132 ComplexMatrixN matr = createComplexMatrixN(numTargs);
1135 SECTION(
"state-vector" ) {
1137 multiControlledMultiQubitUnitary(quregVec, ctrls, numCtrls, targs, numTargs, matr);
1139 REQUIRE(
areEqual(quregVec, refVec) );
1141 SECTION(
"density-matrix" ) {
1143 multiControlledMultiQubitUnitary(quregMatr, ctrls, numCtrls, targs, numTargs, matr);
1145 REQUIRE(
areEqual(quregMatr, refMatr, 10*REAL_EPS) );
1147 destroyComplexMatrixN(matr);
1149 SECTION(
"input validation" ) {
1151 SECTION(
"number of targets" ) {
1155 int numTargs = GENERATE( -1, 0, NUM_QUBITS+1 );
1156 int targs[NUM_QUBITS+1];
1158 ComplexMatrixN matr = createComplexMatrixN(NUM_QUBITS+1);
1161 REQUIRE_THROWS_WITH( multiControlledMultiQubitUnitary(quregVec, ctrls, 1, targs, numTargs, matr), ContainsSubstring(
"number of target qubits"));
1162 destroyComplexMatrixN(matr);
1164 SECTION(
"repetition in targets" ) {
1168 int targs[] = {1,2,2};
1169 ComplexMatrixN matr = createComplexMatrixN(numTargs);
1172 REQUIRE_THROWS_WITH( multiControlledMultiQubitUnitary(quregVec, ctrls, 1, targs, numTargs, matr), ContainsSubstring(
"target") && ContainsSubstring(
"unique"));
1173 destroyComplexMatrixN(matr);
1175 SECTION(
"number of controls" ) {
1178 int numCtrls = GENERATE( -1, NUM_QUBITS+1 );
1179 int ctrls[NUM_QUBITS+1];
1180 for (
int i=0; i<NUM_QUBITS+1; i++)
1183 ComplexMatrixN matr = createComplexMatrixN(1);
1186 REQUIRE_THROWS_WITH( multiControlledMultiQubitUnitary(quregVec, ctrls, numCtrls, targs, 1, matr), ContainsSubstring(
"number of control qubits"));
1187 destroyComplexMatrixN(matr);
1189 SECTION(
"repetition in controls" ) {
1191 int ctrls[] = {0,1,1};
1193 ComplexMatrixN matr = createComplexMatrixN(1);
1196 REQUIRE_THROWS_WITH( multiControlledMultiQubitUnitary(quregVec, ctrls, 3, targs, 1, matr), ContainsSubstring(
"control") && ContainsSubstring(
"unique"));
1197 destroyComplexMatrixN(matr);
1199 SECTION(
"control and target collision" ) {
1201 int ctrls[] = {0,1,2};
1202 int targs[] = {3,1,4};
1203 ComplexMatrixN matr = createComplexMatrixN(3);
1206 REQUIRE_THROWS_WITH( multiControlledMultiQubitUnitary(quregVec, ctrls, 3, targs, 3, matr), ContainsSubstring(
"control and target"));
1207 destroyComplexMatrixN(matr);
1209 SECTION(
"qubit indices" ) {
1215 ComplexMatrixN matr = createComplexMatrixN(numQb);
1219 int inv = GENERATE( -1, NUM_QUBITS );
1220 qb1[GENERATE_COPY(range(0,numQb))] = inv;
1222 REQUIRE_THROWS_WITH( multiControlledMultiQubitUnitary(quregVec, qb1, numQb, qb2, numQb, matr), ContainsSubstring(
"Invalid control") );
1223 REQUIRE_THROWS_WITH( multiControlledMultiQubitUnitary(quregVec, qb2, numQb, qb1, numQb, matr), ContainsSubstring(
"Invalid target") );
1224 destroyComplexMatrixN(matr);
1226 SECTION(
"unitarity" ) {
1229 int numTargs = GENERATE_COPY( range(1,maxNumTargs+1) );
1230 int targs[NUM_QUBITS];
1231 for (
int i=0; i<numTargs; i++)
1234 ComplexMatrixN matr = createComplexMatrixN(numTargs);
1237 REQUIRE_THROWS_WITH( multiControlledMultiQubitUnitary(quregVec, ctrls, 1, targs, numTargs, matr), ContainsSubstring(
"unitary") );
1239 destroyComplexMatrixN(matr);
1241 SECTION(
"unitary creation" ) {
1244 int targs[3] = {1,2,3};
1246 ComplexMatrixN matr;
1247 matr.cpuElems = NULL;
1248 REQUIRE_THROWS_WITH( multiControlledMultiQubitUnitary(quregVec, ctrls, 1, targs, 3, matr), ContainsSubstring(
"created") );
1250 SECTION(
"unitary dimensions" ) {
1253 int targs[2] = {1,2};
1254 ComplexMatrixN matr = createComplexMatrixN(3);
1257 REQUIRE_THROWS_WITH( multiControlledMultiQubitUnitary(quregVec, ctrls, 1, targs, 2, matr), ContainsSubstring(
"matrix has an inconsistent size"));
1258 destroyComplexMatrixN(matr);
1260 SECTION(
"unitary fits in node" ) {
1263 quregVec.isDistributed = 1;
1264 quregVec.numAmpsPerNode = 1;
1265 quregVec.logNumAmpsPerNode = 0;
1268 int targs[2] = {1,2};
1269 ComplexMatrixN matr = createComplexMatrixN(2);
1270 for (
int i=0; i<4; i++)
1271 matr.cpuElems[i][i] = 1;
1274 REQUIRE_THROWS_WITH( multiControlledMultiQubitUnitary(quregVec, ctrls, 1, targs, 2, matr), ContainsSubstring(
"communication buffer") && ContainsSubstring(
"simultaneously store"));
1275 destroyComplexMatrixN(matr);
1278 CLEANUP_TEST( quregVec, quregMatr );
1287TEST_CASE(
"multiControlledMultiRotatePauli",
"[unitaries]" ) {
1289 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
1292 SECTION(
"correctness" ) {
1295 int numTargs = GENERATE_COPY( range(1,NUM_QUBITS) );
1296 int maxNumCtrls = NUM_QUBITS - numTargs;
1297 int numCtrls = GENERATE_COPY( range(1,maxNumCtrls+1) );
1300 int* targs = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numTargs) );
1301 int* ctrls = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numCtrls, targs, numTargs) );
1308 pauliOpType paulis[NUM_QUBITS];
1309 for (
int i=0; i<numTargs; i++)
1313 int refTargs[NUM_QUBITS];
1314 int numRefTargs = 0;
1317 QMatrix yMatr{{0,-qcomp(0,1)},{qcomp(0,1),0}};
1322 for (
int i=0; i<numTargs; i++) {
1324 if (paulis[i] == PAULI_I)
continue;
1325 if (paulis[i] == PAULI_X) fac = xMatr;
1326 if (paulis[i] == PAULI_Y) fac = yMatr;
1327 if (paulis[i] == PAULI_Z) fac = zMatr;
1331 refTargs[numRefTargs++] = targs[i];
1336 if (numRefTargs > 0)
1337 op = getExponentialOfPauliMatrix(param, pauliProd);
1339 SECTION(
"state-vector" ) {
1341 multiControlledMultiRotatePauli(quregVec, ctrls, numCtrls, targs, paulis, numTargs, param);
1342 if (numRefTargs > 0)
1344 REQUIRE(
areEqual(quregVec, refVec) );
1346 SECTION(
"density-matrix" ) {
1348 multiControlledMultiRotatePauli(quregMatr, ctrls, numCtrls, targs, paulis, numTargs, param);
1349 if (numRefTargs > 0)
1351 REQUIRE(
areEqual(quregMatr, refMatr, 10*REAL_EPS) );
1354 SECTION(
"input validation" ) {
1359 Qureg regs[] = {quregVec, quregMatr};
1360 Qureg qureg = regs[GENERATE(0,1)];
1363 pauliOpType paulis[NUM_QUBITS+1];
1364 for (
int q=0; q<NUM_QUBITS+1; q++)
1365 paulis[q] = PAULI_I;
1367 SECTION(
"pauli codes" ) {
1372 int targs[3] = {0, 1, 2};
1375 paulis[GENERATE_COPY(range(0,numTargs))] = (pauliOpType) GENERATE( -1, 4 );
1377 REQUIRE_THROWS_WITH( multiControlledMultiRotatePauli(qureg, ctrls, numCtrls, targs, paulis, numTargs, param), ContainsSubstring(
"invalid Pauli code"));
1379 SECTION(
"number of targets" ) {
1385 int targs[NUM_QUBITS+1];
1386 for (
int i=0; i<NUM_QUBITS+1; i++)
1392 for (
int i=0; i<NUM_QUBITS; i++)
1393 paulis[i] = PAULI_X;
1395 REQUIRE_THROWS_WITH( multiControlledMultiRotatePauli(qureg, ctrls, numCtrls, targs, paulis, -1, param), ContainsSubstring(
"must contain at least one Pauli operator") );
1396 REQUIRE_THROWS_WITH( multiControlledMultiRotatePauli(qureg, ctrls, numCtrls, targs, paulis, NUM_QUBITS+1, param), ContainsSubstring(
"non-identity Pauli operator") && ContainsSubstring(
"exceeds the maximum target") );
1398 SECTION(
"repetition in targets" ) {
1403 int targs[] = {1,2,2};
1405 for (
int i=0; i<NUM_QUBITS; i++)
1406 paulis[i] = PAULI_X;
1408 REQUIRE_THROWS_WITH( multiControlledMultiRotatePauli(qureg, ctrls, numCtrls, targs, paulis, numTargs, param), ContainsSubstring(
"Pauli indices") && ContainsSubstring(
"duplicate"));
1410 SECTION(
"number of controls" ) {
1413 int numCtrls = GENERATE( -1, NUM_QUBITS+1 );
1415 int ctrls[NUM_QUBITS+1];
1416 for (
int i=0; i<NUM_QUBITS+1; i++)
1420 REQUIRE_THROWS_WITH( multiControlledMultiRotatePauli(qureg, ctrls, numCtrls, targs, paulis, numTargs, param), ContainsSubstring(
"number of control qubits"));
1422 SECTION(
"repetition in controls" ) {
1426 int ctrls[] = {0,1,1};
1429 REQUIRE_THROWS_WITH( multiControlledMultiRotatePauli(qureg, ctrls, numCtrls, targs, paulis, numTargs, param), ContainsSubstring(
"control") && ContainsSubstring(
"unique"));
1431 SECTION(
"control and target collision" ) {
1435 int ctrls[] = {0,1,2};
1436 int targs[] = {3,1,4};
1437 for (
int i=0; i<numTargs; i++)
1438 paulis[i] = PAULI_X;
1440 REQUIRE_THROWS_WITH( multiControlledMultiRotatePauli(qureg, ctrls, numCtrls, targs, paulis, numTargs, param), ContainsSubstring(
"control qubit overlaps a non-identity Pauli"));
1442 SECTION(
"qubit indices" ) {
1449 for (
int i=0; i<NUM_QUBITS; i++)
1450 paulis[i] = PAULI_X;
1453 int inv = GENERATE( -1, NUM_QUBITS );
1454 qb1[GENERATE_COPY(range(0,numQb))] = inv;
1456 REQUIRE_THROWS_WITH( multiControlledMultiRotatePauli(qureg, qb1, numQb, qb2, paulis, numQb, param), ContainsSubstring(
"Invalid control") );
1457 REQUIRE_THROWS_WITH( multiControlledMultiRotatePauli(qureg, qb2, numQb, qb1, paulis, numQb, param), ContainsSubstring(
"Invalid index") || ContainsSubstring(
"exceeds the maximum") );
1460 CLEANUP_TEST( quregVec, quregMatr );
1471 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
1474 SECTION(
"correctness" ) {
1477 int numTargs = GENERATE_COPY( range(1,NUM_QUBITS) );
1478 int maxNumCtrls = NUM_QUBITS - numTargs;
1479 int numCtrls = GENERATE_COPY( range(1,maxNumCtrls+1) );
1482 int* targs = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numTargs) );
1483 int* ctrls = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numCtrls, targs, numTargs) );
1488 for (
int t=0; t<numTargs-1; t++)
1494 SECTION(
"state-vector" ) {
1496 multiControlledMultiRotateZ(quregVec, ctrls, numCtrls, targs, numTargs, param);
1498 REQUIRE(
areEqual(quregVec, refVec) );
1500 SECTION(
"density-matrix" ) {
1502 multiControlledMultiRotateZ(quregMatr, ctrls, numCtrls, targs, numTargs, param);
1504 REQUIRE(
areEqual(quregMatr, refMatr, 2*REAL_EPS) );
1507 SECTION(
"input validation" ) {
1512 Qureg regs[] = {quregVec, quregMatr};
1513 Qureg qureg = regs[GENERATE(0,1)];
1515 SECTION(
"number of targets" ) {
1519 int numTargs = GENERATE( -1, 0, NUM_QUBITS+1 );
1521 int targs[NUM_QUBITS+1];
1524 REQUIRE_THROWS_WITH( multiControlledMultiRotateZ(qureg, ctrls, numCtrls, targs, numTargs, param), ContainsSubstring(
"number of target qubits") );
1526 SECTION(
"repetition in targets" ) {
1531 int targs[] = {1,2,2};
1533 REQUIRE_THROWS_WITH( multiControlledMultiRotateZ(qureg, ctrls, numCtrls, targs, numTargs, param), ContainsSubstring(
"target") && ContainsSubstring(
"unique"));
1535 SECTION(
"number of controls" ) {
1538 int numCtrls = GENERATE( -1, NUM_QUBITS+1 );
1540 int ctrls[NUM_QUBITS+1];
1541 for (
int i=0; i<NUM_QUBITS+1; i++)
1545 REQUIRE_THROWS_WITH( multiControlledMultiRotateZ(qureg, ctrls, numCtrls, targs, numTargs, param), ContainsSubstring(
"number of control qubits"));
1547 SECTION(
"repetition in controls" ) {
1551 int ctrls[] = {0,1,1};
1554 REQUIRE_THROWS_WITH( multiControlledMultiRotateZ(qureg, ctrls, numCtrls, targs, numTargs, param), ContainsSubstring(
"control") && ContainsSubstring(
"unique"));
1556 SECTION(
"control and target collision" ) {
1560 int ctrls[] = {0,1,2};
1561 int targs[] = {3,1,4};
1563 REQUIRE_THROWS_WITH( multiControlledMultiRotateZ(qureg, ctrls, numCtrls, targs, numTargs, param), ContainsSubstring(
"control and target"));
1565 SECTION(
"qubit indices" ) {
1573 int inv = GENERATE( -1, NUM_QUBITS );
1574 qb1[GENERATE_COPY(range(0,numQb))] = inv;
1576 REQUIRE_THROWS_WITH( multiControlledMultiRotateZ(qureg, qb1, numQb, qb2, numQb, param), ContainsSubstring(
"Invalid control") );
1577 REQUIRE_THROWS_WITH( multiControlledMultiRotateZ(qureg, qb2, numQb, qb1, numQb, param), ContainsSubstring(
"Invalid target") );
1580 CLEANUP_TEST( quregVec, quregMatr );
1591 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
1596 SECTION(
"correctness" ) {
1599 int numCtrls = GENERATE( range(1,NUM_QUBITS) );
1600 int* ctrls = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numCtrls) );
1602 SECTION(
"state-vector" ) {
1604 multiControlledPhaseFlip(quregVec, ctrls, numCtrls);
1606 REQUIRE(
areEqual(quregVec, refVec) );
1608 SECTION(
"density-matrix" ) {
1610 multiControlledPhaseFlip(quregMatr, ctrls, numCtrls);
1612 REQUIRE(
areEqual(quregMatr, refMatr) );
1615 SECTION(
"input validation" ) {
1617 SECTION(
"number of targets" ) {
1622 int numCtrls = GENERATE( -1, NUM_QUBITS+1 );
1623 int ctrls[NUM_QUBITS+1];
1624 REQUIRE_THROWS_WITH( multiControlledPhaseFlip(quregVec, ctrls, numCtrls), ContainsSubstring(
"number of target qubits"));
1626 SECTION(
"repetition of targets" ) {
1629 int ctrls[] = {0,1,1};
1630 REQUIRE_THROWS_WITH( multiControlledPhaseFlip(quregVec, ctrls, numCtrls), ContainsSubstring(
"qubits must be unique"));
1632 SECTION(
"qubit indices" ) {
1635 int ctrls[] = { 1, 2, GENERATE( -1, NUM_QUBITS ) };
1636 REQUIRE_THROWS_WITH( multiControlledPhaseFlip(quregVec, ctrls, numCtrls), ContainsSubstring(
"Invalid target qubit") );
1639 CLEANUP_TEST( quregVec, quregMatr );
1650 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
1652 QMatrix op{{1,0},{0,expI(param)}};
1654 SECTION(
"correctness" ) {
1657 int numCtrls = GENERATE( range(1,NUM_QUBITS) );
1658 int* ctrls = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numCtrls) );
1660 SECTION(
"state-vector" ) {
1662 multiControlledPhaseShift(quregVec, ctrls, numCtrls, param);
1664 REQUIRE(
areEqual(quregVec, refVec) );
1666 SECTION(
"density-matrix" ) {
1668 multiControlledPhaseShift(quregMatr, ctrls, numCtrls, param);
1670 REQUIRE(
areEqual(quregMatr, refMatr, 2*REAL_EPS) );
1673 SECTION(
"input validation" ) {
1677 SECTION(
"number of targets" ) {
1680 int numCtrls = GENERATE( -1, NUM_QUBITS+1 );
1681 int ctrls[NUM_QUBITS+1];
1682 REQUIRE_THROWS_WITH( multiControlledPhaseShift(quregVec, ctrls, numCtrls, param), ContainsSubstring(
"number of target qubits"));
1684 SECTION(
"repetition of targets" ) {
1687 int ctrls[] = {0,1,1};
1688 REQUIRE_THROWS_WITH( multiControlledPhaseShift(quregVec, ctrls, numCtrls, param), ContainsSubstring(
"qubits must be unique"));
1690 SECTION(
"qubit indices" ) {
1693 int ctrls[] = { 1, 2, GENERATE( -1, NUM_QUBITS ) };
1694 REQUIRE_THROWS_WITH( multiControlledPhaseShift(quregVec, ctrls, numCtrls, param), ContainsSubstring(
"Invalid target qubit") );
1697 CLEANUP_TEST( quregVec, quregMatr );
1706TEST_CASE(
"multiControlledTwoQubitUnitary",
"[unitaries]" ) {
1708 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
1711 REQUIRE( quregVec.numAmpsPerNode >= 4 );
1717 SECTION(
"correctness" ) {
1720 int targ1 = GENERATE( range(0,NUM_QUBITS) );
1721 int targ2 = GENERATE_COPY( filter([=](
int t){
return t!=targ1; }, range(0,NUM_QUBITS)) );
1722 int targs[] = {targ1, targ2};
1723 int numCtrls = GENERATE( range(1,NUM_QUBITS-1) );
1724 int* ctrls = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numCtrls, targs, 2) );
1726 SECTION(
"state-vector" ) {
1728 multiControlledTwoQubitUnitary(quregVec, ctrls, numCtrls, targ1, targ2, matr);
1730 REQUIRE(
areEqual(quregVec, refVec) );
1732 SECTION(
"density-matrix" ) {
1734 multiControlledTwoQubitUnitary(quregMatr, ctrls, numCtrls, targ1, targ2, matr);
1736 REQUIRE(
areEqual(quregMatr, refMatr, 10*REAL_EPS) );
1739 SECTION(
"input validation" ) {
1741 SECTION(
"number of controls" ) {
1746 int numCtrls = GENERATE( -1, NUM_QUBITS+1 );
1747 int ctrls[NUM_QUBITS+1];
1748 REQUIRE_THROWS_WITH( multiControlledTwoQubitUnitary(quregVec, ctrls, numCtrls, 0, 1, matr), ContainsSubstring(
"number of control qubits"));
1750 SECTION(
"repetition of controls" ) {
1753 int ctrls[] = {0,1,1};
1756 REQUIRE_THROWS_WITH( multiControlledTwoQubitUnitary(quregVec, ctrls, numCtrls, targ1, targ2, matr), ContainsSubstring(
"control") && ContainsSubstring(
"unique"));;
1758 SECTION(
"repetition of targets" ) {
1761 int ctrls[] = {0,1,2};
1764 REQUIRE_THROWS_WITH( multiControlledTwoQubitUnitary(quregVec, ctrls, numCtrls, targ1, targ2, matr), ContainsSubstring(
"target") && ContainsSubstring(
"unique"));
1766 SECTION(
"control and target collision" ) {
1769 int ctrls[] = {0,1,2};
1771 int targ2 = ctrls[GENERATE_COPY( range(0,numCtrls) )];
1772 REQUIRE_THROWS_WITH( multiControlledTwoQubitUnitary(quregVec, ctrls, numCtrls, targ1, targ2, matr), ContainsSubstring(
"control and target") );
1774 SECTION(
"qubit indices" ) {
1780 int ctrls[] = { 2, 3, 4 };
1782 int inv = GENERATE( -1, NUM_QUBITS );
1783 REQUIRE_THROWS_WITH( multiControlledTwoQubitUnitary(quregVec, ctrls, numCtrls, inv, targ2, matr), ContainsSubstring(
"Invalid target") );
1784 REQUIRE_THROWS_WITH( multiControlledTwoQubitUnitary(quregVec, ctrls, numCtrls, targ1, inv, matr), ContainsSubstring(
"Invalid target") );
1786 ctrls[numCtrls-1] = inv;
1787 REQUIRE_THROWS_WITH( multiControlledTwoQubitUnitary(quregVec, ctrls, numCtrls, targ1, targ2, matr), ContainsSubstring(
"Invalid control") );
1789 SECTION(
"unitarity " ) {
1792 matr.real[0][0] = 99999;
1793 REQUIRE_THROWS_WITH( multiControlledTwoQubitUnitary(quregVec, ctrls, 1, 1, 2, matr), ContainsSubstring(
"unitary") );
1795 SECTION(
"unitary fits in node" ) {
1798 quregVec.isDistributed = 1;
1799 quregVec.numAmpsPerNode = 1;
1800 quregVec.logNumAmpsPerNode = 0;
1803 REQUIRE_THROWS_WITH( multiControlledTwoQubitUnitary(quregVec, ctrls, 1, 1, 2, matr), ContainsSubstring(
"communication buffer") && ContainsSubstring(
"simultaneously store"));
1806 CLEANUP_TEST( quregVec, quregMatr );
1817 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
1823 SECTION(
"correctness" ) {
1825 int target = GENERATE( range(0,NUM_QUBITS) );
1826 int numCtrls = GENERATE( range(1,NUM_QUBITS) );
1827 int* ctrls = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numCtrls, target) );
1829 SECTION(
"state-vector" ) {
1831 multiControlledUnitary(quregVec, ctrls, numCtrls, target, matr);
1833 REQUIRE(
areEqual(quregVec, refVec) );
1835 SECTION(
"density-matrix" ) {
1837 multiControlledUnitary(quregMatr, ctrls, numCtrls, target, matr);
1839 REQUIRE(
areEqual(quregMatr, refMatr, 10*REAL_EPS) );
1842 SECTION(
"input validation" ) {
1844 SECTION(
"number of controls" ) {
1847 int numCtrls = GENERATE( -1, NUM_QUBITS+1 );
1848 int ctrls[NUM_QUBITS+1];
1849 REQUIRE_THROWS_WITH( multiControlledUnitary(quregVec, ctrls, numCtrls, 0, matr), ContainsSubstring(
"number of control qubits"));
1851 SECTION(
"repetition of controls" ) {
1853 int ctrls[] = {0,1,1};
1854 REQUIRE_THROWS_WITH( multiControlledUnitary(quregVec, ctrls, 3, 2, matr), ContainsSubstring(
"control") && ContainsSubstring(
"unique"));
1856 SECTION(
"control and target collision" ) {
1858 int ctrls[] = {0,1,2};
1859 int targ = ctrls[GENERATE( range(0,3) )];
1860 REQUIRE_THROWS_WITH( multiControlledUnitary(quregVec, ctrls, 3, targ, matr), ContainsSubstring(
"control and target") );
1862 SECTION(
"qubit indices" ) {
1864 int ctrls[] = { 1, 2, GENERATE( -1, NUM_QUBITS ) };
1865 REQUIRE_THROWS_WITH( multiControlledUnitary(quregVec, ctrls, 3, 0, matr), ContainsSubstring(
"Invalid control") );
1868 int targ = GENERATE( -1, NUM_QUBITS );
1869 REQUIRE_THROWS_WITH( multiControlledUnitary(quregVec, ctrls, 3, targ, matr), ContainsSubstring(
"Invalid target") );
1871 SECTION(
"unitarity" ) {
1873 matr.real[0][0] = 9999;
1875 REQUIRE_THROWS_WITH( multiControlledUnitary(quregVec, ctrls, 1, 1, matr), ContainsSubstring(
"unitary") );
1878 CLEANUP_TEST( quregVec, quregMatr );
1889 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
1891 SECTION(
"correctness" ) {
1894 int numTargs = GENERATE_COPY( range(1,NUM_QUBITS+1) );
1897 int* targs = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numTargs) );
1902 SECTION(
"state-vector" ) {
1904 multiQubitNot(quregVec, targs, numTargs);
1905 for (
int t=0; t<numTargs; t++)
1908 REQUIRE(
areEqual(quregVec, refVec) );
1910 SECTION(
"density-matrix" ) {
1912 multiQubitNot(quregMatr, targs, numTargs);
1913 for (
int t=0; t<numTargs; t++)
1916 REQUIRE(
areEqual(quregMatr, refMatr) );
1919 SECTION(
"input validation" ) {
1921 SECTION(
"number of targets" ) {
1924 int numTargs = GENERATE( -1, 0, NUM_QUBITS+1 );
1925 int targs[NUM_QUBITS+1];
1926 REQUIRE_THROWS_WITH( multiQubitNot(quregVec, targs, numTargs), ContainsSubstring(
"number of target qubits"));
1928 SECTION(
"repetition in targets" ) {
1931 int targs[] = {1,2,2};
1932 REQUIRE_THROWS_WITH( multiQubitNot(quregVec, targs, numTargs), ContainsSubstring(
"target") && ContainsSubstring(
"unique"));
1934 SECTION(
"target indices" ) {
1938 int qubits[] = {0,1,2,3,4};
1941 qubits[GENERATE_COPY(range(0,numQb))] = GENERATE( -1, NUM_QUBITS );
1942 REQUIRE_THROWS_WITH( multiQubitNot(quregVec, qubits, numQb), ContainsSubstring(
"Invalid target") );
1945 CLEANUP_TEST( quregVec, quregMatr );
1956 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
1959 int maxNumTargs =
calcLog2(quregVec.numAmpsPerNode);
1961 SECTION(
"correctness" ) {
1964 int numTargs = GENERATE_COPY( range(1,maxNumTargs+1) );
1965 int* targs = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numTargs) );
1969 ComplexMatrixN matr = createComplexMatrixN(numTargs);
1972 SECTION(
"state-vector" ) {
1974 multiQubitUnitary(quregVec, targs, numTargs, matr);
1976 REQUIRE(
areEqual(quregVec, refVec) );
1978 SECTION(
"density-matrix" ) {
1980 multiQubitUnitary(quregMatr, targs, numTargs, matr);
1982 REQUIRE(
areEqual(quregMatr, refMatr, 10*REAL_EPS) );
1984 destroyComplexMatrixN(matr);
1986 SECTION(
"input validation" ) {
1988 SECTION(
"number of targets" ) {
1991 int numTargs = GENERATE( -1, 0, NUM_QUBITS+1 );
1992 int targs[NUM_QUBITS+1];
1993 ComplexMatrixN matr = createComplexMatrixN(NUM_QUBITS+1);
1996 REQUIRE_THROWS_WITH( multiQubitUnitary(quregVec, targs, numTargs, matr), ContainsSubstring(
"number of target qubits"));
1997 destroyComplexMatrixN(matr);
1999 SECTION(
"repetition in targets" ) {
2002 int targs[] = {1,2,2};
2003 ComplexMatrixN matr = createComplexMatrixN(numTargs);
2006 REQUIRE_THROWS_WITH( multiQubitUnitary(quregVec, targs, numTargs, matr), ContainsSubstring(
"target") && ContainsSubstring(
"unique"));
2007 destroyComplexMatrixN(matr);
2009 SECTION(
"qubit indices" ) {
2012 int targs[] = {1,2,3};
2013 ComplexMatrixN matr = createComplexMatrixN(numTargs);
2016 int inv = GENERATE( -1, NUM_QUBITS );
2017 targs[GENERATE_COPY( range(0,numTargs) )] = inv;
2018 REQUIRE_THROWS_WITH( multiQubitUnitary(quregVec, targs, numTargs, matr), ContainsSubstring(
"Invalid target") );
2020 destroyComplexMatrixN(matr);
2022 SECTION(
"unitarity" ) {
2024 int numTargs = GENERATE_COPY( range(1,maxNumTargs) );
2025 int targs[NUM_QUBITS];
2026 for (
int i=0; i<numTargs; i++)
2029 ComplexMatrixN matr = createComplexMatrixN(numTargs);
2032 REQUIRE_THROWS_WITH( multiQubitUnitary(quregVec, targs, numTargs, matr), ContainsSubstring(
"unitary") );
2033 destroyComplexMatrixN(matr);
2035 SECTION(
"unitary creation" ) {
2038 int targs[] = {1,2,3};
2040 ComplexMatrixN matr;
2041 matr.cpuElems = NULL;
2042 REQUIRE_THROWS_WITH( multiQubitUnitary(quregVec, targs, numTargs, matr), ContainsSubstring(
"created") );
2044 SECTION(
"unitary dimensions" ) {
2046 int targs[2] = {1,2};
2047 ComplexMatrixN matr = createComplexMatrixN(3);
2050 REQUIRE_THROWS_WITH( multiQubitUnitary(quregVec, targs, 2, matr), ContainsSubstring(
"matrix has an inconsistent size"));
2051 destroyComplexMatrixN(matr);
2053 SECTION(
"unitary fits in node" ) {
2056 quregVec.isDistributed = 1;
2057 quregVec.numAmpsPerNode = 1;
2058 quregVec.logNumAmpsPerNode = 0;
2061 ComplexMatrixN matr = createComplexMatrixN(2);
2062 for (
int i=0; i<4; i++)
2063 matr.cpuElems[i][i] = 1;
2066 REQUIRE_THROWS_WITH( multiQubitUnitary(quregVec, qb, 2, matr), ContainsSubstring(
"communication buffer") && ContainsSubstring(
"simultaneously store"));
2067 destroyComplexMatrixN(matr);
2070 CLEANUP_TEST( quregVec, quregMatr );
2081 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
2084 SECTION(
"correctness" ) {
2086 int numTargs = GENERATE( range(1,NUM_QUBITS+1) );
2087 int* targs = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numTargs) );
2094 GENERATE( range(0,10) );
2095 pauliOpType paulis[NUM_QUBITS];
2096 for (
int i=0; i<numTargs; i++)
2100 int refTargs[NUM_QUBITS];
2101 int numRefTargs = 0;
2104 QMatrix yMatr{{0,-qcomp(0,1)},{qcomp(0,1),0}};
2109 for (
int i=0; i<numTargs; i++) {
2111 if (paulis[i] == PAULI_I)
continue;
2112 if (paulis[i] == PAULI_X) fac = xMatr;
2113 if (paulis[i] == PAULI_Y) fac = yMatr;
2114 if (paulis[i] == PAULI_Z) fac = zMatr;
2118 refTargs[numRefTargs++] = targs[i];
2123 if (numRefTargs > 0)
2124 op = getExponentialOfPauliMatrix(param, pauliProd);
2126 SECTION(
"state-vector" ) {
2128 multiRotatePauli(quregVec, targs, paulis, numTargs, param);
2129 if (numRefTargs > 0)
2131 REQUIRE(
areEqual(quregVec, refVec) );
2133 SECTION(
"density-matrix" ) {
2135 multiRotatePauli(quregMatr, targs, paulis, numTargs, param);
2136 if (numRefTargs > 0)
2138 REQUIRE(
areEqual(quregMatr, refMatr, 10*REAL_EPS) );
2141 SECTION(
"input validation" ) {
2143 SECTION(
"number of targets" ) {
2145 int numTargs = GENERATE( -1, 0, NUM_QUBITS+1 );
2146 int targs[NUM_QUBITS+1];
2147 for (
int i=0; i<NUM_QUBITS+1; i++)
2149 pauliOpType paulis[NUM_QUBITS+1];
2150 for (
int i=0; i<NUM_QUBITS+1; i++)
2151 paulis[i] = PAULI_X;
2153 REQUIRE_THROWS_WITH( multiRotatePauli(quregVec, targs, paulis, numTargs, param), (ContainsSubstring(
"Pauli operator") && ContainsSubstring(
"exceeds the maximum target")) || ContainsSubstring(
"Invalid number of Paulis") );
2155 SECTION(
"repetition of targets" ) {
2158 int targs[3] = {0, 1, 1};
2159 pauliOpType paulis[3] = {PAULI_X, PAULI_X, PAULI_X};
2160 REQUIRE_THROWS_WITH( multiRotatePauli(quregVec, targs, paulis, numTargs, param), ContainsSubstring(
"Pauli indices contained a duplicate"));
2162 SECTION(
"qubit indices" ) {
2165 int targs[3] = {0, 1, 2};
2166 targs[GENERATE_COPY(range(0,numTargs))] = GENERATE( -1, NUM_QUBITS );
2167 pauliOpType paulis[NUM_QUBITS];
2168 for (
int i=0; i<NUM_QUBITS; i++)
2169 paulis[i] = PAULI_X;
2171 REQUIRE_THROWS_WITH( multiRotatePauli(quregVec, targs, paulis, numTargs, param), (ContainsSubstring(
"non-identity Pauli operator") && ContainsSubstring(
"exceeds the maximum")) || ContainsSubstring(
"Invalid index"));
2173 SECTION(
"pauli codes" ) {
2175 int targs[3] = {0, 1, 2};
2176 pauliOpType paulis[3] = {PAULI_X, PAULI_X, PAULI_X};
2177 paulis[GENERATE_COPY(range(0,numTargs))] = (pauliOpType) GENERATE( -1, 4 );
2178 REQUIRE_THROWS_WITH( multiRotatePauli(quregVec, targs, paulis, numTargs, param), ContainsSubstring(
"invalid Pauli code"));
2181 CLEANUP_TEST( quregVec, quregMatr );
2192 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
2195 SECTION(
"correctness" ) {
2197 int numTargs = GENERATE( range(1,NUM_QUBITS+1) );
2198 int* targs = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numTargs) );
2203 for (
int t=0; t<numTargs-1; t++)
2207 QMatrix expArg = qcomp(0, -param/2) *
2214 int allQubits[NUM_QUBITS];
2215 for (
int i=0; i<NUM_QUBITS; i++)
2218 SECTION(
"state-vector" ) {
2220 multiRotateZ(quregVec, targs, numTargs, param);
2222 REQUIRE(
areEqual(quregVec, refVec) );
2224 SECTION(
"density-matrix" ) {
2226 multiRotateZ(quregMatr, targs, numTargs, param);
2228 REQUIRE(
areEqual(quregMatr, refMatr, 2*REAL_EPS) );
2231 SECTION(
"input validation" ) {
2233 SECTION(
"number of targets" ) {
2235 int numTargs = GENERATE( -1, 0, NUM_QUBITS+1 );
2236 int targs[NUM_QUBITS+1];
2237 REQUIRE_THROWS_WITH( multiRotateZ(quregVec, targs, numTargs, param), ContainsSubstring(
"number of target qubits"));
2240 SECTION(
"repetition of targets" ) {
2243 int targs[3] = {0, 1, 1};
2244 REQUIRE_THROWS_WITH( multiRotateZ(quregVec, targs, numTargs, param), ContainsSubstring(
"target") && ContainsSubstring(
"unique"));
2246 SECTION(
"qubit indices" ) {
2249 int targs[3] = {0, 1, 2};
2250 targs[GENERATE_COPY(range(0,numTargs))] = GENERATE( -1, NUM_QUBITS );
2251 REQUIRE_THROWS_WITH( multiRotateZ(quregVec, targs, numTargs, param), ContainsSubstring(
"Invalid target"));
2254 CLEANUP_TEST( quregVec, quregMatr );
2265 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
2274 SECTION(
"correctness" ) {
2276 int target = GENERATE( range(0,NUM_QUBITS) );
2277 int numCtrls = GENERATE( range(1,NUM_QUBITS) );
2278 int* ctrls = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numCtrls, target) );
2279 int* ctrlState = GENERATE_COPY(
bitsets(numCtrls) );
2281 SECTION(
"state-vector" ) {
2283 multiStateControlledUnitary(quregVec, ctrls, ctrlState, numCtrls, target, matr);
2286 for (
int i=0; i<numCtrls; i++)
2287 if (ctrlState[i] == 0)
2290 for (
int i=0; i<numCtrls; i++)
2291 if (ctrlState[i] == 0)
2294 REQUIRE(
areEqual(quregVec, refVec) );
2296 SECTION(
"density-matrix" ) {
2298 multiStateControlledUnitary(quregMatr, ctrls, ctrlState, numCtrls, target, matr);
2301 for (
int i=0; i<numCtrls; i++)
2302 if (ctrlState[i] == 0)
2305 for (
int i=0; i<numCtrls; i++)
2306 if (ctrlState[i] == 0)
2309 REQUIRE(
areEqual(quregMatr, refMatr, 10*REAL_EPS) );
2312 SECTION(
"input validation" ) {
2314 SECTION(
"number of controls" ) {
2317 int numCtrls = GENERATE( -1, NUM_QUBITS+1 );
2318 int ctrls[NUM_QUBITS+1];
2319 int ctrlState[NUM_QUBITS+1] = {0};
2320 REQUIRE_THROWS_WITH( multiStateControlledUnitary(quregVec, ctrls, ctrlState, numCtrls, 0, matr), ContainsSubstring(
"number of control qubits"));
2322 SECTION(
"repetition of controls" ) {
2324 int ctrls[] = {0,1,1};
2325 int ctrlState[] = {0, 1, 0};
2326 REQUIRE_THROWS_WITH( multiStateControlledUnitary(quregVec, ctrls, ctrlState, 3, 2, matr), ContainsSubstring(
"control") && ContainsSubstring(
"unique"));
2328 SECTION(
"control and target collision" ) {
2330 int ctrls[] = {0,1,2};
2331 int ctrlState[] = {0, 1, 0};
2332 int targ = ctrls[GENERATE( range(0,3) )];
2333 REQUIRE_THROWS_WITH( multiStateControlledUnitary(quregVec, ctrls, ctrlState, 3, targ, matr), ContainsSubstring(
"control and target") );
2335 SECTION(
"qubit indices" ) {
2337 int ctrls[] = { 1, 2, GENERATE( -1, NUM_QUBITS ) };
2338 int ctrlState[] = {0, 1, 0};
2339 REQUIRE_THROWS_WITH( multiStateControlledUnitary(quregVec, ctrls, ctrlState, 3, 0, matr), ContainsSubstring(
"Invalid control") );
2342 int targ = GENERATE( -1, NUM_QUBITS );
2343 REQUIRE_THROWS_WITH( multiStateControlledUnitary(quregVec, ctrls, ctrlState, 3, targ, matr), ContainsSubstring(
"Invalid target") );
2345 SECTION(
"unitarity" ) {
2347 matr.real[0][0] = 99999;
2349 int ctrlState[1] = {0};
2350 REQUIRE_THROWS_WITH( multiStateControlledUnitary(quregVec, ctrls, ctrlState, 1, 1, matr), ContainsSubstring(
"unitary") );
2352 SECTION(
"control state bits" ) {
2355 int ctrls[] = {0, 1, 2};
2356 int ctrlState[] = {0, 0, 0};
2360 ctrlState[2] = GENERATE(-1, 2);
2361 REQUIRE_THROWS_WITH( multiStateControlledUnitary(quregVec, ctrls, ctrlState, 3, targ, matr), ContainsSubstring(
"state") );
2364 CLEANUP_TEST( quregVec, quregMatr );
2532 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
2543 qreal c = cos(param/2);
2544 qreal s = sin(param/2);
2545 qreal m = sqrt(vec.x*vec.x + vec.y*vec.y + vec.z*vec.z);
2548 QMatrix op{{c - (qcomp(0,1)*vec.z*s)/m, -((vec.y + qcomp(0,1)*vec.x)*s)/m},
2549 {((vec.y - qcomp(0,1)*vec.x)*s)/m, c + (qcomp(0,1)*vec.z*s)/m}};
2551 SECTION(
"correctness" ) {
2553 int target = GENERATE( range(0,NUM_QUBITS) );
2555 SECTION(
"state-vector ") {
2557 rotateAroundAxis(quregVec, target, param, vec);
2559 REQUIRE(
areEqual(quregVec, refVec, 10*REAL_EPS) );
2561 SECTION(
"density-matrix" ) {
2563 rotateAroundAxis(quregMatr, target, param, vec);
2565 REQUIRE(
areEqual(quregMatr, refMatr, 100*REAL_EPS) );
2568 SECTION(
"input validation" ) {
2570 SECTION(
"qubit indices" ) {
2572 int target = GENERATE( -1, NUM_QUBITS );
2573 REQUIRE_THROWS_WITH( rotateAroundAxis(quregVec, target, param, vec), ContainsSubstring(
"Invalid target") );
2575 SECTION(
"zero rotation axis" ) {
2578 vec.x=0; vec.y=0; vec.z=0;
2579 REQUIRE_THROWS_WITH( rotateAroundAxis(quregVec, target, param, vec), ContainsSubstring(
"axis") && ContainsSubstring(
"zero") );
2582 CLEANUP_TEST( quregVec, quregMatr );
2593 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
2596 {cos(param/2), - sin(param/2)*qcomp(0,1)},
2597 {- sin(param/2)*qcomp(0,1), cos(param/2)}};
2599 SECTION(
"correctness" ) {
2601 int target = GENERATE( range(0,NUM_QUBITS) );
2603 SECTION(
"state-vector ") {
2605 rotateX(quregVec, target, param);
2607 REQUIRE(
areEqual(quregVec, refVec) );
2609 SECTION(
"density-matrix" ) {
2611 rotateX(quregMatr, target, param);
2613 REQUIRE(
areEqual(quregMatr, refMatr, 2*REAL_EPS) );
2616 SECTION(
"input validation" ) {
2618 SECTION(
"qubit indices" ) {
2620 int target = GENERATE( -1, NUM_QUBITS );
2621 REQUIRE_THROWS_WITH( rotateX(quregVec, target, param), ContainsSubstring(
"Invalid target") );
2624 CLEANUP_TEST( quregVec, quregMatr );
2754 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
2755 qcomp a = qcomp(.5, .5);
2756 qcomp b = qcomp(.5, -.5);
2757 QMatrix op{{1,0,0,0},{0,a,b,0},{0,b,a,0},{0,0,0,1}};
2759 SECTION(
"correctness" ) {
2761 int targ1 = GENERATE( range(0,NUM_QUBITS) );
2762 int targ2 = GENERATE_COPY( filter([=](
int t){
return t!=targ1; }, range(0,NUM_QUBITS)) );
2763 int targs[] = {targ1, targ2};
2765 SECTION(
"state-vector" ) {
2767 sqrtSwapGate(quregVec, targ1, targ2);
2769 REQUIRE(
areEqual(quregVec, refVec) );
2771 SECTION(
"density-matrix" ) {
2773 sqrtSwapGate(quregMatr, targ1, targ2);
2775 REQUIRE(
areEqual(quregMatr, refMatr) );
2778 SECTION(
"input validation" ) {
2780 SECTION(
"qubit indices" ) {
2782 int targ1 = GENERATE( -1, NUM_QUBITS );
2784 REQUIRE_THROWS_WITH( sqrtSwapGate(quregVec, targ1, targ2), ContainsSubstring(
"Invalid target") );
2785 REQUIRE_THROWS_WITH( sqrtSwapGate(quregVec, targ2, targ1), ContainsSubstring(
"Invalid target") );
2787 SECTION(
"repetition of targets" ) {
2790 REQUIRE_THROWS_WITH( sqrtSwapGate(quregVec, qb, qb), ContainsSubstring(
"target") && ContainsSubstring(
"unique") );
2793 CLEANUP_TEST( quregVec, quregMatr );
2804 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
2805 QMatrix op{{1,0,0,0},{0,0,1,0},{0,1,0,0},{0,0,0,1}};
2807 SECTION(
"correctness" ) {
2809 int targ1 = GENERATE( range(0,NUM_QUBITS) );
2810 int targ2 = GENERATE_COPY( filter([=](
int t){
return t!=targ1; }, range(0,NUM_QUBITS)) );
2811 int targs[] = {targ1, targ2};
2813 SECTION(
"state-vector" ) {
2815 swapGate(quregVec, targ1, targ2);
2817 REQUIRE(
areEqual(quregVec, refVec) );
2819 SECTION(
"density-matrix" ) {
2821 swapGate(quregMatr, targ1, targ2);
2823 REQUIRE(
areEqual(quregMatr, refMatr) );
2826 SECTION(
"input validation" ) {
2828 SECTION(
"qubit indices" ) {
2830 int targ1 = GENERATE( -1, NUM_QUBITS );
2832 REQUIRE_THROWS_WITH( swapGate(quregVec, targ1, targ2), ContainsSubstring(
"Invalid target") );
2833 REQUIRE_THROWS_WITH( swapGate(quregVec, targ2, targ1), ContainsSubstring(
"Invalid target") );
2835 SECTION(
"repetition of targets" ) {
2838 REQUIRE_THROWS_WITH( swapGate(quregVec, qb, qb), ContainsSubstring(
"target") && ContainsSubstring(
"unique") );
2841 CLEANUP_TEST( quregVec, quregMatr );
2891 PREPARE_TEST( quregVec, quregMatr, refVec, refMatr );
2894 REQUIRE( quregVec.numAmpsPerNode >= 4 );
2900 SECTION(
"correctness" ) {
2902 int targ1 = GENERATE( range(0,NUM_QUBITS) );
2903 int targ2 = GENERATE_COPY( filter([=](
int t){
return t!=targ1; }, range(0,NUM_QUBITS)) );
2904 int targs[] = {targ1, targ2};
2906 SECTION(
"state-vector" ) {
2908 twoQubitUnitary(quregVec, targ1, targ2, matr);
2910 REQUIRE(
areEqual(quregVec, refVec) );
2912 SECTION(
"density-matrix" ) {
2914 twoQubitUnitary(quregMatr, targ1, targ2, matr);
2916 REQUIRE(
areEqual(quregMatr, refMatr, 10*REAL_EPS) );
2919 SECTION(
"input validation" ) {
2921 SECTION(
"qubit indices" ) {
2923 int targ1 = GENERATE( -1, NUM_QUBITS );
2925 REQUIRE_THROWS_WITH( twoQubitUnitary(quregVec, targ1, targ2, matr), ContainsSubstring(
"Invalid target") );
2926 REQUIRE_THROWS_WITH( twoQubitUnitary(quregVec, targ2, targ1, matr), ContainsSubstring(
"Invalid target") );
2928 SECTION(
"repetition of targets" ) {
2931 REQUIRE_THROWS_WITH( twoQubitUnitary(quregVec, qb, qb, matr), ContainsSubstring(
"target") && ContainsSubstring(
"unique") );
2933 SECTION(
"unitarity" ) {
2935 matr.real[0][0] = 9999;
2936 REQUIRE_THROWS_WITH( twoQubitUnitary(quregVec, 0, 1, matr), ContainsSubstring(
"unitary") );
2938 SECTION(
"unitary fits in node" ) {
2941 quregVec.isDistributed = 1;
2942 quregVec.numAmpsPerNode = 1;
2943 quregVec.logNumAmpsPerNode = 0;
2944 REQUIRE_THROWS_WITH( twoQubitUnitary(quregVec, 0, 1, matr), ContainsSubstring(
"communication buffer") && ContainsSubstring(
"cannot simultaneously store") );
2947 CLEANUP_TEST( quregVec, quregMatr );