27
27
class _BaseLineQid (ops .Qid ):
28
28
"""The base class for `LineQid` and `LineQubit`."""
29
29
30
- def __init__ (self , x : int ) -> None :
31
- """Initializes a line qubit at the given x coordinate."""
32
- self ._x = x
30
+ _x : int
31
+ _dimension : int
32
+ _hash : Optional [int ] = None
33
+
34
+ def __getstate__ (self ):
35
+ # Don't save hash when pickling; see #3777.
36
+ state = self .__dict__
37
+ if "_hash" in state :
38
+ state = state .copy ()
39
+ del state ["_hash" ]
40
+ return state
41
+
42
+ def __hash__ (self ) -> int :
43
+ if self ._hash is None :
44
+ self ._hash = hash ((self ._x , self ._dimension ))
45
+ return self ._hash
46
+
47
+ def __eq__ (self , other ):
48
+ # Explicitly implemented for performance (vs delegating to Qid).
49
+ if isinstance (other , _BaseLineQid ):
50
+ return self ._x == other ._x and self ._dimension == other ._dimension
51
+ return NotImplemented
52
+
53
+ def __ne__ (self , other ):
54
+ # Explicitly implemented for performance (vs delegating to Qid).
55
+ if isinstance (other , _BaseLineQid ):
56
+ return self ._x != other ._x or self ._dimension != other ._dimension
57
+ return NotImplemented
33
58
34
59
def _comparison_key (self ):
35
- return self .x
60
+ return self ._x
36
61
37
62
@property
38
63
def x (self ) -> int :
39
64
return self ._x
40
65
66
+ @property
67
+ def dimension (self ) -> int :
68
+ return self ._dimension
69
+
41
70
def with_dimension (self , dimension : int ) -> 'LineQid' :
42
- return LineQid (self .x , dimension )
71
+ return LineQid (self ._x , dimension )
43
72
44
73
def is_adjacent (self , other : 'cirq.Qid' ) -> bool :
45
74
"""Determines if two qubits are adjacent line qubits.
@@ -49,49 +78,45 @@ def is_adjacent(self, other: 'cirq.Qid') -> bool:
49
78
50
79
Returns: True iff other and self are adjacent.
51
80
"""
52
- return isinstance (other , _BaseLineQid ) and abs (self .x - other .x ) == 1
81
+ return isinstance (other , _BaseLineQid ) and abs (self ._x - other ._x ) == 1
53
82
54
83
def neighbors (self , qids : Optional [Iterable [ops .Qid ]] = None ) -> Set ['_BaseLineQid' ]:
55
84
"""Returns qubits that are potential neighbors to this LineQubit
56
85
57
86
Args:
58
87
qids: optional Iterable of qubits to constrain neighbors to.
59
88
"""
60
- neighbors = set ()
61
- for q in [self - 1 , self + 1 ]:
62
- if qids is None or q in qids :
63
- neighbors .add (q )
64
- return neighbors
89
+ return {q for q in [self - 1 , self + 1 ] if qids is None or q in qids }
65
90
66
91
@abc .abstractmethod
67
92
def _with_x (self , x : int ) -> Self :
68
93
"""Returns a qubit with the same type but a different value of `x`."""
69
94
70
95
def __add__ (self , other : Union [int , Self ]) -> Self :
71
96
if isinstance (other , _BaseLineQid ):
72
- if self .dimension != other .dimension :
97
+ if self ._dimension != other ._dimension :
73
98
raise TypeError (
74
99
"Can only add LineQids with identical dimension. "
75
- f"Got { self .dimension } and { other .dimension } "
100
+ f"Got { self ._dimension } and { other ._dimension } "
76
101
)
77
- return self ._with_x (x = self .x + other .x )
102
+ return self ._with_x (x = self ._x + other ._x )
78
103
if not isinstance (other , int ):
79
104
raise TypeError (f"Can only add ints and { type (self ).__name__ } . Instead was { other } " )
80
- return self ._with_x (self .x + other )
105
+ return self ._with_x (self ._x + other )
81
106
82
107
def __sub__ (self , other : Union [int , Self ]) -> Self :
83
108
if isinstance (other , _BaseLineQid ):
84
- if self .dimension != other .dimension :
109
+ if self ._dimension != other ._dimension :
85
110
raise TypeError (
86
111
"Can only subtract LineQids with identical dimension. "
87
- f"Got { self .dimension } and { other .dimension } "
112
+ f"Got { self ._dimension } and { other ._dimension } "
88
113
)
89
- return self ._with_x (x = self .x - other .x )
114
+ return self ._with_x (x = self ._x - other ._x )
90
115
if not isinstance (other , int ):
91
116
raise TypeError (
92
117
f"Can only subtract ints and { type (self ).__name__ } . Instead was { other } "
93
118
)
94
- return self ._with_x (self .x - other )
119
+ return self ._with_x (self ._x - other )
95
120
96
121
def __radd__ (self , other : int ) -> Self :
97
122
return self + other
@@ -100,16 +125,16 @@ def __rsub__(self, other: int) -> Self:
100
125
return - self + other
101
126
102
127
def __neg__ (self ) -> Self :
103
- return self ._with_x (- self .x )
128
+ return self ._with_x (- self ._x )
104
129
105
130
def __complex__ (self ) -> complex :
106
- return complex (self .x )
131
+ return complex (self ._x )
107
132
108
133
def __float__ (self ) -> float :
109
- return float (self .x )
134
+ return float (self ._x )
110
135
111
136
def __int__ (self ) -> int :
112
- return int (self .x )
137
+ return int (self ._x )
113
138
114
139
115
140
class LineQid (_BaseLineQid ):
@@ -137,16 +162,12 @@ def __init__(self, x: int, dimension: int) -> None:
137
162
dimension: The dimension of the qid's Hilbert space, i.e.
138
163
the number of quantum levels.
139
164
"""
140
- super ().__init__ (x )
141
- self ._dimension = dimension
142
165
self .validate_dimension (dimension )
143
-
144
- @property
145
- def dimension (self ):
146
- return self ._dimension
166
+ self ._x = x
167
+ self ._dimension = dimension
147
168
148
169
def _with_x (self , x : int ) -> 'LineQid' :
149
- return LineQid (x , dimension = self .dimension )
170
+ return LineQid (x , dimension = self ._dimension )
150
171
151
172
@staticmethod
152
173
def range (* range_args , dimension : int ) -> List ['LineQid' ]:
@@ -192,15 +213,15 @@ def for_gate(val: Any, start: int = 0, step: int = 1) -> List['LineQid']:
192
213
return LineQid .for_qid_shape (qid_shape (val ), start = start , step = step )
193
214
194
215
def __repr__ (self ) -> str :
195
- return f"cirq.LineQid({ self .x } , dimension={ self .dimension } )"
216
+ return f"cirq.LineQid({ self ._x } , dimension={ self ._dimension } )"
196
217
197
218
def __str__ (self ) -> str :
198
- return f"q({ self .x } ) (d={ self .dimension } )"
219
+ return f"q({ self ._x } ) (d={ self ._dimension } )"
199
220
200
221
def _circuit_diagram_info_ (
201
222
self , args : 'cirq.CircuitDiagramInfoArgs'
202
223
) -> 'cirq.CircuitDiagramInfo' :
203
- return protocols .CircuitDiagramInfo (wire_symbols = (f"{ self .x } (d={ self .dimension } )" ,))
224
+ return protocols .CircuitDiagramInfo (wire_symbols = (f"{ self ._x } (d={ self ._dimension } )" ,))
204
225
205
226
def _json_dict_ (self ) -> Dict [str , Any ]:
206
227
return protocols .obj_to_dict_helper (self , ['x' , 'dimension' ])
@@ -223,9 +244,15 @@ class LineQubit(_BaseLineQid):
223
244
224
245
"""
225
246
226
- @property
227
- def dimension (self ) -> int :
228
- return 2
247
+ _dimension = 2
248
+
249
+ def __init__ (self , x : int ) -> None :
250
+ """Initializes a line qubit at the given x coordinate.
251
+
252
+ Args:
253
+ x: The x coordinate.
254
+ """
255
+ self ._x = x
229
256
230
257
def _with_x (self , x : int ) -> 'LineQubit' :
231
258
return LineQubit (x )
@@ -234,7 +261,7 @@ def _cmp_tuple(self):
234
261
cls = LineQid if type (self ) is LineQubit else type (self )
235
262
# Must be the same as Qid._cmp_tuple but with cls in place of
236
263
# type(self).
237
- return (cls .__name__ , repr (cls ), self ._comparison_key (), self .dimension )
264
+ return (cls .__name__ , repr (cls ), self ._comparison_key (), self ._dimension )
238
265
239
266
@staticmethod
240
267
def range (* range_args ) -> List ['LineQubit' ]:
@@ -249,15 +276,15 @@ def range(*range_args) -> List['LineQubit']:
249
276
return [LineQubit (i ) for i in range (* range_args )]
250
277
251
278
def __repr__ (self ) -> str :
252
- return f"cirq.LineQubit({ self .x } )"
279
+ return f"cirq.LineQubit({ self ._x } )"
253
280
254
281
def __str__ (self ) -> str :
255
- return f"q({ self .x } )"
282
+ return f"q({ self ._x } )"
256
283
257
284
def _circuit_diagram_info_ (
258
285
self , args : 'cirq.CircuitDiagramInfoArgs'
259
286
) -> 'cirq.CircuitDiagramInfo' :
260
- return protocols .CircuitDiagramInfo (wire_symbols = (f"{ self .x } " ,))
287
+ return protocols .CircuitDiagramInfo (wire_symbols = (f"{ self ._x } " ,))
261
288
262
289
def _json_dict_ (self ) -> Dict [str , Any ]:
263
290
return protocols .obj_to_dict_helper (self , ['x' ])
0 commit comments