Skip to content

Commit 83a34a8

Browse files
committed
♻️ refactored tests and removed workaround methods from main package
1 parent 5a98392 commit 83a34a8

File tree

3 files changed

+279
-259
lines changed

3 files changed

+279
-259
lines changed

include/dd/Package.hpp

-198
Original file line numberDiff line numberDiff line change
@@ -772,204 +772,6 @@ template <class Config> class Package {
772772
return e;
773773
}
774774

775-
mEdge makeSWAPDD(const std::size_t n, const qc::Controls& controls,
776-
const qc::Qubit target0, const qc::Qubit target1,
777-
const std::size_t start = 0) {
778-
auto c = controls;
779-
c.insert(qc::Control{target0});
780-
mEdge e = makeGateDD(X_MAT, n, c, target1, start);
781-
c.erase(qc::Control{target0});
782-
c.insert(qc::Control{target1});
783-
e = multiply(e, multiply(makeGateDD(X_MAT, n, c, target0, start), e));
784-
return e;
785-
}
786-
787-
mEdge makePeresDD(const std::size_t n, const qc::Controls& controls,
788-
const qc::Qubit target0, const qc::Qubit target1,
789-
const std::size_t start = 0) {
790-
auto c = controls;
791-
c.insert(qc::Control{target0});
792-
mEdge e = makeGateDD(X_MAT, n, c, target1, start);
793-
e = multiply(makeGateDD(X_MAT, n, controls, target0, start), e);
794-
return e;
795-
}
796-
797-
mEdge makePeresInvDD(const std::size_t n, const qc::Controls& controls,
798-
const qc::Qubit target0, const qc::Qubit target1,
799-
const std::size_t start = 0) {
800-
mEdge e = makeGateDD(X_MAT, n, controls, target0, start);
801-
auto c = controls;
802-
c.insert(qc::Control{target0});
803-
e = multiply(makeGateDD(X_MAT, n, c, target1, start), e);
804-
return e;
805-
}
806-
807-
mEdge makeiSWAPDD(const std::size_t n, const qc::Controls& controls,
808-
const qc::Qubit target0, const qc::Qubit target1,
809-
const std::size_t start = 0) {
810-
mEdge e = makeGateDD(S_MAT, n, controls, target1, start); // S q[1]
811-
e = multiply(e, makeGateDD(S_MAT, n, controls, target0, start)); // S q[0]
812-
e = multiply(e, makeGateDD(H_MAT, n, controls, target0, start)); // H q[0]
813-
auto c = controls;
814-
c.insert(qc::Control{target0});
815-
e = multiply(e, makeGateDD(X_MAT, n, c, target1, start)); // CX q[0], q[1]
816-
c.erase(qc::Control{target0});
817-
c.insert(qc::Control{target1});
818-
e = multiply(e, makeGateDD(X_MAT, n, c, target0, start)); // CX q[1], q[0]
819-
e = multiply(e, makeGateDD(H_MAT, n, controls, target1, start)); // H q[1]
820-
return e;
821-
}
822-
823-
mEdge makeiSWAPinvDD(const std::size_t n, const qc::Controls& controls,
824-
const qc::Qubit target0, const qc::Qubit target1,
825-
const std::size_t start = 0) {
826-
mEdge e = makeGateDD(H_MAT, n, controls, target1, start); // H q[1]
827-
auto c = controls;
828-
c.insert(qc::Control{target1});
829-
e = multiply(e, makeGateDD(X_MAT, n, c, target0, start)); // CX q[1], q[0]
830-
c.erase(qc::Control{target1});
831-
c.insert(qc::Control{target0});
832-
e = multiply(e, makeGateDD(X_MAT, n, c, target1, start)); // CX q[0], q[1]
833-
e = multiply(e, makeGateDD(H_MAT, n, controls, target0, start)); // H q[0]
834-
e = multiply(e,
835-
makeGateDD(SDG_MAT, n, controls, target0, start)); // Sdag q[0]
836-
e = multiply(e,
837-
makeGateDD(SDG_MAT, n, controls, target1, start)); // Sdag q[1]
838-
return e;
839-
}
840-
841-
mEdge makeDCXDD(const std::size_t n, const qc::Controls& controls,
842-
const qc::Qubit target0, const qc::Qubit target1,
843-
const std::size_t start = 0) {
844-
auto c = controls;
845-
c.insert(qc::Control{target0});
846-
mEdge e = makeGateDD(X_MAT, n, c, target1, start);
847-
c.erase(qc::Control{target0});
848-
c.insert(qc::Control{target1});
849-
e = multiply(e, makeGateDD(X_MAT, n, c, target0, start));
850-
return e;
851-
}
852-
853-
mEdge makeRZZDD(const std::size_t n, const qc::Controls& controls,
854-
const qc::Qubit target0, const qc::Qubit target1,
855-
const fp theta, const std::size_t start = 0) {
856-
auto c = controls;
857-
c.insert(qc::Control{target0});
858-
auto e = makeGateDD(X_MAT, n, c, target1, start);
859-
c.erase(qc::Control{target0});
860-
e = multiply(e, makeGateDD(rzMat(theta), n, c, target1, start));
861-
c.insert(qc::Control{target0});
862-
e = multiply(e, makeGateDD(X_MAT, n, c, target1, start));
863-
return e;
864-
}
865-
866-
mEdge makeRYYDD(const std::size_t n, const qc::Controls& controls,
867-
const qc::Qubit target0, const qc::Qubit target1,
868-
const fp theta, const std::size_t start = 0) {
869-
// no controls are necessary on the RX gates since they cancel if the
870-
// controls are 0.
871-
auto e = makeGateDD(rxMat(PI_2), n, qc::Controls{}, target0, start);
872-
e = multiply(e, makeGateDD(rxMat(PI_2), n, qc::Controls{}, target1, start));
873-
e = multiply(e, makeTwoQubitGateDD(rzzMat(theta), n, controls, target0,
874-
target1, start));
875-
e = multiply(e,
876-
makeGateDD(rxMat(-PI_2), n, qc::Controls{}, target1, start));
877-
e = multiply(e,
878-
makeGateDD(rxMat(-PI_2), n, qc::Controls{}, target0, start));
879-
return e;
880-
}
881-
882-
mEdge makeRXXDD(const std::size_t n, const qc::Controls& controls,
883-
const qc::Qubit target0, const qc::Qubit target1,
884-
const fp theta, const std::size_t start = 0) {
885-
// no controls are necessary on the H gates since they cancel if the
886-
// controls are 0.
887-
auto e = makeGateDD(H_MAT, n, qc::Controls{}, target0, start);
888-
e = multiply(e, makeGateDD(H_MAT, n, qc::Controls{}, target1, start));
889-
e = multiply(e, makeTwoQubitGateDD(rzzMat(theta), n, controls, target0,
890-
target1, start));
891-
e = multiply(e, makeGateDD(H_MAT, n, qc::Controls{}, target1, start));
892-
e = multiply(e, makeGateDD(H_MAT, n, qc::Controls{}, target0, start));
893-
return e;
894-
}
895-
896-
mEdge makeRZXDD(const std::size_t n, const qc::Controls& controls,
897-
const qc::Qubit target0, const qc::Qubit target1,
898-
const fp theta, const std::size_t start = 0) {
899-
// no controls are necessary on the H gates since they cancel if the
900-
// controls are 0.
901-
auto e = makeGateDD(H_MAT, n, qc::Controls{}, target1, start);
902-
e = multiply(e, makeTwoQubitGateDD(rzzMat(theta), n, controls, target0,
903-
target1, start));
904-
e = multiply(e, makeGateDD(H_MAT, n, qc::Controls{}, target1, start));
905-
return e;
906-
}
907-
908-
mEdge makeECRDD(const std::size_t n, const qc::Controls& controls,
909-
const qc::Qubit target0, const qc::Qubit target1,
910-
const std::size_t start = 0) {
911-
auto e =
912-
makeTwoQubitGateDD(rzxMat(-PI_4), n, controls, target0, target1, start);
913-
e = multiply(e, makeGateDD(X_MAT, n, controls, target0, start));
914-
e = multiply(e, makeTwoQubitGateDD(rzxMat(PI_4), n, controls, target0,
915-
target1, start));
916-
return e;
917-
}
918-
919-
mEdge makeXXMinusYYDD(const std::size_t n, const qc::Controls& controls,
920-
const qc::Qubit target0, const qc::Qubit target1,
921-
const fp theta, const fp beta = 0.,
922-
const std::size_t start = 0) {
923-
auto e = makeGateDD(rzMat(-beta), n, qc::Controls{}, target1, start);
924-
e = multiply(e,
925-
makeGateDD(rzMat(-PI_2), n, qc::Controls{}, target0, start));
926-
e = multiply(e, makeGateDD(SX_MAT, n, qc::Controls{}, target0, start));
927-
e = multiply(e, makeGateDD(rzMat(PI_2), n, qc::Controls{}, target0, start));
928-
e = multiply(e, makeGateDD(S_MAT, n, qc::Controls{}, target1, start));
929-
e = multiply(e, makeGateDD(X_MAT, n, qc::Control{target0}, target1, start));
930-
// only the following two gates need to be controlled by the controls since
931-
// the other gates cancel if the controls are 0.
932-
e = multiply(e,
933-
makeGateDD(ryMat(-theta / 2.), n, controls, target0, start));
934-
e = multiply(e, makeGateDD(ryMat(theta / 2.), n, controls, target1, start));
935-
936-
e = multiply(e, makeGateDD(X_MAT, n, qc::Control{target0}, target1, start));
937-
e = multiply(e, makeGateDD(SDG_MAT, n, qc::Controls{}, target1, start));
938-
e = multiply(e,
939-
makeGateDD(rzMat(-PI_2), n, qc::Controls{}, target0, start));
940-
e = multiply(e, makeGateDD(SXDG_MAT, n, qc::Controls{}, target0, start));
941-
e = multiply(e, makeGateDD(rzMat(PI_2), n, qc::Controls{}, target0, start));
942-
e = multiply(e, makeGateDD(rzMat(beta), n, qc::Controls{}, target1, start));
943-
return e;
944-
}
945-
946-
mEdge makeXXPlusYYDD(const std::size_t n, const qc::Controls& controls,
947-
const qc::Qubit target0, const qc::Qubit target1,
948-
const fp theta, const fp beta = 0.,
949-
const std::size_t start = 0) {
950-
auto e = makeGateDD(rzMat(beta), n, qc::Controls{}, target1, start);
951-
e = multiply(e,
952-
makeGateDD(rzMat(-PI_2), n, qc::Controls{}, target0, start));
953-
e = multiply(e, makeGateDD(SX_MAT, n, qc::Controls{}, target0, start));
954-
e = multiply(e, makeGateDD(rzMat(PI_2), n, qc::Controls{}, target0, start));
955-
e = multiply(e, makeGateDD(S_MAT, n, qc::Controls{}, target1, start));
956-
e = multiply(e, makeGateDD(X_MAT, n, qc::Control{target0}, target1, start));
957-
// only the following two gates need to be controlled by the controls since
958-
// the other gates cancel if the controls are 0.
959-
e = multiply(e, makeGateDD(ryMat(theta / 2.), n, controls, target0, start));
960-
e = multiply(e, makeGateDD(ryMat(theta / 2.), n, controls, target1, start));
961-
962-
e = multiply(e, makeGateDD(X_MAT, n, qc::Control{target0}, target1, start));
963-
e = multiply(e, makeGateDD(SDG_MAT, n, qc::Controls{}, target1, start));
964-
e = multiply(e,
965-
makeGateDD(rzMat(-PI_2), n, qc::Controls{}, target0, start));
966-
e = multiply(e, makeGateDD(SXDG_MAT, n, qc::Controls{}, target0, start));
967-
e = multiply(e, makeGateDD(rzMat(PI_2), n, qc::Controls{}, target0, start));
968-
e = multiply(e,
969-
makeGateDD(rzMat(-beta), n, qc::Controls{}, target1, start));
970-
return e;
971-
}
972-
973775
private:
974776
// check whether node represents a symmetric matrix or the identity
975777
void checkSpecialMatrices(mNode* p) {

test/dd/test_dd_functionality.cpp

+82-35
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class DDFunctionality : public testing::TestWithParam<qc::OpType> {
4141

4242
std::size_t nqubits = 4U;
4343
std::size_t initialComplexCount = 0U;
44-
qc::MatrixDD d{}, e{}, ident{};
44+
qc::MatrixDD e{}, ident{};
4545
std::unique_ptr<dd::Package<>> dd;
4646
std::mt19937_64 mt;
4747
std::uniform_real_distribution<dd::fp> dist;
@@ -64,7 +64,7 @@ TEST_P(DDFunctionality, standardOpBuildInverseBuild) {
6464
using namespace qc::literals;
6565
auto gate = static_cast<qc::OpType>(GetParam());
6666

67-
qc::StandardOperation op, op_neg;
67+
qc::StandardOperation op;
6868
switch (gate) {
6969
case qc::GPhase:
7070
op = qc::StandardOperation(nqubits, Controls{}, Targets{}, gate,
@@ -121,7 +121,7 @@ TEST_P(DDFunctionality, controlledStandardOpBuildInverseBuild) {
121121
using namespace qc::literals;
122122
auto gate = static_cast<qc::OpType>(GetParam());
123123

124-
qc::StandardOperation op, op_neg;
124+
qc::StandardOperation op;
125125
switch (gate) {
126126
case qc::GPhase:
127127
op = qc::StandardOperation(nqubits, Controls{0}, Targets{}, gate,
@@ -150,23 +150,18 @@ TEST_P(DDFunctionality, controlledStandardOpBuildInverseBuild) {
150150
case qc::Peres:
151151
case qc::Peresdg:
152152
op = qc::StandardOperation(nqubits, Controls{0}, 1, 2, gate);
153-
op_neg = qc::StandardOperation(nqubits, Controls{0_nc}, 1, 2, gate);
154153
break;
155154
case qc::RXX:
156155
case qc::RYY:
157156
case qc::RZZ:
158157
case qc::RZX:
159158
op = qc::StandardOperation(nqubits, Controls{0}, 1, 2, gate,
160159
std::vector{dist(mt)});
161-
op_neg = qc::StandardOperation(nqubits, Controls{0_nc}, 1, 2, gate,
162-
std::vector{dist(mt)});
163160
break;
164161
case qc::XXminusYY:
165162
case qc::XXplusYY:
166163
op = qc::StandardOperation(nqubits, Controls{0}, 1, 2, gate,
167164
std::vector{dist(mt), dist(mt)});
168-
op_neg = qc::StandardOperation(nqubits, Controls{0_nc}, 1, 2, gate,
169-
std::vector{dist(mt), dist(mt)});
170165
break;
171166
default:
172167
op = qc::StandardOperation(nqubits, 0, 1, gate);
@@ -177,43 +172,95 @@ TEST_P(DDFunctionality, controlledStandardOpBuildInverseBuild) {
177172
dd->incRef(e);
178173

179174
EXPECT_EQ(ident, e);
180-
181-
if (qc::isTwoQubitGate(gate)) {
182-
ASSERT_NO_THROW(
183-
{ d = dd->multiply(getDD(&op_neg, *dd), getInverseDD(&op_neg, *dd)); });
184-
dd->incRef(d);
185-
186-
EXPECT_EQ(ident, d);
187-
}
188175
}
189176

190-
TEST_F(DDFunctionality, twoTargetControlledGateDDEdgeCases) {
177+
TEST_P(DDFunctionality, controlledStandardNegOpBuildInverseBuild) {
191178
using namespace qc::literals;
192-
auto newNQubits = 12U;
193-
auto newDD = std::make_unique<dd::Package<>>(newNQubits);
194-
auto gate = SWAP;
195-
196-
qc::StandardOperation op, op_neg;
197-
op = qc::StandardOperation(newNQubits, Controls{1, 5, 7, 11}, 3, 9, gate);
198-
op_neg = qc::StandardOperation(newNQubits, Controls{1_nc, 5_nc, 7_nc, 11_nc},
199-
3, 9, gate);
179+
auto gate = static_cast<qc::OpType>(GetParam());
200180

201-
ASSERT_NO_THROW(
202-
{ e = newDD->multiply(getDD(&op, *newDD), getInverseDD(&op, *newDD)); });
203-
newDD->incRef(e);
181+
qc::StandardOperation op;
182+
switch (gate) {
183+
case qc::GPhase:
184+
op = qc::StandardOperation(nqubits, Controls{0}, Targets{}, gate,
185+
std::vector{dist(mt)});
186+
break;
187+
case qc::U:
188+
op = qc::StandardOperation(nqubits, 0, 1, gate,
189+
std::vector{dist(mt), dist(mt), dist(mt)});
190+
break;
191+
case qc::U2:
192+
op = qc::StandardOperation(nqubits, 0, 1, gate,
193+
std::vector{dist(mt), dist(mt)});
194+
break;
195+
case qc::RX:
196+
case qc::RY:
197+
case qc::RZ:
198+
case qc::P:
199+
op = qc::StandardOperation(nqubits, 0, 1, gate, std::vector{dist(mt)});
200+
break;
204201

205-
ASSERT_NO_THROW({
206-
d = newDD->multiply(getDD(&op_neg, *newDD), getInverseDD(&op_neg, *newDD));
207-
});
208-
newDD->incRef(d);
202+
case qc::SWAP:
203+
case qc::iSWAP:
204+
case qc::iSWAPdg:
205+
case qc::DCX:
206+
case qc::ECR:
207+
case qc::Peres:
208+
case qc::Peresdg:
209+
op = qc::StandardOperation(nqubits, Controls{0_nc}, 1, 2, gate);
210+
break;
211+
case qc::RXX:
212+
case qc::RYY:
213+
case qc::RZZ:
214+
case qc::RZX:
215+
op = qc::StandardOperation(nqubits, Controls{0_nc}, 1, 2, gate,
216+
std::vector{dist(mt)});
217+
break;
218+
case qc::XXminusYY:
219+
case qc::XXplusYY:
220+
op = qc::StandardOperation(nqubits, Controls{0_nc}, 1, 2, gate,
221+
std::vector{dist(mt), dist(mt)});
222+
break;
223+
default:
224+
op = qc::StandardOperation(nqubits, 0, 1, gate);
225+
}
209226

210-
// the DD of the identity needs to be reconstructed as well
211-
ident = newDD->makeIdent(newNQubits);
227+
ASSERT_NO_THROW(
228+
{ e = dd->multiply(getDD(&op, *dd), getInverseDD(&op, *dd)); });
229+
dd->incRef(e);
212230

213231
EXPECT_EQ(ident, e);
214-
EXPECT_EQ(ident, d);
215232
}
216233

234+
// TEST_F(DDFunctionality, twoTargetControlledGateDDEdgeCases) {
235+
// using namespace qc::literals;
236+
// auto newNQubits = 12U;
237+
// auto newDD = std::make_unique<dd::Package<>>(newNQubits);
238+
// auto gate = SWAP;
239+
//
240+
// qc::StandardOperation op, op_neg;
241+
// op = qc::StandardOperation(newNQubits, Controls{1, 5, 7, 11}, 3, 9, gate);
242+
// op_neg = qc::StandardOperation(newNQubits, Controls{1_nc, 5_nc, 7_nc,
243+
// 11_nc},
244+
// 3, 9, gate);
245+
//
246+
// ASSERT_NO_THROW(
247+
// { e = newDD->multiply(getDD(&op, *newDD), getInverseDD(&op, *newDD));
248+
// });
249+
// newDD->incRef(e);
250+
//
251+
// ASSERT_NO_THROW({
252+
// d = newDD->multiply(getDD(&op_neg, *newDD), getInverseDD(&op_neg,
253+
// *newDD));
254+
// });
255+
// newDD->incRef(d);
256+
//
257+
// // the DD of the identity needs to be reconstructed as well
258+
// ident = newDD->makeIdent(newNQubits);
259+
//
260+
// EXPECT_EQ(ident, e);
261+
// EXPECT_EQ(ident, d);
262+
// }
263+
217264
TEST_F(DDFunctionality, buildCircuit) {
218265
qc::QuantumComputation qc(nqubits);
219266

0 commit comments

Comments
 (0)