@@ -52,26 +52,31 @@ def _xyz_sequence(matrix: su2_ct.SU2CliffordT) -> tuple[str, ...]:
5252]
5353
5454
55- def _xz_sequence (matrix : su2_ct .SU2CliffordT , use_hs : bool = True ) -> Optional [tuple [str , ...]]:
55+ def _xz_sequence (matrix : su2_ct .SU2CliffordT , use_hs : bool = True , prv : str = 'dummy' ) -> Optional [tuple [str , ...]]:
56+ # if use_hs:
57+ # matrix = matrix.reduce()
5658 if matrix .det () == 2 :
5759 return clifford (matrix )
5860 cliffords = [su2_ct .ISqrt2 ]
5961 if use_hs :
6062 cliffords .append (su2_ct .HSqrt2 )
6163 cliffords .append (su2_ct .HSqrt2 @ su2_ct .SSqrt2 )
6264 candidates = []
65+ pref = prv .removesuffix ('*' )
6366 for name , t in _T_list :
67+ if name .startswith (pref ): continue
6468 for c in cliffords :
6569 new = c .adjoint () @ matrix
6670 new = t .adjoint () @ new
6771 new = new .scale_down ()
6872 if new is None or not new .is_valid ():
6973 continue
70- seq = _xz_sequence (new , False )
74+ seq = _xz_sequence (new , False , name )
7175 if seq is None :
7276 continue
7377 gates = cast (tuple [str , ...], c .gates )
7478 candidates .append (seq + (name ,) + gates )
79+ break
7580 if not candidates :
7681 return None
7782 return min (candidates , key = len )
@@ -113,19 +118,34 @@ def to_sequence(matrix: su2_ct.SU2CliffordT, fmt: str = 'xyz') -> tuple[str, ...
113118}
114119
115120
116- def _to_quirk_name (name : str ) -> str :
117- if name == "I" :
118- return "1"
119- if name in ("X" , "Y" , "Z" , "H" ):
120- return "\" " + name + "\" "
121- if name == "S" :
122- return "\" Z^½\" "
123- if name == "S*" :
124- return "\" Z^-½\" "
125- if name .startswith ("T" ):
126- if name .endswith ("*" ):
127- return "\" " + name [1 ].upper () + "^-¼" + "\" "
128- return "\" " + name [1 ].upper () + "^¼" + "\" "
121+ def _to_quirk_name (name : str , allow_global_phase : bool = False ) -> str :
122+ if allow_global_phase :
123+ if name == "I" :
124+ return "1"
125+ if name in ("X" , "Y" , "Z" , "H" ):
126+ return "\" " + name + "\" "
127+ if name == "S" :
128+ return "\" Z^½\" "
129+ if name == "S*" :
130+ return "\" Z^-½\" "
131+ if name .startswith ("T" ):
132+ if name .endswith ("*" ):
133+ return "\" " + name [1 ].upper () + "^-¼" + "\" "
134+ return "\" " + name [1 ].upper () + "^¼" + "\" "
135+ else :
136+ if name == "I" :
137+ return "1"
138+ if name == "H" :
139+ return "\" H\" "
140+ if name in ("X" , "Y" , "Z" ):
141+ return '{"id":"R%sft","arg":"-pi"}' % (name .lower ())
142+ if name == "S" :
143+ return '{"id":"Rzft","arg":"pi/2"}'
144+ if name == "S*" :
145+ return '{"id":"Rzft","arg":"-pi/2"}'
146+ if name .startswith ("T" ):
147+ angle = ['pi/4' , '-pi/4' ][name .endswith ('*' )]
148+ return '{"id":"R%sft","arg":"%s"}' % (name [1 ].lower (), angle )
129149 raise ValueError (f"{ name = } is not supported" )
130150
131151
@@ -145,13 +165,27 @@ def to_cirq(
145165 return tuple (_CIRQ_GATE_MAP [g ](q ) for g in to_sequence (matrix , fmt ))
146166
147167
148- def to_quirk (matrix : su2_ct .SU2CliffordT , fmt : str ) -> tuple [str , ...]:
168+ def to_quirk (matrix : su2_ct .SU2CliffordT , fmt : str , allow_global_phase : bool = False ) -> tuple [str , ...]:
149169 """Retruns a representation of the matrix as a sequence of quirk symbols.
150170
151171 Args:
152172 matrix: The matrix to represent.
153173 fmt: The gates to use (see the documentation of to_sequence).
174+ allow_global_phase: whether the result can have a global phase or not.
175+ If this is set then each gate (except H) gets replaced by SU2 version:
176+ - S -> Rz(pi/2)
177+ - T -> Rz(pi/4)
178+ - X -> Rx(-pi)
179+ - Y -> Ry(-pi)
180+ - Z -> Rz(-pi)
181+ Then a prefix composed of SXSX that corrects the phase difference caused by H gates
182+ is added.
154183 Returns:
155184 A tuple quirk symbols.
156185 """
157- return tuple (_to_quirk_name (name ) for name in to_sequence (matrix , fmt ))
186+ sequence = to_sequence (matrix , fmt )
187+ phase_correction = ()
188+ if not allow_global_phase :
189+ phase = sum (g == 'H' for g in sequence ) % 4
190+ phase_correction = ('"Z^½"' , '"X"' , '"Z^½"' , '"X"' ) * phase
191+ return phase_correction + tuple (_to_quirk_name (name , allow_global_phase ) for name in sequence )
0 commit comments