Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Naive Implementation of the Encoding Circuit #154

Merged
merged 23 commits into from
Sep 18, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
7f5bfbb
is_degenerate, is_degen tests, and naive implementation of encoding c…
dmtrung14 Jul 6, 2023
36d8133
augment bimatrix in naive_encoding_circuit
dmtrung14 Jul 6, 2023
e6dbb95
uncomment tests
dmtrung14 Jul 6, 2023
05e3c56
minor
dmtrung14 Jul 13, 2023
cd05fff
encoding circuit -split
dmtrung14 Jul 14, 2023
365553a
Slightly better docstring for is_degenerate -- please report in the d…
Krastanov Jul 16, 2023
14604eb
a simplified version of your `standard_tab_gott` - should be doing th…
Krastanov Jul 16, 2023
2a0c94f
provide a `reportperm` keyword argument to the `MixedDestabilizer` co…
Krastanov Jul 16, 2023
460a131
Merge branch 'master' of https://github.com/QuantumSavory/QuantumClif…
dmtrung14 Jul 21, 2023
8f6265a
streamlined standard_tab_gott and added reference
dmtrung14 Jul 21, 2023
2e568de
Merge branch 'minor' of https://github.com/dmtrung14/QuantumClifford.…
dmtrung14 Jul 21, 2023
4cdd2a6
streamlined standard_tab_gott and allowed undoperm and applied to nec
dmtrung14 Jul 29, 2023
cee2e31
Merge branch 'master' into minor
Krastanov Jul 29, 2023
18d505e
clean up and add tests
Krastanov Aug 4, 2023
abba3b2
temporarry changes
dmtrung14 Aug 4, 2023
1c345f8
temporary commit
dmtrung14 Aug 4, 2023
9939e6a
finally implement it, and a bunch of cleanup
Krastanov Sep 17, 2023
88b6d4b
Merge branch 'master' into pr/dmtrung14/154
Krastanov Sep 17, 2023
5b9b0ef
ammend
Krastanov Sep 17, 2023
4db5e8e
fix tests
Krastanov Sep 17, 2023
00a1465
correct for qubit permutations
Krastanov Sep 17, 2023
eb224c9
references
Krastanov Sep 17, 2023
ed698f3
fix documenter
Krastanov Sep 17, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 96 additions & 1 deletion src/ecc/ECC.jl
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,105 @@ function logz_ops(c::AbstractECC)
logicalzview(MixedDest)
end

# TODO implement isdegenerate

""" Check if the code is degenerate or not."""
function is_degenerate(c::AbstractECC)
tableau = stab_to_gf2(parity_checks(c))
n = code_n(c)
dictionary = Set()
for column in 1:2*n
temp = tableau[:, column]
if temp in dictionary
return true
else
push!(dictionary, temp)
end
end
return false
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you document where is this from? Where did you find this algorithm?


"""The rank of the bimatrix of a code."""
function rank(c::AbstractECC)
destab_gott = MixedDestabilizer(parity_checks(c), undoperm=false)
bimat = stab_to_gf2(stabilizerview(destab_gott))
rank = 0
for i in 1:code_s(c)
if bimat[i, i] == 1
rank +=1
end
end
return rank
end

"""The standardized logical tableau of a code by [PhysRevA.56.76](@cite)"""
function standard_tab_gott(c::AbstractECC)
n, s, k, r = code_n(c), code_s(c), code_k(c), rank(c)
# The standard form is
# I A1 A2 | B C1 C2
# 0 0 0 | D I E
# and we augment the following third line (for logical qubits)
# 0 E^T I | 0 0 0
# Then we apply the gates line by line bottom up in accordance with the formalisms here: arXiv:quant-ph/9607030
standard_tab = stab_to_gf2(stabilizerview(MixedDestabilizer(parity_checks(c), undoperm=false)))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

at some point you have to undo the permutations of columns, otherwise your qubits are now reindexed from what the user was expecting, and great amount of confusion can ensue

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also, check this function, it seems to be doing most of what you need. canonicalize_gott specifically seems to be doing all of the necessary steps, including creating the E^T part

function MixedDestabilizer(stab::Stabilizer{T}; undoperm=true) where {T}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nope, I am wrong, it does not do everything you need, but might be a useful inspiration for how to write your code in a more simple way

for i in 1: k
# can we use canonicalize_gott for the entire mixedDestabilizer? (i.e. the stab + log parts = n rows)
augment = zeros(Int8, (1, 2*n))
for j in 1:n
if j > r && j <= n - k
augment[j] = standard_tab[j, 2*n-k+i] # the corresponding column of E in E^T
elseif j == n-k+i
augment[j] = 1
end
end
standard_tab = vcat(standard_tab, augment)
end
# Flipping the table so it has the same format as the papercode
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just use transpose, and if you need to reverse axes you can use reverse. It would be much shorter and more legible.

res = zeros(Int8, (n, 2n))
for i in 1:n
for j in 1:n
res[i, j] = standard_tab[n+1-j, n+1-i]
end
for j in n+1:2*n
res[i,j] = standard_tab[2*n+1-j, n+1-i]
end
end
return res
end


""" The naive implementation of the encoding circuit by arXiv:quant-ph/9607030 """
function naive_encoding_circuit(c::AbstractECC)
n, k, s, r = code_n(c), code_k(c), code_s(c), rank(c)
naive_ec = AbstractOperation[]
# Applying the hadamard gate to the last r qubits
for i in n: -1: n-r+1
push!(naive_ec, sHadamard(i))
end

standard_tab = standard_tab_gott(c)

for i in 1 : n
if standard_tab[i, i] ==1
for j in 1:n
if j == i continue end
gate = (standard_tab[j, i], standard_tab[j, i+n])
if gate == (1,0)
push!(naive_ec, sCNOT(j, i))
elseif gate == (0,1)
push!(naive_ec, sXCZ(j, i))
elseif gate == (1,1)
push!(naive_ec, sXCY(j, i))
end
end
end
end
return naive_ec
end


include("./bitflipcode.jl")
include("./shorcode.jl")
include("./steanecode.jl")
include("./papercode.jl")

end #module
9 changes: 9 additions & 0 deletions src/ecc/papercode.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
struct Paper8 <: AbstractECC end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May we rename this to Cleve8 (from the last name of the author). Paper8 is a bit confusing :D

I will test all of this later today and give comments


code_n(c::Paper8) = 8

parity_checks(c::Paper8) = S"XXXXXXXX
ZZZZZZZZ
XIXIZYZY
XIYZXIYZ
XZIYIYXZ"
39 changes: 35 additions & 4 deletions test/test_ecc.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using Test
using QuantumClifford
using QuantumClifford.ECC: AbstractECC, Steane7, Shor9, Bitflip3, naive_syndrome_circuit, code_n, parity_checks, encoding_circuit, code_s, code_k, rate, distance,logx_ops, logz_ops
using QuantumClifford.ECC: AbstractECC, Paper8, Steane7, Shor9, Bitflip3, naive_syndrome_circuit, code_n, parity_checks, encoding_circuit, code_s, code_k, rate, distance,logx_ops, logz_ops, naive_encoding_circuit, is_degenerate, rank

codes = [
Bitflip3(),
Expand Down Expand Up @@ -57,12 +57,17 @@ end

##

function test_naive_syndrome(c::AbstractECC)
function test_naive_syndrome(c::AbstractECC, e::Bool=false)
# create a random logical state
unencoded_qubits = random_stabilizer(code_k(c))
bufferqubits = one(Stabilizer,code_s(c))
logicalqubits = unencoded_qubits⊗bufferqubits
mctrajectory!(logicalqubits, encoding_circuit(c))
if e
#add some noise to logicalqubits
apply!(logicalqubits, P"X", rand(1:code_n(c)))
apply!(logicalqubits, P"Z", rand(1:code_n(c)))
end
# measure using `project!`
s1 = copy(logicalqubits)
syndrome1 = [project!(s1, check)[3] for check in parity_checks(c)]
Expand All @@ -72,8 +77,10 @@ function test_naive_syndrome(c::AbstractECC)
s2 = copy(logicalqubits)
syndrome2 = Register(s2⊗ancillaryqubits, falses(code_s(c)))
mctrajectory!(syndrome2, naive_circuit)
@test all(syndrome1 .== 0)
@test all(bitview(syndrome2) .== 0)
if !e
@test all(syndrome1 .== 0)
@test all(bitview(syndrome2) .== 0)
end
@test bitview(syndrome2) == syndrome1.÷2

# TODO test when there is potential for errors / non-commuting operators
Expand All @@ -82,6 +89,7 @@ end
@testset "naive syndrome circuits - zero syndrome for logical states" begin
for c in codes, _ in 1:2
test_naive_syndrome(c)
test_naive_syndrome(c, true)
end
end

Expand All @@ -105,3 +113,26 @@ end
test_with_pframes(c)
end
end


##


function test_is_degenerate(c::AbstractECC)
if c == Shor9()
@test is_degenerate(c) == true
elseif c == Steane7()
@test is_degenerate(c) == false
elseif c== Bitflip3()
@test is_degenerate(c) == true
end
end

@testset "is degenerate function - test on popular codes" begin
for c in codes
test_is_degenerate(c)
end
end

##