Skip to content

Commit c39c6cc

Browse files
author
Keefe Huang
committed
Add tests for CCZ, CRZ, MCRZ and MCZ
1 parent 894add1 commit c39c6cc

File tree

2 files changed

+165
-4
lines changed

2 files changed

+165
-4
lines changed

src/zx/FunctionalityConstruction.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,7 @@ void FunctionalityConstruction::addCrz(ZXDiagram& diag,
333333
const PiExpression& phase,
334334
const Qubit control, const Qubit target,
335335
std::vector<Vertex>& qubits) {
336+
// CRZ decomposition uses reversed CNOT direction
336337
addCnot(diag, target, control, qubits);
337338
addZSpider(diag, control, qubits, -phase / 2);
338339
addZSpider(diag, target, qubits, phase / 2);
@@ -392,9 +393,10 @@ void FunctionalityConstruction::addMcx(ZXDiagram& diag,
392393
});
393394
if (it == qubits.end()) {
394395
throw ZXException("No ancilla qubit available for MCX decomposition");
395-
} else {
396-
anc = static_cast<Qubit>(*it);
397-
}
396+
}
397+
398+
anc = static_cast<Qubit>(*it);
399+
398400
controls.pop_back();
399401
second.push_back(anc);
400402

test/zx/test_zx_functionality.cpp

Lines changed: 160 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,54 @@ TEST_F(ZXFunctionalityTest, CRZ) {
244244
EXPECT_TRUE(d.connected(d.getInput(0), d.getOutput(0)));
245245
}
246246

247+
TEST_F(ZXFunctionalityTest, MultiCZ) {
248+
using namespace qc::literals;
249+
qc = qc::QuantumComputation(3);
250+
qc.mcz({1, 2}, 0);
251+
252+
auto qcPrime = qc::QuantumComputation(3);
253+
qcPrime.h(0);
254+
qcPrime.mcx({1, 2}, 0);
255+
qcPrime.h(0);
256+
257+
auto d = FunctionalityConstruction::buildFunctionality(&qc);
258+
259+
auto dPrime = FunctionalityConstruction::buildFunctionality(&qcPrime);
260+
261+
d.concat(dPrime.invert());
262+
263+
fullReduce(d);
264+
265+
EXPECT_TRUE(d.isIdentity());
266+
EXPECT_TRUE(d.globalPhaseIsZero());
267+
EXPECT_TRUE(d.connected(d.getInput(0), d.getOutput(0)));
268+
}
269+
TEST_F(ZXFunctionalityTest, CCZ) {
270+
using namespace qc::literals;
271+
const std::string testfile = "OPENQASM 2.0;"
272+
"include \"qelib1.inc\";"
273+
"qreg q[3];"
274+
"ccz q[0],q[1],q[2];\n";
275+
276+
qc = qasm3::Importer::imports(testfile);
277+
auto qcPrime = qc::QuantumComputation(3);
278+
qcPrime.h(0);
279+
qcPrime.mcx({1, 2}, 0);
280+
qcPrime.h(0);
281+
282+
auto d = FunctionalityConstruction::buildFunctionality(&qc);
283+
284+
auto dPrime = FunctionalityConstruction::buildFunctionality(&qcPrime);
285+
286+
d.concat(dPrime.invert());
287+
288+
fullReduce(d);
289+
290+
EXPECT_TRUE(d.isIdentity());
291+
EXPECT_TRUE(d.globalPhaseIsZero());
292+
EXPECT_TRUE(d.connected(d.getInput(0), d.getOutput(0)));
293+
}
294+
247295
TEST_F(ZXFunctionalityTest, MultiControlX) {
248296
using namespace qc::literals;
249297
qc = qc::QuantumComputation(4);
@@ -333,7 +381,75 @@ TEST_F(ZXFunctionalityTest, MultiControlX1) {
333381
EXPECT_TRUE(d.connected(d.getInput(0), d.getOutput(0)));
334382
}
335383

336-
TEST_F(ZXFunctionalityTest, MultiCRZ) {
384+
TEST_F(ZXFunctionalityTest, MultiControlZ) {
385+
using namespace qc::literals;
386+
qc = qc::QuantumComputation(4);
387+
qc.mcz({1, 2, 3}, 0);
388+
389+
auto qcPrime = qc::QuantumComputation(4);
390+
qcPrime.h(0);
391+
qcPrime.mcx({1, 2, 3}, 0);
392+
qcPrime.h(0);
393+
394+
auto d = FunctionalityConstruction::buildFunctionality(&qc);
395+
396+
auto dPrime = FunctionalityConstruction::buildFunctionality(&qcPrime);
397+
398+
d.concat(dPrime.invert());
399+
400+
fullReduce(d);
401+
402+
EXPECT_TRUE(d.isIdentity());
403+
EXPECT_TRUE(d.globalPhaseIsZero());
404+
EXPECT_TRUE(d.connected(d.getInput(0), d.getOutput(0)));
405+
EXPECT_TRUE(d.connected(d.getInput(1), d.getOutput(1)));
406+
EXPECT_TRUE(d.connected(d.getInput(2), d.getOutput(2)));
407+
}
408+
409+
TEST_F(ZXFunctionalityTest, MultiControlZ0) {
410+
using namespace qc::literals;
411+
qc = qc::QuantumComputation(1);
412+
qc.mcz({}, 0);
413+
414+
auto qcPrime = qc::QuantumComputation(1);
415+
qcPrime.z(0);
416+
417+
auto d = FunctionalityConstruction::buildFunctionality(&qc);
418+
419+
auto dPrime = FunctionalityConstruction::buildFunctionality(&qcPrime);
420+
421+
d.concat(dPrime.invert());
422+
423+
fullReduce(d);
424+
425+
EXPECT_TRUE(d.isIdentity());
426+
EXPECT_TRUE(d.globalPhaseIsZero());
427+
EXPECT_TRUE(d.connected(d.getInput(0), d.getOutput(0)));
428+
}
429+
430+
TEST_F(ZXFunctionalityTest, MultiControlZ1) {
431+
using namespace qc::literals;
432+
qc = qc::QuantumComputation(2);
433+
qc.mcz({1}, 0);
434+
435+
auto qcPrime = qc::QuantumComputation(2);
436+
qcPrime.cz(1, 0);
437+
438+
auto d = FunctionalityConstruction::buildFunctionality(&qc);
439+
440+
auto dPrime = FunctionalityConstruction::buildFunctionality(&qcPrime);
441+
442+
d.concat(dPrime.invert());
443+
444+
fullReduce(d);
445+
446+
EXPECT_TRUE(d.isIdentity());
447+
EXPECT_TRUE(d.globalPhaseIsZero());
448+
EXPECT_TRUE(d.connected(d.getInput(0), d.getOutput(0)));
449+
}
450+
451+
452+
TEST_F(ZXFunctionalityTest, MultiControlRZ) {
337453
using namespace qc::literals;
338454
qc = qc::QuantumComputation(3);
339455
qc.mcrz(PI / 4, {1, 2}, 0);
@@ -348,6 +464,49 @@ TEST_F(ZXFunctionalityTest, MultiCRZ) {
348464
EXPECT_TRUE(d.connected(d.getInput(0), d.getOutput(0)));
349465
}
350466

467+
TEST_F(ZXFunctionalityTest, MultiControlRZ0) {
468+
using namespace qc::literals;
469+
qc = qc::QuantumComputation(1);
470+
qc.mcrz(PI / 4, {}, 0);
471+
472+
auto qcPrime = qc::QuantumComputation(1);
473+
qcPrime.rz(PI / 4, 0);
474+
475+
auto d = FunctionalityConstruction::buildFunctionality(&qc);
476+
477+
auto dPrime = FunctionalityConstruction::buildFunctionality(&qcPrime);
478+
479+
d.concat(dPrime.invert());
480+
481+
fullReduce(d);
482+
483+
EXPECT_TRUE(d.isIdentity());
484+
EXPECT_TRUE(d.globalPhaseIsZero());
485+
EXPECT_TRUE(d.connected(d.getInput(0), d.getOutput(0)));
486+
}
487+
488+
TEST_F(ZXFunctionalityTest, MultiControlRZ1) {
489+
using namespace qc::literals;
490+
qc = qc::QuantumComputation(2);
491+
qc.mcrz(PI / 4, {1}, 0);
492+
493+
auto qcPrime = qc::QuantumComputation(2);
494+
qcPrime.crz(PI / 4, 1, 0);
495+
496+
auto d = FunctionalityConstruction::buildFunctionality(&qc);
497+
498+
auto dPrime = FunctionalityConstruction::buildFunctionality(&qcPrime);
499+
500+
d.concat(dPrime.invert());
501+
502+
fullReduce(d);
503+
504+
EXPECT_TRUE(d.isIdentity());
505+
EXPECT_TRUE(d.globalPhaseIsZero());
506+
EXPECT_TRUE(d.connected(d.getInput(0), d.getOutput(0)));
507+
}
508+
509+
351510
TEST_F(ZXFunctionalityTest, UnsupportedControl) {
352511
using namespace qc::literals;
353512
qc = qc::QuantumComputation(2);

0 commit comments

Comments
 (0)