1- """ the `apply_right!` function is used to prepend any quantum operation to unitary Clifford operation"""
1+ """ the `apply_right!` function is used to right multiply any quantum operation to unitary
2+ Clifford operation or Pauli product"""
23function apply_right! end
34
4- function apply_right! (l:: CliffordOperator , r:: AbstractCliffordOperator ; phases= true )
5- @warn " Slow apply_right! operation: $r "
6- apply! (CliffordOperator (r, nqubits (l)), l; phases= phases)
7- end
85
9- # helper
6+ # dense_cliffords
7+
8+ function apply_right! (l:: CliffordOperator , r:: PauliOperator ; phases= false )
9+ nqubits (l)== nqubits (r) || throw (DimensionMismatch (" The Clifford and Pauli operators need to act on the same number of qubits." ))
10+ tab (l). phases[nqubits (l)+ 1 : end ] .⊻= r[1 : nqubits (l)]
11+ tab (l). phases[1 : nqubits (l)] .⊻= r[nqubits (l)+ 1 : end ]
12+ end
13+
14+ function apply_right! (l:: CliffordOperator , r:: CliffordOperator ; phases= true )
15+ nqubits (l)== nqubits (r) || throw (DimensionMismatch (" The two Clifford operators need to act on the same number of qubits." ))
16+ l_tab = tab (l)
17+ r_tab = tab (r)
18+ threadlocal = l. buffer
19+ new_xzs = Vector {typeof(threadlocal)} (undef, length (l_tab))
20+ @inbounds for row_r in eachindex (r_tab)
21+ zero! (threadlocal)
22+ apply_right_row_kernel! (threadlocal, row_r, l_tab, r_tab, phases= phases)
23+ new_xzs[row_r] = copy (threadlocal)
24+ end
25+ @inbounds for row_l in eachindex (l_tab)
26+ l_tab[row_l] = new_xzs[row_l]
27+ end
28+ l
29+ end
30+
31+ @inline function apply_right_row_kernel! (new_lrow, row, l_tab, r_tab; phases= true )
32+ phases && (new_lrow. phase[] = r_tab. phases[row])
33+ n = nqubits (l_tab)
34+ for qubit in 1 : n
35+ x,z = r_tab[row,qubit]
36+ if phases&& x&& z
37+ new_lrow. phase[] -= 0x1
38+ end
39+ if x
40+ mul_left! (new_lrow, l_tab, qubit, phases= Val (phases))
41+ end
42+ if z
43+ mul_left! (new_lrow, l_tab, qubit+ n, phases= Val (phases))
44+ end
45+ end
46+ new_lrow
47+ end
48+
49+
50+ # symbolic_cliffords
51+
1052function mul_right_ignore_anticommute! (l:: PauliOperator , r:: PauliOperator )
1153 x = mul_right! (l, r; phases= Val (true ))
1254 x. phase[] = x. phase[] & 0x02
@@ -36,7 +78,7 @@ function apply_right!(l::CliffordOperator, r::sHadamardYZ)
3678end
3779
3880function apply_right! (l:: CliffordOperator , r:: sPhase )
39- l[r . q] = mul_right_ignore_anticommute ! (l[r . q], l[ nqubits (l) + r. q] )
81+ apply_right ! (l, sInvPhase ( r. q) )
4082 apply_right! (l, sZ (r. q))
4183 return l
4284end
@@ -85,17 +127,6 @@ function apply_right!(l::CliffordOperator, r::sInvSQRTY)
85127 return l
86128end
87129
88- function apply_right! (l:: CliffordOperator , r:: sPhase )
89- apply_right! (l, sInvPhase (r. q))
90- apply_right! (l, sZ (r. q))
91- return l
92- end
93-
94- function apply_right! (l:: CliffordOperator , r:: sInvPhase )
95- l[r. q] = mul_right_ignore_anticommute! (l[r. q], l[nqubits (l)+ r. q])
96- return l
97- end
98-
99130function apply_right! (l:: CliffordOperator , r:: sCXYZ )
100131 rowswap! (tab (l), r. q, nqubits (l)+ r. q)
101132 l[r. q] = mul_right_ignore_anticommute! (l[r. q], l[nqubits (l)+ r. q])
@@ -124,14 +155,17 @@ function apply_right!(l::CliffordOperator, r::sSWAP)
124155 return l
125156end
126157
127- # function apply_right!(l::CliffordOperator, r::sSWAPCX)
128- # rowswap!(tab(l), r.q1, r.q2)
129- # return l
130- # end
158+ function apply_right! (l:: CliffordOperator , r:: sSWAPCX )
159+ apply_right! (l, sSWAP (r. q1, r. q2))
160+ apply_right! (l, sCNOT (r. q2, r. q1))
161+ return l
162+ end
131163
132- # function apply_right!(l::CliffordOperator, r::sInvSWAPCX)
133- # return l
134- # end
164+ function apply_right! (l:: CliffordOperator , r:: sInvSWAPCX )
165+ apply_right! (l, sCNOT (r. q2, r. q1))
166+ apply_right! (l, sSWAP (r. q1, r. q2))
167+ return l
168+ end
135169
136170function apply_right! (l:: CliffordOperator , r:: sISWAP )
137171 apply_right! (l, sSWAP (r. q1, r. q2))
@@ -149,21 +183,26 @@ function apply_right!(l::CliffordOperator, r::sInvISWAP)
149183 return l
150184end
151185
152- # function apply_right!(l::CliffordOperator, r::sCZSWAP)
153- # return l
154- # end
186+ function apply_right! (l:: CliffordOperator , r:: sCZSWAP )
187+ apply_right! (l, sZCZ (r. q2, r. q1))
188+ apply_right! (l, sSWAP (r. q1, r. q2))
189+ return l
190+ end
155191
156- # function apply_right!(l::CliffordOperator, r::sCXSWAP)
157- # return l
158- # end
192+ function apply_right! (l:: CliffordOperator , r:: sCXSWAP )
193+ apply_right! (l, sCNOT (r. q2, r. q1))
194+ apply_right! (l, sSWAP (r. q1, r. q2))
195+ return l
196+ end
159197
160198function apply_right! (l:: CliffordOperator , r:: sCNOT )
161199 return apply_right! (l, sZCX (r. q1, r. q2))
162200end
163201
164- # function apply_right!(l::CliffordOperator, r::sCPHASE)
165- # return l
166- # end
202+ function apply_right! (l:: CliffordOperator , r:: sCPHASE )
203+ apply_right! (l, sZCZ (r. q1, r. q2))
204+ return l
205+ end
167206
168207function apply_right! (l:: CliffordOperator , r:: sZCX )
169208 l[nqubits (l)+ r. q2] = mul_right! (l[nqubits (l)+ r. q2], l[nqubits (l)+ r. q1]; phases= Val (true ))
@@ -218,13 +257,22 @@ function apply_right!(l::CliffordOperator, r::sYCZ)
218257 return apply_right! (l, sZCY (r. q2, r. q1))
219258end
220259
221- # function apply_right!(l::CliffordOperator, r::sZCrY)
222- # return l
223- # end
260+ function apply_right! (l:: CliffordOperator , r:: sZCrY )
261+ l[r. q1] = mul_left! (l[r. q1], l[r. q2])
262+ l[r. q2] = mul_left! (l[r. q2], l[nqubits (l)+ r. q1])
263+ l[nqubits (l)+ r. q2] = mul_left! (l[nqubits (l)+ r. q2], l[nqubits (l)+ r. q1])
264+ l[r. q1] = mul_left! (l[r. q1], l[nqubits (l)+ r. q2])
265+ return l
266+ end
224267
225- # function apply_right!(l::CliffordOperator, r::sInvZCrY)
226- # return l
227- # end
268+ function apply_right! (l:: CliffordOperator , r:: sInvZCrY )
269+ l[r. q1] = mul_left! (l[r. q1], l[r. q2])
270+ l[r. q2] = mul_left! (l[r. q2], l[nqubits (l)+ r. q1])
271+ l[nqubits (l)+ r. q2] = mul_left! (l[nqubits (l)+ r. q2], l[nqubits (l)+ r. q1])
272+ l[r. q1] = mul_left! (l[r. q1], l[nqubits (l)+ r. q2])
273+ phases (tab (l))[r. q1] ⊻= 0x02
274+ return l
275+ end
228276
229277function apply_right! (l:: CliffordOperator , r:: sSQRTZZ )
230278 apply_right! (l, sInvSQRTZZ (r. q1, r. q2))
0 commit comments