Skip to content

Commit c381adb

Browse files
committed
🚸✅ add equality operator for QuantumComputation and respective tests
Signed-off-by: burgholzer <[email protected]>
1 parent 24b80e2 commit c381adb

File tree

3 files changed

+167
-0
lines changed

3 files changed

+167
-0
lines changed

‎include/mqt-core/ir/QuantumComputation.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,11 @@ class QuantumComputation {
420420
*/
421421
void invert();
422422

423+
[[nodiscard]] bool operator==(const QuantumComputation& rhs) const;
424+
[[nodiscard]] bool operator!=(const QuantumComputation& rhs) const {
425+
return !(*this == rhs);
426+
}
427+
423428
/**
424429
* printing
425430
*/

‎src/ir/QuantumComputation.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,31 @@ void QuantumComputation::invert() {
642642
"output permutation will not be swapped.\n";
643643
}
644644
}
645+
646+
bool QuantumComputation::operator==(const QuantumComputation& rhs) const {
647+
if (nqubits != rhs.nqubits || nancillae != rhs.nancillae ||
648+
nclassics != rhs.nclassics || qregs != rhs.qregs || cregs != rhs.cregs ||
649+
ancregs != rhs.ancregs || initialLayout != rhs.initialLayout ||
650+
outputPermutation != rhs.outputPermutation ||
651+
ancillary != rhs.ancillary || garbage != rhs.garbage ||
652+
seed != rhs.seed || globalPhase != rhs.globalPhase ||
653+
occurringVariables != rhs.occurringVariables) {
654+
return false;
655+
}
656+
657+
if (ops.size() != rhs.ops.size()) {
658+
return false;
659+
}
660+
661+
for (std::size_t i = 0; i < ops.size(); ++i) {
662+
if (*ops[i] != *rhs.ops[i]) {
663+
return false;
664+
}
665+
}
666+
667+
return true;
668+
}
669+
645670
std::ostream& QuantumComputation::print(std::ostream& os) const {
646671
os << name << "\n";
647672
const auto width =

‎test/ir/test_qfr_functionality.cpp

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1334,3 +1334,140 @@ TEST_F(QFRFunctionality, AddQubitWithoutNeighboringQubits) {
13341334
EXPECT_EQ(startMiddle, 2U);
13351335
EXPECT_EQ(sizeMiddle, 1U);
13361336
}
1337+
1338+
TEST_F(QFRFunctionality, CopyConstructor) {
1339+
QuantumComputation qc(2, 2);
1340+
qc.h(0);
1341+
qc.swap(0, 1);
1342+
qc.barrier();
1343+
qc.measure(0, 0);
1344+
qc.classicControlled(X, 0, {0, 1});
1345+
const sym::Variable theta{"theta"};
1346+
qc.rx(Symbolic{theta}, 0);
1347+
1348+
QuantumComputation compound(2, 2);
1349+
compound.h(0);
1350+
compound.cx(0, 1);
1351+
qc.emplace_back(compound.asOperation());
1352+
1353+
qc.initialLayout[0] = 1;
1354+
qc.initialLayout[1] = 0;
1355+
qc.outputPermutation[0] = 1;
1356+
qc.outputPermutation[1] = 0;
1357+
qc.gphase(0.25);
1358+
1359+
qc.setLogicalQubitAncillary(1);
1360+
qc.setLogicalQubitGarbage(1);
1361+
1362+
const auto qcCopy = qc;
1363+
EXPECT_EQ(qc, qcCopy);
1364+
}
1365+
1366+
TEST_F(QFRFunctionality, InequalityDifferentNumberOfQubits) {
1367+
// Different number of qubits
1368+
const QuantumComputation qc1(2, 2);
1369+
const QuantumComputation qc2(3, 3);
1370+
EXPECT_NE(qc1, qc2);
1371+
}
1372+
1373+
TEST_F(QFRFunctionality, InequalityDifferentInitialLayout) {
1374+
// Different initial layout
1375+
QuantumComputation qc1(2, 2);
1376+
QuantumComputation qc2(2, 2);
1377+
qc1.initialLayout[0] = 0;
1378+
qc1.initialLayout[1] = 1;
1379+
qc2.initialLayout[0] = 1;
1380+
qc2.initialLayout[1] = 0;
1381+
EXPECT_NE(qc1, qc2);
1382+
}
1383+
1384+
TEST_F(QFRFunctionality, InequalityDifferentGateOperations) {
1385+
// Different gate operations
1386+
QuantumComputation qc1(2, 2);
1387+
QuantumComputation qc2(2, 2);
1388+
qc1.h(0);
1389+
qc2.cx(0, 1); // Different operation
1390+
EXPECT_NE(qc1, qc2);
1391+
}
1392+
1393+
TEST_F(QFRFunctionality, InequalityDifferentGateOrder) {
1394+
// Same gates but different order
1395+
QuantumComputation qc1(2, 2);
1396+
QuantumComputation qc2(2, 2);
1397+
qc1.h(0);
1398+
qc1.cx(0, 1);
1399+
1400+
qc2.cx(0, 1);
1401+
qc2.h(0); // Reversed order
1402+
EXPECT_NE(qc1, qc2);
1403+
}
1404+
1405+
TEST_F(QFRFunctionality, InequalityDifferentAncillaryQubits) {
1406+
// Different ancillary qubits
1407+
QuantumComputation qc1(2, 2);
1408+
qc1.setLogicalQubitAncillary(1);
1409+
1410+
const QuantumComputation qc2(2, 2);
1411+
// No ancillary qubits in qc2
1412+
EXPECT_NE(qc1, qc2);
1413+
}
1414+
1415+
TEST_F(QFRFunctionality, InequalityDifferentGarbageQubits) {
1416+
// Different garbage qubits
1417+
QuantumComputation qc1(2, 2);
1418+
qc1.setLogicalQubitGarbage(1);
1419+
1420+
const QuantumComputation qc2(2, 2);
1421+
// No garbage qubits in qc2
1422+
EXPECT_NE(qc1, qc2);
1423+
}
1424+
1425+
TEST_F(QFRFunctionality, InequalityDifferentFinalLayout) {
1426+
// Different final layout
1427+
QuantumComputation qc1(2, 2);
1428+
QuantumComputation qc2(2, 2);
1429+
qc1.outputPermutation[0] = 1;
1430+
qc1.outputPermutation[1] = 0;
1431+
1432+
qc2.outputPermutation[0] = 0;
1433+
qc2.outputPermutation[1] = 1;
1434+
EXPECT_NE(qc1, qc2);
1435+
}
1436+
1437+
TEST_F(QFRFunctionality, InequalityDifferentQuantumPhase) {
1438+
// Different quantum phase
1439+
QuantumComputation qc1(2, 2);
1440+
qc1.gphase(0.1); // Add global phase
1441+
1442+
const QuantumComputation qc2(2, 2);
1443+
// No global phase in qc2
1444+
EXPECT_NE(qc1, qc2);
1445+
}
1446+
1447+
TEST_F(QFRFunctionality, InequalityDifferentNumberOfClassicalBits) {
1448+
// Different number of classical bits
1449+
const QuantumComputation qc1(2, 3); // 2 qubits, 3 classical bits
1450+
const QuantumComputation qc2(2, 2); // 2 qubits, 2 classical bits
1451+
EXPECT_NE(qc1, qc2);
1452+
}
1453+
1454+
TEST_F(QFRFunctionality, InequalityDifferentMeasurementMappings) {
1455+
// Different measurement mappings
1456+
QuantumComputation qc1(2, 2);
1457+
qc1.measure(0, 1); // Measure qubit 0 to classical bit 1
1458+
1459+
QuantumComputation qc2(2, 2);
1460+
qc2.measure(0, 0); // Measure qubit 0 to classical bit 0
1461+
EXPECT_NE(qc1, qc2);
1462+
}
1463+
1464+
TEST_F(QFRFunctionality, InequalityDifferentAdditionalOperations) {
1465+
// Different additional operations
1466+
QuantumComputation qc1(2, 2);
1467+
qc1.h(0);
1468+
1469+
QuantumComputation qc2(2, 2);
1470+
qc2.h(0);
1471+
qc2.barrier(); // qc2 has an additional barrier
1472+
EXPECT_NE(qc1, qc2);
1473+
}

0 commit comments

Comments
 (0)