Skip to content

Commit 4674e11

Browse files
Change BasicGate __eq__ to test for matrix attribute (ProjectQ-Framework#252)
1 parent d630645 commit 4674e11

7 files changed

Lines changed: 57 additions & 10 deletions

File tree

projectq/backends/_sim/_simulator_test.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,15 +147,15 @@ def test_simulator_is_available(sim):
147147

148148
new_cmd.gate = Mock1QubitGate()
149149
assert sim.is_available(new_cmd)
150-
assert new_cmd.gate.cnt == 1
150+
assert new_cmd.gate.cnt == 4
151151

152152
new_cmd.gate = Mock6QubitGate()
153153
assert not sim.is_available(new_cmd)
154-
assert new_cmd.gate.cnt == 1
154+
assert new_cmd.gate.cnt == 4
155155

156156
new_cmd.gate = MockNoMatrixGate()
157157
assert not sim.is_available(new_cmd)
158-
assert new_cmd.gate.cnt == 1
158+
assert new_cmd.gate.cnt == 7
159159

160160

161161
def test_simulator_cheat(sim):

projectq/cengines/_replacer/_replacer_test.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,6 @@ def magic_filter(self, cmd):
178178
qb = eng.allocate_qubit()
179179
MagicGate() | qb
180180
eng.flush()
181-
for cmd in backend.received_commands:
182-
print(cmd)
183181
assert len(backend.received_commands) == 4
184182
assert backend.received_commands[1].gate == H
185183
assert backend.received_commands[2].gate == Rx(-0.6)

projectq/ops/_basics.py

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,16 @@
3434
import math
3535
from copy import deepcopy
3636

37+
import numpy as np
38+
3739
from projectq.types import BasicQubit
3840
from ._command import Command, apply_command
3941

4042

4143
ANGLE_PRECISION = 12
4244
ANGLE_TOLERANCE = 10 ** -ANGLE_PRECISION
45+
RTOL = 1e-10
46+
ATOL = 1e-12
4347

4448

4549
class NotMergeable(Exception):
@@ -200,8 +204,39 @@ def __or__(self, qubits):
200204
apply_command(cmd)
201205

202206
def __eq__(self, other):
203-
""" Return True if equal (i.e., instance of same class). """
204-
return isinstance(other, self.__class__)
207+
""" Return True if equal (i.e., instance of same class).
208+
209+
Unless both have a matrix attribute in which case we also check
210+
that the matrices are identical as people might want to do the
211+
following:
212+
213+
Example:
214+
.. code-block:: python
215+
216+
gate = BasicGate()
217+
gate.matrix = numpy.matrix([[1,0],[0, -1]])
218+
"""
219+
if hasattr(self, 'matrix'):
220+
if not hasattr(other, 'matrix'):
221+
return False
222+
if hasattr(other, 'matrix'):
223+
if not hasattr(self, 'matrix'):
224+
return False
225+
if hasattr(self, 'matrix') and hasattr(other, 'matrix'):
226+
if (not isinstance(self.matrix, np.matrix) or
227+
not isinstance(other.matrix, np.matrix)):
228+
raise TypeError("One of the gates doesn't have the correct "
229+
"type (numpy.matrix) for the matrix "
230+
"attribute.")
231+
if (self.matrix.shape == other.matrix.shape and
232+
np.allclose(self.matrix, other.matrix,
233+
rtol=RTOL, atol=ATOL,
234+
equal_nan=False)):
235+
return True
236+
else:
237+
return False
238+
else:
239+
return isinstance(other, self.__class__)
205240

206241
def __ne__(self, other):
207242
return not self.__eq__(other)

projectq/ops/_basics_test.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@
1414

1515
"""Tests for projectq.ops._basics."""
1616

17-
import pytest
1817
from copy import deepcopy
1918
import math
2019

20+
import numpy as np
21+
import pytest
22+
2123
from projectq.types import Qubit, Qureg
2224
from projectq.ops import Command
2325
from projectq import MainEngine
@@ -116,6 +118,13 @@ def test_basic_gate_compare():
116118
gate2 = _basics.BasicGate()
117119
assert gate1 == gate2
118120
assert not (gate1 != gate2)
121+
gate3 = _basics.BasicGate()
122+
gate3.matrix = np.matrix([[1, 0], [0, -1]])
123+
assert gate1 != gate3
124+
gate4 = _basics.BasicGate()
125+
gate4.matrix = [[1, 0], [0, -1]]
126+
with pytest.raises(TypeError):
127+
gate4 == gate3
119128

120129

121130
def test_comparing_different_gates():

projectq/ops/_qftgate.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,6 @@ class QFTGate(BasicGate):
2222
def __str__(self):
2323
return "QFT"
2424

25+
2526
#: Shortcut (instance of) :class:`projectq.ops.QFTGate`
2627
QFT = QFTGate()

projectq/ops/_qftgate_test.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,7 @@
2020
def test_qft_gate_str():
2121
gate = _qftgate.QFT
2222
assert str(gate) == "QFT"
23+
24+
25+
def test_qft_equality():
26+
assert _qftgate.QFT == _qftgate.QFTGate()

projectq/setups/decompositions/carb1qubit2cnotrzandry_test.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ def test_recognize_incorrect_gates():
5858
BasicGate() | qubit
5959
# Two qubit gate:
6060
two_qubit_gate = BasicGate()
61-
two_qubit_gate.matrix = [[1, 0, 0, 0], [0, 1, 0, 0],
62-
[0, 0, 1, 0], [0, 0, 0, 1]]
61+
two_qubit_gate.matrix = np.matrix([[1, 0, 0, 0], [0, 1, 0, 0],
62+
[0, 0, 1, 0], [0, 0, 0, 1]])
6363
two_qubit_gate | qubit
6464
with Control(eng, ctrl_qureg):
6565
# Too many Control qubits:

0 commit comments

Comments
 (0)