You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CHANGELOG.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,6 +7,7 @@
7
7
8
8
## v0.10.1-dev
9
9
10
+
- Implementing `apply_inv!` for direct application of the inverse of a given gate.
10
11
- The lifted product code constructor `LPCode` now supports non-commutative group algebras by appropriate switching left/right representations — particularly useful now that there is also an `Oscar` extension, which provides many non-abelian group constructors.
11
12
- Introduce `metacheck_matrix_x`, `metacheck_matrix_z`, and `metacheck_matrix` for CSS codes built using chain complexes and homology.
12
13
-`ReedMuller`, `RecursiveReedMuller`, and `QuantumReedMuller` are moved to `QECCore` from `QuantumClifford.ECC`.
nqubits(stab)==nqubits(c) ||throw(DimensionMismatch("The tableau and the Clifford operator need to act on the same number of qubits. Consider specifying an array of indices as a third argument to the `apply!` function to avoid this error."))
@@ -132,6 +137,10 @@ function _apply!(stab::AbstractStabilizer, c::CliffordOperator; phases::Val{B}=V
132
137
stab
133
138
end
134
139
140
+
function_apply_inv!(stab::AbstractStabilizer, c::CliffordOperator; phases::Val{B}=Val(true)) where B
141
+
_apply!(stab, inv(c); phases=phases)
142
+
end
143
+
135
144
#TODO Added a lot of type assertions to help Julia infer types, but they are much too strict for cases where bitpacking varies (check tests)
136
145
@inlinefunctionapply_row_kernel!(new_stabrow, row, s_tab, c_tab; phases::Val{B}=Val(true)) where B
137
146
B && (new_stabrow.phase[] = s_tab.phases[row])
@@ -177,6 +186,10 @@ function _apply!(stab::AbstractStabilizer, c::CliffordOperator, indices_of_appli
177
186
stab
178
187
end
179
188
189
+
function_apply_inv!(stab::AbstractStabilizer, c::CliffordOperator, indices_of_application::AbstractArray{Int,1}; phases::Val{B}=Val(true)) where B
Copy file name to clipboardExpand all lines: src/symbolic_cliffords.jl
+88-44Lines changed: 88 additions & 44 deletions
Original file line number
Diff line number
Diff line change
@@ -57,7 +57,7 @@ Base.@propagate_inbounds setzbit(xzs::AbstractMatrix{T}, r::Int, c::Int, z::T, s
57
57
# Single-qubit gates
58
58
##############################
59
59
60
-
function_apply!(stab::AbstractStabilizer, gate::G; phases::Val{B}=Val(true)) where {B, G<:AbstractSingleQubitOperator}
60
+
function_apply!(stab::AbstractStabilizer, gate::AbstractSingleQubitOperator; phases::Val{B}=Val(true)) where {B}
61
61
s =tab(stab)
62
62
c = gate.q
63
63
@inbounds@simdfor r ineachindex(s)
@@ -71,8 +71,22 @@ function _apply!(stab::AbstractStabilizer, gate::G; phases::Val{B}=Val(true)) wh
71
71
stab
72
72
end
73
73
74
+
function_apply_inv!(stab::AbstractStabilizer, gate::AbstractSingleQubitOperator; phases::Val{B}=Val(true)) where {B} # code repetition with the corresponding `_apply`
75
+
s =tab(stab)
76
+
c = gate.q
77
+
@inbounds@simdfor r ineachindex(s)
78
+
x =getxbit(s, r, c)
79
+
z =getzbit(s, r, c)
80
+
x,z,phase =inv_qubit_kernel(gate,x,z)
81
+
setxbit(s, r, c, x)
82
+
setzbit(s, r, c, z)
83
+
B && phase && (s.phases[r] = (s.phases[r]+0x2)&3)
84
+
end
85
+
stab
86
+
end
87
+
74
88
"""Macro used to define single qubit symbolic gates and their `qubit_kernel` methods."""
75
-
macroqubitop1(name, kernel)
89
+
macroqubitop1(name, kernel, inv_kernel)
76
90
prefixname =Symbol(:s,name)
77
91
docstring ="A \"symbolic\" single-qubit $name. See also: [`SingleQubitOperator`](@ref), [`AbstractSymbolicOperator`](@ref)"
function_apply!(stab::AbstractStabilizer, gate::G; phases::Val{B}=Val(true)) where {B, G<:AbstractTwoQubitOperator}
291
+
function_apply!(stab::AbstractStabilizer, gate::AbstractTwoQubitOperator; phases::Val{B}=Val(true)) where {B}
274
292
s =tab(stab)
275
293
q1 = gate.q1
276
294
q2 = gate.q2
@@ -295,8 +313,33 @@ function _apply!(stab::AbstractStabilizer, gate::G; phases::Val{B}=Val(true)) wh
295
313
stab
296
314
end
297
315
316
+
function_apply_inv!(stab::AbstractStabilizer, gate::AbstractTwoQubitOperator; phases::Val{B}=Val(true)) where {B} # code repetition with the corresponding `_apply`
317
+
s =tab(stab)
318
+
q1 = gate.q1
319
+
q2 = gate.q2
320
+
Tₘₑ =eltype(s.xzs)
321
+
shift =getshift(Tₘₑ, q1) -getshift(Tₘₑ, q2)
322
+
@inbounds@simdfor r ineachindex(s)
323
+
# for r in eachindex(s)
324
+
x1 =getxbit(s, r, q1)
325
+
z1 =getzbit(s, r, q1)
326
+
x2 =getxbit(s, r, q2)<<shift
327
+
z2 =getzbit(s, r, q2)<<shift
328
+
x1,z1,x2,z2,phase =inv_qubit_kernel(gate,x1,z1,x2,z2) # Most `inv_qubit_kernel` functions are defined by a `qubitop2` macro
329
+
setxbit(s, r, q1, x1, 0)
330
+
setzbit(s, r, q1, z1, 0)
331
+
setxbit(s, r, q2, x2, -shift)
332
+
setzbit(s, r, q2, z2, -shift)
333
+
if B && phase
334
+
s.phases[r] +=0x2
335
+
s.phases[r] &=3
336
+
end
337
+
end
338
+
stab
339
+
end
340
+
298
341
"""Macro used to define 2-qubit symbolic gates and their `qubit_kernel` methods."""
299
-
macroqubitop2(name, kernel)
342
+
macroqubitop2(name, kernel, inv_kernel)
300
343
prefixname =Symbol(:s,name)
301
344
docstring ="A \"symbolic\"$name. See also: [`AbstractSymbolicOperator`](@ref)"
0 commit comments