@@ -64,7 +64,7 @@ class NotInvertible(Exception):
6464
6565class BasicGate (object ):
6666 """
67- Base class of all gates.
67+ Base class of all gates. (Don't use it directly but derive from it)
6868 """
6969 def __init__ (self ):
7070 """
@@ -204,39 +204,19 @@ def __or__(self, qubits):
204204 apply_command (cmd )
205205
206206 def __eq__ (self , other ):
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
207+ """
208+ Equality comparision
209+
210+ Return True if instance of the same class, unless other is an instance
211+ of :class:MatrixGate, in which case equality is to be checked by testing
212+ for existence and (approximate) equality of matrix representations.
213+ """
214+ if isinstance (other , self .__class__ ):
215+ return True
216+ elif isinstance (other , MatrixGate ):
217+ return NotImplemented
238218 else :
239- return isinstance ( other , self . __class__ )
219+ return False
240220
241221 def __ne__ (self , other ):
242222 return not self .__eq__ (other )
@@ -248,6 +228,71 @@ def __hash__(self):
248228 return hash (str (self ))
249229
250230
231+ class MatrixGate (BasicGate ):
232+ """
233+ Defines a gate class whose instances are defined by a matrix.
234+
235+ Note:
236+ Use this gate class only for gates acting on a small numbers of qubits.
237+ In general, consider instead using one of the provided ProjectQ gates
238+ or define a new class as this allows the compiler to work symbolically.
239+
240+ Example:
241+
242+ .. code-block:: python
243+
244+ gate = MatrixGate([[0, 1], [1, 0]])
245+ gate | qubit
246+ """
247+ def __init__ (self , matrix = None ):
248+ """
249+ Initialize MatrixGate
250+
251+ Args:
252+ matrix(numpy.matrix): matrix which defines the gate. Default: None
253+ """
254+ BasicGate .__init__ (self )
255+ self ._matrix = np .matrix (matrix ) if matrix is not None else None
256+
257+ @property
258+ def matrix (self ):
259+ return self ._matrix
260+
261+ @matrix .setter
262+ def matrix (self , matrix ):
263+ self ._matrix = np .matrix (matrix )
264+
265+ def __eq__ (self , other ):
266+ """
267+ Equality comparision
268+
269+ Return True only if both gates have a matrix respresentation and the
270+ matrices are (approximately) equal. Otherwise return False.
271+ """
272+ if not hasattr (other , 'matrix' ):
273+ return False
274+ if (not isinstance (self .matrix , np .matrix ) or
275+ not isinstance (other .matrix , np .matrix )):
276+ raise TypeError ("One of the gates doesn't have the correct "
277+ "type (numpy.matrix) for the matrix "
278+ "attribute." )
279+ if (self .matrix .shape == other .matrix .shape and
280+ np .allclose (self .matrix , other .matrix ,
281+ rtol = RTOL , atol = ATOL ,
282+ equal_nan = False )):
283+ return True
284+ return False
285+
286+ def __str__ (self ):
287+ return ("MatrixGate(" + str (self .matrix .tolist ()) + ")" )
288+
289+ def __hash__ (self ):
290+ return hash (str (self ))
291+
292+ def get_inverse (self ):
293+ return MatrixGate (np .linalg .inv (self .matrix ))
294+
295+
251296class SelfInverseGate (BasicGate ):
252297 """
253298 Self-inverse basic gate class.
0 commit comments