Skip to content

Commit

Permalink
adding new single-qubit gates (QuantumSavory#333)
Browse files Browse the repository at this point in the history

Co-authored-by: Stefan Krastanov <github.acc@krastanov.org>
Co-authored-by: Stefan Krastanov <stefan@krastanov.org>
  • Loading branch information
3 people authored Sep 14, 2024
1 parent 381f43c commit 05491d9
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 22 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

## dev

- Implementing many more named single-qubit gates following naming convention similar to the stim package in python.
- **(fix)** Bug fix to the `parity_checks(ReedMuller(r, m))` of classical Reed-Muller code (it was returning generator matrix).
- `RecursiveReedMuller` code implementation as an alternative implementation of `ReedMuller`.

Expand Down
1 change: 1 addition & 0 deletions src/QuantumClifford.jl
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export
# Symbolic Clifford Ops
AbstractSymbolicOperator, AbstractSingleQubitOperator, AbstractTwoQubitOperator,
sHadamard, sPhase, sInvPhase, SingleQubitOperator, sId1, sX, sY, sZ,
sHadamardXY, sHadamardYZ, sSQRTX, sInvSQRTX, sSQRTY, sInvSQRTY, sCXYZ, sCZYX,
sCNOT, sCPHASE, sSWAP,
sXCX, sXCY, sXCZ, sYCX, sYCY, sYCZ, sZCX, sZCY, sZCZ,
sZCrY, sInvZCrY,
Expand Down
65 changes: 44 additions & 21 deletions src/symbolic_cliffords.jl
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,20 @@ macro qubitop1(name, kernel)
end
end

@qubitop1 Hadamard (z , x , x!=0 && z!=0)
@qubitop1 Phase (x , xz , x!=0 && z!=0)
@qubitop1 InvPhase (x , xz , x!=0 && z==0)
@qubitop1 X (x , z , z!=0)
@qubitop1 Y (x , z , (xz)!=0)
@qubitop1 Z (x , z , x!=0)
@qubitop1 Hadamard (z ,x , x!=0 && z!=0)
@qubitop1 HadamardXY (x ,xz , x==0 && z!=0)
@qubitop1 HadamardYZ (xz ,z , x!=0 && z==0)
@qubitop1 Phase (x ,xz , x!=0 && z!=0)
@qubitop1 InvPhase (x ,xz , x!=0 && z==0)
@qubitop1 X (x ,z , z!=0)
@qubitop1 Y (x ,z , (xz)!=0)
@qubitop1 Z (x ,z , x!=0)
@qubitop1 SQRTX (xz ,z , x==0 && z!=0)
@qubitop1 InvSQRTX (xz ,z , x!=0 && z!=0)
@qubitop1 SQRTY (z ,x , z==0)
@qubitop1 InvSQRTY (z ,x , z!=0 && x==0)
@qubitop1 CXYZ (xz ,x , z==0 && x==0)
@qubitop1 CZYX (z ,xz , z==0 && x==0)

"""A "symbolic" single-qubit Identity operation.
Expand Down Expand Up @@ -177,13 +185,21 @@ function _apply!(stab::AbstractStabilizer, op::SingleQubitOperator; phases::Val{
stab
end

SingleQubitOperator(h::sHadamard) = SingleQubitOperator(h.q, false, true , true , false, false, false)
SingleQubitOperator(p::sPhase) = SingleQubitOperator(p.q, true , true , false, true , false, false)
SingleQubitOperator(p::sInvPhase) = SingleQubitOperator(p.q, true , true , false, true , true , false)
SingleQubitOperator(p::sId1) = SingleQubitOperator(p.q, true , false, false, true , false, false)
SingleQubitOperator(p::sX) = SingleQubitOperator(p.q, true , false, false, true , false, true)
SingleQubitOperator(p::sY) = SingleQubitOperator(p.q, true , false, false, true , true , true)
SingleQubitOperator(p::sZ) = SingleQubitOperator(p.q, true , false, false, true , true , false)
SingleQubitOperator(h::sHadamard) = SingleQubitOperator(h.q, false, true , true , false, false, false)
SingleQubitOperator(p::sPhase) = SingleQubitOperator(p.q, true , true , false, true , false, false)
SingleQubitOperator(p::sInvPhase) = SingleQubitOperator(p.q, true , true , false, true , true , false)
SingleQubitOperator(p::sId1) = SingleQubitOperator(p.q, true , false, false, true , false, false)
SingleQubitOperator(p::sX) = SingleQubitOperator(p.q, true , false, false, true , false, true)
SingleQubitOperator(p::sY) = SingleQubitOperator(p.q, true , false, false, true , true , true)
SingleQubitOperator(p::sZ) = SingleQubitOperator(p.q, true , false, false, true , true , false)
SingleQubitOperator(p::sCXYZ) = SingleQubitOperator(p.q, true , true , true , false, false, false)
SingleQubitOperator(p::sCZYX) = SingleQubitOperator(p.q, false, true , true , true , false, false)
SingleQubitOperator(p::sHadamardXY) = SingleQubitOperator(p.q, true , true , false, true , false, true)
SingleQubitOperator(p::sHadamardYZ) = SingleQubitOperator(p.q, true , false, true , true , true , false)
SingleQubitOperator(p::sSQRTX) = SingleQubitOperator(p.q, true , false, true , true , false, true)
SingleQubitOperator(p::sInvSQRTX) = SingleQubitOperator(p.q, true , false, true , true , false, false)
SingleQubitOperator(p::sSQRTY) = SingleQubitOperator(p.q, false, true , true , false, true , false)
SingleQubitOperator(p::sInvSQRTY) = SingleQubitOperator(p.q, false, true , true , false, false, true)
SingleQubitOperator(o::SingleQubitOperator) = o
function SingleQubitOperator(op::CliffordOperator, qubit)
nqubits(op)==1 || throw(DimensionMismatch("You are trying to convert a multiqubit `CliffordOperator` into a symbolic `SingleQubitOperator`."))
Expand Down Expand Up @@ -232,14 +248,21 @@ function LinearAlgebra.inv(op::SingleQubitOperator)
return SingleQubitOperator(c, op.q)
end

LinearAlgebra.inv(h::sHadamard) = sHadamard(h.q)
LinearAlgebra.inv(p::sPhase) = sInvPhase(p.q)
LinearAlgebra.inv(p::sInvPhase) = sPhase(p.q)
LinearAlgebra.inv(p::sId1) = sId1(p.q)
LinearAlgebra.inv(p::sX) = sX(p.q)
LinearAlgebra.inv(p::sY) = sY(p.q)
LinearAlgebra.inv(p::sZ) = sZ(p.q)

LinearAlgebra.inv(h::sHadamard) = sHadamard(h.q)
LinearAlgebra.inv(p::sPhase) = sInvPhase(p.q)
LinearAlgebra.inv(p::sInvPhase) = sPhase(p.q)
LinearAlgebra.inv(p::sId1) = sId1(p.q)
LinearAlgebra.inv(p::sX) = sX(p.q)
LinearAlgebra.inv(p::sY) = sY(p.q)
LinearAlgebra.inv(p::sZ) = sZ(p.q)
LinearAlgebra.inv(p::sHadamardXY) = sHadamardXY(p.q)
LinearAlgebra.inv(p::sHadamardYZ) = sHadamardYZ(p.q)
LinearAlgebra.inv(p::sSQRTX) = sInvSQRTX(p.q)
LinearAlgebra.inv(p::sInvSQRTX) = sSQRTX(p.q)
LinearAlgebra.inv(p::sSQRTY) = sInvSQRTY(p.q)
LinearAlgebra.inv(p::sInvSQRTY) = sSQRTY(p.q)
LinearAlgebra.inv(p::sCZYX) = sCXYZ(p.q)
LinearAlgebra.inv(p::sCXYZ) = sCZYX(p.q)
##############################
# Two-qubit gates
##############################
Expand Down
13 changes: 12 additions & 1 deletion test/test_symcliff.jl
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
end

@testset "SingleQubitOperator inv methods" begin
for gate_type in [sHadamard, sX, sY, sZ, sId1 , sPhase, sInvPhase]
for gate_type in filter(gate_type -> gate_type != SingleQubitOperator, subtypes(AbstractSingleQubitOperator))
n = rand(1:10)
@test CliffordOperator(inv(SingleQubitOperator(gate_type(n))), n) == inv(CliffordOperator(gate_type(n), n))
@test CliffordOperator(inv(gate_type(n)), n) == inv(CliffordOperator(gate_type(n), n))
Expand All @@ -76,6 +76,17 @@
@test CliffordOperator(inv(random_op), i) == inv(CliffordOperator(random_op, i))
@test CliffordOperator(inv(SingleQubitOperator(random_op)), i) == inv(CliffordOperator(random_op, i))
end

@testset "Consistency checks with Stim" begin
# see https://github.com/quantumlib/Stim/blob/main/doc/gates.md
@test CliffordOperator(sCXYZ) == C"Y X"
@test CliffordOperator(sCZYX) == C"Z Y"
@test CliffordOperator(sSQRTX) == C"X -Y"
@test CliffordOperator(sSQRTY) == C"-Z X"
@test CliffordOperator(sInvSQRTX) == C"X Y"
@test CliffordOperator(sInvSQRTY) == C"Z -X"
@test CliffordOperator(sHadamardXY) == C"Y -Z"
@test CliffordOperator(sHadamardYZ) == C"-X Y"
end

@testset "TwoQubitOperator inv methods" begin
Expand Down

0 comments on commit 05491d9

Please sign in to comment.