@@ -141,145 +141,141 @@ def _pad_tableau(
141141 return padded_tableau
142142
143143
144+ def _gate_tableau (num_qubits : int , gate : raw_types .Gate ) -> 'cirq.CliffordTableau' :
145+ qubits = devices .LineQubit .range (num_qubits )
146+ t = qis .CliffordTableau (num_qubits = num_qubits )
147+ args = sim .CliffordTableauSimulationState (
148+ tableau = t , qubits = qubits , prng = np .random .RandomState ()
149+ )
150+ protocols .act_on (gate , args , qubits , allow_decompose = False )
151+ return args .tableau
152+
153+
144154class CommonCliffordGateMetaClass (value .ABCMetaImplementAnyOneOf ):
145155 """A metaclass used to lazy initialize several common Clifford Gate as class attributes."""
146156
157+ # These are class properties so we define them as properties on a metaclass.
158+ # Note that in python 3.9+ @classmethod can be used with @property, so these
159+ # can be moved to CommonCliffordGates.
160+
147161 @property
148- def I (cls ):
149- if getattr (cls , '_I' , None ) is None :
150- cls ._I = cls . _generate_clifford_from_known_gate ( 1 , identity .I )
162+ def I (cls ) -> 'cirq.SingleQubitCliffordGate' :
163+ if not hasattr (cls , '_I' ) :
164+ cls ._I = SingleQubitCliffordGate . from_clifford_tableau ( _gate_tableau ( 1 , identity .I ) )
151165 return cls ._I
152166
153167 @property
154- def X (cls ):
155- if getattr (cls , '_X' , None ) is None :
156- cls ._X = cls . _generate_clifford_from_known_gate ( 1 , pauli_gates .X )
168+ def X (cls ) -> 'cirq.SingleQubitCliffordGate' :
169+ if not hasattr (cls , '_X' ) :
170+ cls ._X = SingleQubitCliffordGate . from_clifford_tableau ( _gate_tableau ( 1 , pauli_gates .X ) )
157171 return cls ._X
158172
159173 @property
160- def Y (cls ):
161- if getattr (cls , '_Y' , None ) is None :
162- cls ._Y = cls . _generate_clifford_from_known_gate ( 1 , pauli_gates .Y )
174+ def Y (cls ) -> 'cirq.SingleQubitCliffordGate' :
175+ if not hasattr (cls , '_Y' ) :
176+ cls ._Y = SingleQubitCliffordGate . from_clifford_tableau ( _gate_tableau ( 1 , pauli_gates .Y ) )
163177 return cls ._Y
164178
165179 @property
166- def Z (cls ):
167- if getattr (cls , '_Z' , None ) is None :
168- cls ._Z = cls . _generate_clifford_from_known_gate ( 1 , pauli_gates .Z )
180+ def Z (cls ) -> 'cirq.SingleQubitCliffordGate' :
181+ if not hasattr (cls , '_Z' ) :
182+ cls ._Z = SingleQubitCliffordGate . from_clifford_tableau ( _gate_tableau ( 1 , pauli_gates .Z ) )
169183 return cls ._Z
170184
171185 @property
172- def H (cls ):
173- if getattr (cls , '_H' , None ) is None :
174- cls ._H = cls . _generate_clifford_from_known_gate ( 1 , common_gates .H )
186+ def H (cls ) -> 'cirq.SingleQubitCliffordGate' :
187+ if not hasattr (cls , '_H' ) :
188+ cls ._H = SingleQubitCliffordGate . from_clifford_tableau ( _gate_tableau ( 1 , common_gates .H ) )
175189 return cls ._H
176190
177191 @property
178- def S (cls ):
179- if getattr (cls , '_S' , None ) is None :
180- cls ._S = cls . _generate_clifford_from_known_gate ( 1 , common_gates .S )
192+ def S (cls ) -> 'cirq.SingleQubitCliffordGate' :
193+ if not hasattr (cls , '_S' ) :
194+ cls ._S = SingleQubitCliffordGate . from_clifford_tableau ( _gate_tableau ( 1 , common_gates .S ) )
181195 return cls ._S
182196
183197 @property
184- def CNOT (cls ):
185- if getattr (cls , '_CNOT' , None ) is None :
186- cls ._CNOT = cls . _generate_clifford_from_known_gate ( 2 , common_gates .CNOT )
198+ def CNOT (cls ) -> 'cirq.CliffordGate' :
199+ if not hasattr (cls , '_CNOT' ) :
200+ cls ._CNOT = CliffordGate . from_clifford_tableau ( _gate_tableau ( 2 , common_gates .CNOT ) )
187201 return cls ._CNOT
188202
189203 @property
190- def CZ (cls ):
191- if getattr (cls , '_CZ' , None ) is None :
192- cls ._CZ = cls . _generate_clifford_from_known_gate ( 2 , common_gates .CZ )
204+ def CZ (cls ) -> 'cirq.CliffordGate' :
205+ if not hasattr (cls , '_CZ' ) :
206+ cls ._CZ = CliffordGate . from_clifford_tableau ( _gate_tableau ( 2 , common_gates .CZ ) )
193207 return cls ._CZ
194208
195209 @property
196- def SWAP (cls ):
197- if getattr (cls , '_SWAP' , None ) is None :
198- cls ._SWAP = cls . _generate_clifford_from_known_gate ( 2 , common_gates .SWAP )
210+ def SWAP (cls ) -> 'cirq.CliffordGate' :
211+ if not hasattr (cls , '_SWAP' ) :
212+ cls ._SWAP = CliffordGate . from_clifford_tableau ( _gate_tableau ( 2 , common_gates .SWAP ) )
199213 return cls ._SWAP
200214
201215 @property
202- def X_sqrt (cls ):
203- if getattr (cls , '_X_sqrt' , None ) is None :
216+ def X_sqrt (cls ) -> 'cirq.SingleQubitCliffordGate' :
217+ if not hasattr (cls , '_X_sqrt' ) :
204218 # Unfortunately, due the code style, the matrix should be viewed transposed.
205219 # Note xs, zs, and rs are column vector.
206220 # Transformation: X -> X, Z -> -Y
207- _clifford_tableau = qis .CliffordTableau ._from_json_dict_ (
221+ clifford_tableau = qis .CliffordTableau ._from_json_dict_ (
208222 n = 1 , rs = [0 , 1 ], xs = [[1 ], [1 ]], zs = [[0 ], [1 ]]
209223 )
210- cls ._X_sqrt = cls .from_clifford_tableau (_clifford_tableau )
224+ cls ._X_sqrt = SingleQubitCliffordGate .from_clifford_tableau (clifford_tableau )
211225 return cls ._X_sqrt
212226
213227 @property
214- def X_nsqrt (cls ):
215- if getattr (cls , '_X_nsqrt' , None ) is None :
228+ def X_nsqrt (cls ) -> 'cirq.SingleQubitCliffordGate' :
229+ if not hasattr (cls , '_X_nsqrt' ) :
216230 # Transformation: X->X, Z->Y
217- _clifford_tableau = qis .CliffordTableau ._from_json_dict_ (
231+ clifford_tableau = qis .CliffordTableau ._from_json_dict_ (
218232 n = 1 , rs = [0 , 0 ], xs = [[1 ], [1 ]], zs = [[0 ], [1 ]]
219233 )
220- cls ._X_nsqrt = cls .from_clifford_tableau (_clifford_tableau )
234+ cls ._X_nsqrt = SingleQubitCliffordGate .from_clifford_tableau (clifford_tableau )
221235 return cls ._X_nsqrt
222236
223237 @property
224- def Y_sqrt (cls ):
225- if getattr (cls , '_Y_sqrt' , None ) is None :
238+ def Y_sqrt (cls ) -> 'cirq.SingleQubitCliffordGate' :
239+ if not hasattr (cls , '_Y_sqrt' ) :
226240 # Transformation: X -> -Z, Z -> X
227- _clifford_tableau = qis .CliffordTableau ._from_json_dict_ (
241+ clifford_tableau = qis .CliffordTableau ._from_json_dict_ (
228242 n = 1 , rs = [1 , 0 ], xs = [[0 ], [1 ]], zs = [[1 ], [0 ]]
229243 )
230- cls ._Y_sqrt = cls .from_clifford_tableau (_clifford_tableau )
244+ cls ._Y_sqrt = SingleQubitCliffordGate .from_clifford_tableau (clifford_tableau )
231245 return cls ._Y_sqrt
232246
233247 @property
234- def Y_nsqrt (cls ):
235- if getattr (cls , '_Y_nsqrt' , None ) is None :
248+ def Y_nsqrt (cls ) -> 'cirq.SingleQubitCliffordGate' :
249+ if not hasattr (cls , '_Y_nsqrt' ) :
236250 # Transformation: X -> Z, Z -> -X
237- _clifford_tableau = qis .CliffordTableau ._from_json_dict_ (
251+ clifford_tableau = qis .CliffordTableau ._from_json_dict_ (
238252 n = 1 , rs = [0 , 1 ], xs = [[0 ], [1 ]], zs = [[1 ], [0 ]]
239253 )
240- cls ._Y_nsqrt = cls .from_clifford_tableau (_clifford_tableau )
254+ cls ._Y_nsqrt = SingleQubitCliffordGate .from_clifford_tableau (clifford_tableau )
241255 return cls ._Y_nsqrt
242256
243257 @property
244- def Z_sqrt (cls ):
245- if getattr (cls , '_Z_sqrt' , None ) is None :
258+ def Z_sqrt (cls ) -> 'cirq.SingleQubitCliffordGate' :
259+ if not hasattr (cls , '_Z_sqrt' ) :
246260 # Transformation: X -> Y, Z -> Z
247261 _clifford_tableau = qis .CliffordTableau ._from_json_dict_ (
248262 n = 1 , rs = [0 , 0 ], xs = [[1 ], [0 ]], zs = [[1 ], [1 ]]
249263 )
250- cls ._Z_sqrt = cls .from_clifford_tableau (_clifford_tableau )
264+ cls ._Z_sqrt = SingleQubitCliffordGate .from_clifford_tableau (_clifford_tableau )
251265 return cls ._Z_sqrt
252266
253267 @property
254- def Z_nsqrt (cls ):
255- if getattr (cls , '_Z_nsqrt' , None ) is None :
268+ def Z_nsqrt (cls ) -> 'cirq.SingleQubitCliffordGate' :
269+ if not hasattr (cls , '_Z_nsqrt' ) :
256270 # Transformation: X -> -Y, Z -> Z
257271 _clifford_tableau = qis .CliffordTableau ._from_json_dict_ (
258272 n = 1 , rs = [1 , 0 ], xs = [[1 ], [0 ]], zs = [[1 ], [1 ]]
259273 )
260- cls ._Z_nsqrt = cls .from_clifford_tableau (_clifford_tableau )
274+ cls ._Z_nsqrt = SingleQubitCliffordGate .from_clifford_tableau (_clifford_tableau )
261275 return cls ._Z_nsqrt
262276
263277
264278class CommonCliffordGates (metaclass = CommonCliffordGateMetaClass ):
265-
266- # We need to use the lazy initialization of these common gates since they need to use
267- # cirq.sim, which can not be imported when
268- @classmethod
269- def _generate_clifford_from_known_gate (
270- cls , num_qubits : int , gate : raw_types .Gate
271- ) -> Union ['SingleQubitCliffordGate' , 'CliffordGate' ]:
272- qubits = devices .LineQubit .range (num_qubits )
273- t = qis .CliffordTableau (num_qubits = num_qubits )
274- args = sim .CliffordTableauSimulationState (
275- tableau = t , qubits = qubits , prng = np .random .RandomState ()
276- )
277-
278- protocols .act_on (gate , args , qubits , allow_decompose = False )
279- if num_qubits == 1 :
280- return SingleQubitCliffordGate .from_clifford_tableau (args .tableau )
281- return CliffordGate .from_clifford_tableau (args .tableau )
282-
283279 @classmethod
284280 def from_clifford_tableau (cls , tableau : qis .CliffordTableau ) -> 'CliffordGate' :
285281 """Create the CliffordGate instance from Clifford Tableau.
0 commit comments