Skip to content

Commit b5d1443

Browse files
committed
compare unitaries
1 parent 051c9e6 commit b5d1443

File tree

2 files changed

+36
-138
lines changed

2 files changed

+36
-138
lines changed

src/qrisp/interface/converter/cirq_converter.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,20 @@ def convert_to_cirq(qrisp_circuit):
8787
params = instr.op.params
8888

8989
if op_i not in qrisp_cirq_ops_dict:
90-
raise ValueError(
91-
f"{op_i} gate is not supported by the Qrisp to Cirq converter."
92-
)
90+
try:
91+
def transpile_predicate(op):
92+
if op.name == op_i:
93+
return True
94+
else:
95+
return False
96+
97+
transpiled_qc = qrisp_circuit.transpile(transpile_predicate=transpile_predicate)
98+
return convert_to_cirq(transpiled_qc)
99+
100+
except Exception:
101+
raise ValueError(
102+
f"{op_i} gate is not supported by the Qrisp to Cirq converter."
103+
)
93104

94105
if op_i in ["gphase"]:
95106
print(
Lines changed: 22 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import pytest
22
import numpy as np
33

4-
from cirq import LineQubit
4+
from cirq import LineQubit, unitary
55

66
from cirq import CNOT, H, X, Y, Z, S, T, rx, ry, rz, M, R, SWAP
77
from unittest.mock import MagicMock
@@ -28,53 +28,20 @@ def test_n_qubit_gate_circuit():
2828
qc_single_qubit_gates.t(1)
2929
qc_single_qubit_gates.t_dg(3)
3030
qc_single_qubit_gates.s_dg(2)
31-
32-
expected_cirq_qc_single_qubit_gates_ops = [
33-
H(LineQubit(0)),
34-
X(LineQubit(1)),
35-
Y(LineQubit(3)),
36-
Z(LineQubit(2)),
37-
rx(rads=0.3).on(LineQubit(3)),
38-
ry(rads=0.4).on(LineQubit(1)),
39-
rz(rads=0.2).on(LineQubit(2)),
40-
S(LineQubit(0)),
41-
T(LineQubit(1)),
42-
(T**-1).on(LineQubit(3)),
43-
(S**-1).on(LineQubit(2)),
44-
M(LineQubit(0)),
45-
R(LineQubit(0)),
46-
]
47-
48-
converted_circ = convert_to_cirq(qc_single_qubit_gates)
49-
assert expected_cirq_qc_single_qubit_gates_ops == list(
50-
converted_circ.all_operations()
51-
)
31+
expected_unitary = qc_single_qubit_gates.get_unitary()
32+
converted_cirq = convert_to_cirq(qc_single_qubit_gates)
33+
calculated_unitary = unitary(converted_cirq)
34+
np.testing.assert_array_almost_equal(expected_unitary, calculated_unitary)
35+
5236

5337
# 4 qubit circuit containing all multi-controlled gates
5438
# there is only 1 multicontrolled gate mcx
55-
qc_mcx = QuantumCircuit(10)
56-
qc_mcx.mcx([0, 1, 2, 4, 5, 7], [3, 8])
57-
58-
expected_mcx_circ = [
59-
X(LineQubit(3)).controlled_by(
60-
LineQubit(0),
61-
LineQubit(1),
62-
LineQubit(2),
63-
LineQubit(4),
64-
LineQubit(5),
65-
LineQubit(7),
66-
),
67-
X(LineQubit(8)).controlled_by(
68-
LineQubit(0),
69-
LineQubit(1),
70-
LineQubit(2),
71-
LineQubit(4),
72-
LineQubit(5),
73-
LineQubit(7),
74-
),
75-
]
76-
converted_circ = convert_to_cirq(qc_mcx)
77-
assert expected_mcx_circ == list(converted_circ.all_operations())
39+
qc_mcx = QuantumCircuit(8)
40+
qc_mcx.mcx([0, 1, 2, 4, 5, 6], [3, 7])
41+
expected_unitary = qc_mcx.get_unitary()
42+
converted_cirq = convert_to_cirq(qc_mcx)
43+
calculated_unitary = unitary(converted_cirq)
44+
np.testing.assert_array_almost_equal(expected_unitary, calculated_unitary)
7845

7946

8047
@pytest.mark.parametrize(
@@ -138,11 +105,10 @@ def test_converter_compiled_qs():
138105
mcx(ctrl, target)
139106
compiled_qc = ctrl.qs.compile()
140107
cirq_qc = convert_to_cirq(compiled_qc)
141-
assert [
142-
X(LineQubit(4)).controlled_by(
143-
LineQubit(0), LineQubit(1), LineQubit(2), LineQubit(3)
144-
)
145-
] == list(cirq_qc.all_operations())
108+
expected_unitary = compiled_qc.get_unitary()
109+
converted_cirq = convert_to_cirq(compiled_qc)
110+
calculated_unitary = unitary(converted_cirq)
111+
np.testing.assert_array_almost_equal(expected_unitary, calculated_unitary)
146112

147113
# reflection around GHZ state in a QuantumSession
148114
# Prepare |1> state
@@ -158,25 +124,7 @@ def ghz(qv):
158124

159125
reflection_compiled_qc = qv.qs.compile()
160126
reflection_cirq_qc = convert_to_cirq(reflection_compiled_qc)
161-
assert list(reflection_cirq_qc.all_operations()) == [
162-
X(LineQubit(1)),
163-
X(LineQubit(2)),
164-
X(LineQubit(3)),
165-
X(LineQubit(0)),
166-
CNOT(LineQubit(0), LineQubit(4)),
167-
H(LineQubit(4)),
168-
CNOT(LineQubit(0), LineQubit(1)),
169-
CNOT(LineQubit(0), LineQubit(2)),
170-
CNOT(LineQubit(0), LineQubit(3)),
171-
H(LineQubit(0)),
172-
X(LineQubit(4)).controlled_by(
173-
LineQubit(0), LineQubit(1), LineQubit(2), LineQubit(3)
174-
),
175-
H(LineQubit(4)),
176-
H(LineQubit(0)),
177-
X(LineQubit(4)),
178-
]
179-
127+
180128

181129
def test_transpiled_qc():
182130
"""Verify the converter works without any issues for a transpiled circuit that has a composite gate."""
@@ -196,71 +144,10 @@ def U(qv):
196144
QPE(qv, U, precision=3)
197145
test_circuit = qv.qs.compile()
198146
# test_circuit has a composite gate QFT_dg
199-
with pytest.raises(
200-
ValueError, match="QFT_dg gate is not supported by the Qrisp to Cirq converter."
201-
):
202-
convert_to_cirq(test_circuit)
203-
204-
def transpile_predicate(op):
205-
if op.name == "QFT_dg":
206-
return True
207-
else:
208-
return False
147+
# the function transpiles the composite gate, if possible
209148

210-
transpiled_qc = test_circuit.transpile(transpile_predicate=transpile_predicate)
149+
expected_unitary = test_circuit.get_unitary()
150+
converted_cirq = convert_to_cirq(test_circuit)
151+
calculated_unitary = unitary(converted_cirq)
152+
np.testing.assert_array_almost_equal(expected_unitary, calculated_unitary)
211153

212-
assert list(convert_to_cirq(transpiled_qc).all_operations()) == [
213-
H(LineQubit(0)),
214-
H(LineQubit(1)),
215-
H(LineQubit(2)),
216-
H(LineQubit(3)),
217-
H(LineQubit(4)),
218-
(Z**1.570796326794896558).on(LineQubit(0)),
219-
(Z**0.3926990816987241395).on(LineQubit(1)),
220-
(Z**1.9634954084936206975).on(LineQubit(2)),
221-
(Z**3.926990816987241395).on(LineQubit(3)),
222-
(Z**7.85398163397448279).on(LineQubit(4)),
223-
CNOT(LineQubit(2), LineQubit(0)),
224-
CNOT(LineQubit(3), LineQubit(1)),
225-
(Z**-1.570796326794896558).on(LineQubit(0)),
226-
(Z**-0.3926990816987241395).on(LineQubit(1)),
227-
CNOT(LineQubit(2), LineQubit(0)),
228-
CNOT(LineQubit(3), LineQubit(1)),
229-
(Z**3.141592653589793116).on(LineQubit(0)),
230-
(Z**0.3926990816987241395).on(LineQubit(1)),
231-
CNOT(LineQubit(3), LineQubit(0)),
232-
CNOT(LineQubit(2), LineQubit(1)),
233-
(Z**-3.141592653589793116).on(LineQubit(0)),
234-
(Z**-0.3926990816987241395).on(LineQubit(1)),
235-
CNOT(LineQubit(3), LineQubit(0)),
236-
CNOT(LineQubit(2), LineQubit(1)),
237-
(Z**6.283185307179586232).on(LineQubit(0)),
238-
(Z**0.3926990816987241395).on(LineQubit(1)),
239-
CNOT(LineQubit(4), LineQubit(0)),
240-
CNOT(LineQubit(3), LineQubit(1)),
241-
(Z**-6.283185307179586232).on(LineQubit(0)),
242-
(Z**-0.3926990816987241395).on(LineQubit(1)),
243-
CNOT(LineQubit(4), LineQubit(0)),
244-
CNOT(LineQubit(3), LineQubit(1)),
245-
(Z**1.570796326794896558).on(LineQubit(1)),
246-
(Z**-0.7853981633974483).on(LineQubit(3)),
247-
CNOT(LineQubit(4), LineQubit(1)),
248-
(Z**-1.570796326794896558).on(LineQubit(1)),
249-
CNOT(LineQubit(4), LineQubit(1)),
250-
SWAP(LineQubit(4), LineQubit(2)),
251-
(Z**-1.1780972450961724).on(LineQubit(4)),
252-
H(LineQubit(2)),
253-
(Z**-1.1780972450961724).on(LineQubit(2)),
254-
CNOT(LineQubit(3), LineQubit(2)),
255-
(Z**0.7853981633974483).on(LineQubit(2)),
256-
CNOT(LineQubit(3), LineQubit(2)),
257-
H(LineQubit(3)),
258-
CNOT(LineQubit(4), LineQubit(2)),
259-
(Z**-0.7853981633974483).on(LineQubit(3)),
260-
(Z**0.39269908169872414).on(LineQubit(2)),
261-
CNOT(LineQubit(4), LineQubit(2)),
262-
CNOT(LineQubit(4), LineQubit(3)),
263-
(Z**0.7853981633974483).on(LineQubit(3)),
264-
CNOT(LineQubit(4), LineQubit(3)),
265-
H(LineQubit(4)),
266-
]

0 commit comments

Comments
 (0)