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

Color codes support 1 #361

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions src/ecc/ECC.jl
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,7 @@ include("codes/gottesman.jl")
include("codes/surface.jl")
include("codes/concat.jl")
include("codes/random_circuit.jl")
include("codes/color_codes.jl")
Copy link
Member

Choose a reason for hiding this comment

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

oh, I forgot. The newly implemented codes should also be exported so that they are part of the public API of the library (see at the start of this file)

include("codes/classical/reedmuller.jl")
include("codes/classical/bch.jl")
include("codes/classical/recursivereedmuller.jl")
Expand Down
208 changes: 208 additions & 0 deletions src/ecc/codes/color_codes.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
abstract type ColorCode <: AbstractECC end

"""Planar color codes that encode a single logical qubit."""
abstract type TriangularCode <: ColorCode end

"""Triangular code following the 4.8.8 tiling. Constructor take a distance d as input."""
Copy link
Member

Choose a reason for hiding this comment

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

Yet one more thing I forgot. This should have a [](@cite) reference, that reference should be added to the bibtex file and to the listing of references in the "suggested readings" doc page.

struct Triangular4_8_8 <: TriangularCode
Copy link
Member

Choose a reason for hiding this comment

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

darn, these underscores are a bit jarring... How about switching to Triangular488 - I know it will be weird if we ever implement patterns with double digits, but by then we might just have a more general-purpose constructor.

Same for the other code implemented here.

d::Int
function Triangular4_8_8(d)
if d%2!=1
throw(DomainError("only odd distance trianglular color codes are allowed.\nRefer to https://arxiv.org/abs/1108.5738"))

Check warning on line 11 in src/ecc/codes/color_codes.jl

View workflow job for this annotation

GitHub Actions / Spell Check with Typos

"trianglular" should be "triangular".
Copy link
Member

Choose a reason for hiding this comment

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

Given that it ends on a full stop, it seems like a sentence, so let's capitalize the first letter.

end
return new(d)
end
end

"""Triangular code following the 6.6.6 tiling. Constructor take a distance d as input."""
struct Triangular6_6_6 <: TriangularCode
d::Int
function Triangular6_6_6(d)
if d%2!=1
throw(DomainError("only odd distance trianglular color codes are allowed.\nRefer to https://arxiv.org/abs/1108.5738"))

Check warning on line 22 in src/ecc/codes/color_codes.jl

View workflow job for this annotation

GitHub Actions / Spell Check with Typos

"trianglular" should be "triangular".
Copy link
Member

Choose a reason for hiding this comment

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

Given that it ends on a full stop, it seems like a sentence, so let's capitalize the first letter.

end
return new(d)
end
end

Triangular4_8_8() = Triangular4_8_8(3) # smallest d
Triangular6_6_6() = Triangular6_6_6(3) # smallest d

function parity_checks(c::TriangularCode)
matrix = get_check_matrix(c)

num_checks, qubits = size(matrix)
return Stabilizer(vcat(matrix,zeros(Bool,num_checks,qubits)), vcat(zeros(Bool,num_checks,qubits), matrix))
Copy link
Member

Choose a reason for hiding this comment

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

This looks like it would be much simpler to do by writing something like parity_checks(CSS(matrix, matrix)) (as there is a general-purpose CSS type already in existence).

I am also leaning towards just putting the content of get_check_matrix in here directly. The redirection seems unnecessary (especially if the simpler CSS(matrix,matrix) expression is used)

end

function get_check_matrix(c::Triangular6_6_6)
Copy link
Member

Choose a reason for hiding this comment

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

This seems to be a private helper meant to exist only for color codes. Change the name to reflect that (or just remove that function altogether and directly use parity_checks)

# TODO make code look a bit nicer by copying the style of the "init_pos" code blocks
n = code_n(c)
num_checks = (n-1)/2 |> Int
num_layers = (c.d-1)/2 |> Int
Comment on lines +41 to +42
Copy link
Member

Choose a reason for hiding this comment

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

÷ (div), not /

checks = zeros(Bool, num_checks, n)

i = 1
checks_written = 0
for layer in 1:num_layers
# extend half 6-gons from last iteration to full hexagons
num_6_gons = layer-1
checks_written -= num_6_gons
for j in 1:(num_6_gons)
init_pos = i + 2*(j-1)
checks[checks_written+1,init_pos+2*(layer-1)+1] = 1
checks[checks_written+1,init_pos+2*(layer-1)+2] = 1
checks_written+=1
end

# red trapezoid
checks[checks_written+1,i] = 1
checks[checks_written+1,i+(layer-1)*2+1] = 1
checks[checks_written+1,i+2+4*(layer-1)] = 1
checks[checks_written+1,i+2+4*(layer-1)+1] = 1
checks_written += 1

# blue trapezoid
checks[checks_written+1,i+1+4*(layer-1)] = 1
checks[checks_written+1,i+1+4*(layer-1)+layer*2] = 1
checks[checks_written+1,i+5+8*(layer-1)] = 1
checks[checks_written+1,i+5+8*(layer-1)+1] = 1
checks_written += 1

# red hexagons
for j in 1:(layer-1)
checks[checks_written+1,i+(j-1)*2+1] = 1
checks[checks_written+1,i+(j-1)*2+2] = 1
checks[checks_written+1,i+(j-1)*2+2+2*(layer-1)] = 1
checks[checks_written+1,i+(j-1)*2+2+2*(layer-1)+1] = 1
checks[checks_written+1,i+(j-1)*2+2+2*(layer-1)+layer*2] = 1
checks[checks_written+1,i+(j-1)*2+2+2*(layer-1)+layer*2+1] = 1

checks_written += 1
end

# blue hexagons
for j in 1:(layer-1)
init_pos = i+(j-1)*2+(layer-1)*2+1
checks[checks_written+1, init_pos] = 1
checks[checks_written+1, init_pos+1] = 1
checks[checks_written+1, init_pos+2*layer] = 1
checks[checks_written+1, init_pos+2*layer+1] = 1
checks[checks_written+1, init_pos+4*layer] = 1
checks[checks_written+1, init_pos+4*layer+1] = 1

checks_written += 1
end

# green half 6gons
for j in 0:(layer-1)
init_pos = i+2*j+2+4*(layer-1)
checks[checks_written+1,init_pos] = 1
checks[checks_written+1,init_pos+1] = 1
checks[checks_written+1,init_pos+2*layer] = 1
checks[checks_written+1,init_pos+2*layer+1] = 1
checks_written += 1
end

i += 4+6*(layer-1)
end

return checks
end

"""Returns the binary matrix defining the X stabilizers for the Triangular4_8_8 code. The Z stabilizers are the same.
Based on Fig. 2 of https://arxiv.org/abs/1108.5738"""
function get_check_matrix(c::Triangular4_8_8)
n = code_n(c)
num_checks = (n-1)/2 |> Int
Copy link
Member

Choose a reason for hiding this comment

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

if you know for a fact these will be integers, use ÷ not / (or div if you do not like using unicode)

num_layers = (c.d-1)/2 |> Int
Copy link
Member

Choose a reason for hiding this comment

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

same comment

checks = zeros(Bool, num_checks, n)

i = 1
checks_written = 0
for layer in 1:num_layers
# Convert half 8-gons from previous layer into full 8-gons
num_8_gons = layer-1
checks_written -= num_8_gons
for j in 1:(num_8_gons)
checks[checks_written+1,i+2*layer+1+(j-1)*2] = 1
checks[checks_written+1,i+2*layer+j*2] = 1

offset = 0
if layer == num_layers && num_layers%2==0
offset = 1
end

checks[checks_written+1,(2*layer+1)+i+2*layer+1+(j-1)*2 - offset] = 1
checks[checks_written+1,(2*layer+1)+i+2*layer+j*2 - offset] = 1

checks_written += 1
end

# red 4-gons
for j in 0:(layer-1)
checks[checks_written+1,i+j*2] = 1
checks[checks_written+1,i+1+j*2] = 1
checks[checks_written+1,i+2*layer+j*2] = 1
checks[checks_written+1,i+2*layer+1+j*2] = 1
checks_written += 1
end

if layer%2 == 1
# green half 8-gons on left side
checks[checks_written+1,i] = 1
checks[checks_written+1,i+2*layer] = 1
checks[checks_written+1,i+4*layer] = 1
checks[checks_written+1,i+4*layer+1] = 1
checks_written += 1
else
# blue half 8-gon on right side
checks[checks_written+1,i+1+(layer-1)*2] = 1
checks[checks_written+1,i+2*layer+1+(layer-1)*2] = 1

# when d=5,9,13,... the final row qubits is indexed slightly differently.
offset = 0
if layer == num_layers
offset = 1
end

checks[checks_written+1,(i+4*layer)+layer*2-offset] = 1
checks[checks_written+1,(i+4*layer)+1+layer*2-offset] = 1
checks_written += 1
end

# blue/green half 8-gons on the bottom
for j in 0:(layer-1)
checks[checks_written+1,i+2*layer+j*2] = 1
checks[checks_written+1,i+2*layer+1+j*2] = 1

offset = 0
if layer == num_layers && num_layers%2==0
offset = 1
end

checks[checks_written+1,(2*layer+1)+i+2*layer+j*2 - offset] = 1
checks[checks_written+1,(2*layer+1)+i+2*layer+1+j*2 - offset] = 1

checks_written += 1
end

i += 4*layer
end
return checks
end

"""Returns which qubits each stabilizer touches when given a parity check matrix. Useful for debugging/testing."""
function get_qubit_indices(matrix::Matrix{Bool})
Copy link
Member

Choose a reason for hiding this comment

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

This seems to be specific to color codes and it seems to be private. Change the name to reflect that, e.g. _colorcode_get_qubit_indices

for j in 1:size(matrix)[1] println(findall(>(0),matrix[j,:])) end
return
end

function iscss(::ColorCode)
return true
end

"""From https://arxiv.org/abs/1108.5738 Fig. 2's caption:"""
Copy link
Member

Choose a reason for hiding this comment

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

Remove this docstring or turn it into a comment.

The way it is currently done, this will pop up in the documentation in the docstring for the general code_n function, which does not seem to be the goal.

code_n(c::Triangular4_8_8) = 0.5*c.d^2+c.d-0.5 |> Int
code_n(c::Triangular6_6_6) = 0.75*c.d^2+.25 |> Int
code_k(c::TriangularCode) = 1
Loading