qec 0.0.11__py3-none-any.whl → 0.2.0__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- qec/__init__.py +0 -0
- qec/quantum_codes/__init__.py +2 -0
- qec/quantum_codes/codetables_de.py +93 -0
- qec/quantum_codes/five_qubit_code.py +67 -0
- qec/stabilizer_code/__init__.py +1 -0
- qec/stabilizer_code/css_code.py +6 -0
- qec/stabilizer_code/stabilizer_code.py +609 -0
- qec/utils/__init__.py +0 -0
- qec/utils/binary_pauli_utils.py +401 -0
- qec/utils/codetables_de_utils.py +272 -0
- qec/utils/sparse_binary_utils.py +64 -0
- qec-0.2.0.dist-info/LICENSE +21 -0
- qec-0.2.0.dist-info/METADATA +82 -0
- qec-0.2.0.dist-info/RECORD +16 -0
- {qec-0.0.11.dist-info → qec-0.2.0.dist-info}/WHEEL +1 -1
- qec/css.py +0 -164
- qec/hgp.py +0 -75
- qec/lifted_hgp.py +0 -79
- qec/protograph.py +0 -150
- qec/quantum_codes.py +0 -185
- qec/stab.py +0 -119
- qec/xzzx_codes.py +0 -333
- qec-0.0.11.dist-info/METADATA +0 -18
- qec-0.0.11.dist-info/RECORD +0 -11
- {qec-0.0.11.dist-info → qec-0.2.0.dist-info}/top_level.txt +0 -0
qec/quantum_codes.py
DELETED
@@ -1,185 +0,0 @@
|
|
1
|
-
import numpy as np
|
2
|
-
from qec.hgp import hgp_single,hgp
|
3
|
-
# from .hgp3d import hgp3d
|
4
|
-
from ldpc.codes import rep_code,ring_code,hamming_code
|
5
|
-
from .css import css_code
|
6
|
-
from ldpc.code_util import compute_code_distance
|
7
|
-
# from .lifted_hgp import lifted_hgp, lifted_bicycle
|
8
|
-
|
9
|
-
|
10
|
-
'''
|
11
|
-
[[4,2,2]] detection code
|
12
|
-
'''
|
13
|
-
|
14
|
-
class det422(css_code):
|
15
|
-
def __init__(self):
|
16
|
-
hx=np.array([[1,1,1,1]])
|
17
|
-
hz=np.array([[1,1,1,1]])
|
18
|
-
super().__init__(hx,hz)
|
19
|
-
self.name="det422"
|
20
|
-
|
21
|
-
'''
|
22
|
-
The Steane Code
|
23
|
-
'''
|
24
|
-
class steane_code(css_code):
|
25
|
-
def __init__(self,g=3):
|
26
|
-
if g<3: raise Exception("g must be equal or larger than 3")
|
27
|
-
|
28
|
-
super().__init__()
|
29
|
-
self.hx=hamming_code(g)
|
30
|
-
self.hz=hamming_code(g)
|
31
|
-
self.K=self.compute_dimension()
|
32
|
-
self.D=3
|
33
|
-
self.lx,self.lz=self.compute_logicals()
|
34
|
-
self.name=f"steane_{g}"
|
35
|
-
|
36
|
-
'''
|
37
|
-
2D topological codes
|
38
|
-
'''
|
39
|
-
|
40
|
-
class surface_code(hgp):
|
41
|
-
def __init__(self,n1,n2=None):
|
42
|
-
if n2 is None: n2=n1
|
43
|
-
h1=rep_code(n1)
|
44
|
-
h2=rep_code(n2)
|
45
|
-
super().__init__(h1,h2,compute_distance=True)
|
46
|
-
self.compute_ldpc_params()
|
47
|
-
self.name=f"surface_{self.D}"
|
48
|
-
|
49
|
-
|
50
|
-
class toric_code(hgp):
|
51
|
-
def __init__(self,n1,n2=None):
|
52
|
-
if n2 is None: n2=n1
|
53
|
-
h1=ring_code(n1)
|
54
|
-
h2=ring_code(n2)
|
55
|
-
super().__init__(h1,h2,compute_distance=True)
|
56
|
-
self.compute_ldpc_params()
|
57
|
-
self.name=f"toric_{self.D}"
|
58
|
-
|
59
|
-
|
60
|
-
# '''
|
61
|
-
# 3D Topological codes
|
62
|
-
# '''
|
63
|
-
|
64
|
-
# class toric_code_3d(hgp3d):
|
65
|
-
# def __init__(self,distance):
|
66
|
-
# h=ring_code(distance)
|
67
|
-
# super().__init__(h)
|
68
|
-
# if self.K==np.nan: self.compute_dimension()
|
69
|
-
# self.compute_ldpc_params()
|
70
|
-
# self.name=f"toric3d_{distance}"
|
71
|
-
|
72
|
-
# class surface_code_3d(hgp3d):
|
73
|
-
# def __init__(self,distance):
|
74
|
-
# h=rep_code(distance)
|
75
|
-
# super().__init__(h,h,h.T)
|
76
|
-
# if self.K==np.nan: self.compute_dimension()
|
77
|
-
# self.compute_ldpc_params()
|
78
|
-
# self.name=f"surface3d_{distance}"
|
79
|
-
|
80
|
-
|
81
|
-
# '''
|
82
|
-
# Lifted Product Codes
|
83
|
-
# '''
|
84
|
-
|
85
|
-
# def qldpc(code_name):
|
86
|
-
|
87
|
-
# print(code_name)
|
88
|
-
|
89
|
-
# if code_name is "p19b1":
|
90
|
-
|
91
|
-
# lift_parameter=63
|
92
|
-
|
93
|
-
# proto_a = np.array([
|
94
|
-
# [{27}, {}, {}, {}, {}, {0}, {54}],
|
95
|
-
# [{54}, {27}, {}, {}, {}, {}, {0}],
|
96
|
-
# [{0}, {54}, {27}, {}, {}, {}, {}],
|
97
|
-
# [{}, {0}, {54}, {27}, {}, {}, {}],
|
98
|
-
# [{}, {}, {0}, {54}, {27}, {}, {}],
|
99
|
-
# [{}, {}, {}, {0}, {54}, {27}, {}],
|
100
|
-
# [{}, {}, {}, {}, {0}, {54}, {27}]
|
101
|
-
# ])
|
102
|
-
|
103
|
-
# proto_b = np.array([
|
104
|
-
# [{0, 62, 57}]
|
105
|
-
# ])
|
106
|
-
|
107
|
-
# return lifted_hgp(lift_parameter,proto_a,proto_b)
|
108
|
-
|
109
|
-
# if code_name is "p19b2":
|
110
|
-
|
111
|
-
# lift_parameter=63
|
112
|
-
|
113
|
-
# proto_a = np.array([
|
114
|
-
# [{27}, {}, {}, {0}, {18}, {27}, {0}],
|
115
|
-
# [{0}, {27}, {}, {}, {0}, {18}, {27}],
|
116
|
-
# [{27}, {0}, {27}, {}, {}, {0}, {18}],
|
117
|
-
# [{18}, {27}, {0}, {27}, {}, {}, {0}],
|
118
|
-
# [{0}, {18}, {27}, {0}, {27}, {}, {}],
|
119
|
-
# [{}, {0}, {18}, {27}, {0}, {27}, {}],
|
120
|
-
# [{}, {}, {0}, {18}, {27}, {0}, {27}]
|
121
|
-
# ])
|
122
|
-
|
123
|
-
# proto_b = np.array([
|
124
|
-
# [{0, 62, 57}]
|
125
|
-
# ])
|
126
|
-
|
127
|
-
# return lifted_hgp(lift_parameter,proto_a,proto_b)
|
128
|
-
|
129
|
-
# if code_name is "p19b3":
|
130
|
-
|
131
|
-
# lift_parameter=127
|
132
|
-
|
133
|
-
# proto_a = np.array([
|
134
|
-
# [{0}, {}, {51}, {52}, {}],
|
135
|
-
# [{}, {0}, {}, {111}, {20}],
|
136
|
-
# [{0}, {}, {98}, {}, {122}],
|
137
|
-
# [{0}, {80}, {}, {119}, {}],
|
138
|
-
# [{}, {0}, {5}, {}, {106}]
|
139
|
-
# ])
|
140
|
-
|
141
|
-
# proto_b = np.array([
|
142
|
-
# [{0, 126, 120}]
|
143
|
-
# ])
|
144
|
-
|
145
|
-
# return lifted_hgp(lift_parameter,proto_a,proto_b)
|
146
|
-
|
147
|
-
# if code_name is "tanner":
|
148
|
-
|
149
|
-
# lift_parameter=31
|
150
|
-
|
151
|
-
# proto_a = np.array([
|
152
|
-
# [{1},{2},{4},{8},{16}],
|
153
|
-
# [{5},{10},{20},{9},{18}],
|
154
|
-
# [{25},{19},{7},{14},{28}]
|
155
|
-
# ])
|
156
|
-
|
157
|
-
# return lifted_hgp(31,proto_a)
|
158
|
-
|
159
|
-
# if code_name is "p19a1":
|
160
|
-
|
161
|
-
# '''
|
162
|
-
# Bicycle code A1 from p19
|
163
|
-
# '''
|
164
|
-
|
165
|
-
# a=np.array([[{0,15,20,28,66}]])
|
166
|
-
# b=np.array([[{0,58,59,100,121}]])
|
167
|
-
|
168
|
-
# return lifted_bicycle(127,a,b)
|
169
|
-
|
170
|
-
|
171
|
-
# if code_name is "p19a2":
|
172
|
-
|
173
|
-
# '''
|
174
|
-
# Bicycle code A1 from p19
|
175
|
-
# '''
|
176
|
-
|
177
|
-
# a=np.array([[{0,1,14,16,22}]])
|
178
|
-
# b=np.array([[{0,3,13,20,42}]])
|
179
|
-
|
180
|
-
# return lifted_bicycle(63,a,b)
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
qec/stab.py
DELETED
@@ -1,119 +0,0 @@
|
|
1
|
-
import numpy as np
|
2
|
-
from ldpc import mod2
|
3
|
-
from tqdm import tqdm
|
4
|
-
|
5
|
-
def gf2_to_gf4(bin):
|
6
|
-
n=int(len(bin)/2)
|
7
|
-
gf4=np.zeros(n).astype(int)
|
8
|
-
for i in range(n):
|
9
|
-
if bin[i]==1 and bin[i+n]==0:
|
10
|
-
gf4[i]=1
|
11
|
-
elif bin[i]==0 and bin[i+n]==1:
|
12
|
-
gf4[i]=3
|
13
|
-
elif bin[i]==1 and bin[i+n]==1:
|
14
|
-
gf4[i]=2
|
15
|
-
else:
|
16
|
-
gf4[i]=0
|
17
|
-
return gf4
|
18
|
-
|
19
|
-
|
20
|
-
class stab_code():
|
21
|
-
|
22
|
-
def __init__(self,hx=None,hz=None):
|
23
|
-
|
24
|
-
if hz is None or hz is None:
|
25
|
-
self.hx=np.array([[]])
|
26
|
-
self.hz = np.array([[]])
|
27
|
-
self.N=np.nan
|
28
|
-
self.K=np.nan
|
29
|
-
self.lx=np.array([[]])
|
30
|
-
self.lz=np.array([[]])
|
31
|
-
self.D=np.nan
|
32
|
-
|
33
|
-
else:
|
34
|
-
self.hx=hx
|
35
|
-
self.hz=hz
|
36
|
-
self.init_code()
|
37
|
-
|
38
|
-
self.h=np.hstack([self.hx,self.hz])
|
39
|
-
self.l=np.hstack([self.lx,self.lz])
|
40
|
-
|
41
|
-
def init_code(self):
|
42
|
-
|
43
|
-
self.h=np.hstack([self.hx,self.hz])
|
44
|
-
self.N=self.hx.shape[1]
|
45
|
-
self.K=self.N-mod2.rank(self.h)
|
46
|
-
self.compute_logical_operators()
|
47
|
-
self.D=np.nan
|
48
|
-
|
49
|
-
def compute_logical_operators(self):
|
50
|
-
#compute logical operators
|
51
|
-
#Kernel H
|
52
|
-
|
53
|
-
ker_H=mod2.nullspace(np.hstack([self.hz,self.hx]))
|
54
|
-
image_HT=mod2.row_basis(np.hstack([self.hx,self.hz]))
|
55
|
-
|
56
|
-
log_stack=np.vstack([image_HT,ker_H])
|
57
|
-
pivots=mod2.row_echelon(log_stack.T)[3]
|
58
|
-
log_op_indices=[i for i in range(image_HT.shape[0],log_stack.shape[0]) if i in pivots]
|
59
|
-
self.l=log_stack[log_op_indices]
|
60
|
-
self.lx =self.l[:,0:self.N]
|
61
|
-
self.lz=self.l[:,self.N:2*self.N]
|
62
|
-
|
63
|
-
self.K=int(self.l.shape[0]/2)
|
64
|
-
|
65
|
-
def compute_code_distance(self,return_logicals=False):
|
66
|
-
|
67
|
-
if self.N>10:
|
68
|
-
print("Warning: computing a code distance of codes with N>10 will take a long time.")
|
69
|
-
|
70
|
-
re,r,_,_=mod2.row_echelon(self.h)
|
71
|
-
stab_basis=re[0:r]
|
72
|
-
logical_stack=np.vstack([stab_basis,self.l])
|
73
|
-
all_logicals=mod2.row_span(logical_stack)
|
74
|
-
# np.argmin(np.sum(all_logicals,axis=1))
|
75
|
-
|
76
|
-
d_min=self.N
|
77
|
-
min_indices=[]
|
78
|
-
min_logicals=[]
|
79
|
-
for i in tqdm(range(len(all_logicals))):
|
80
|
-
logical=all_logicals[i]
|
81
|
-
logical=gf2_to_gf4(logical)
|
82
|
-
temp=np.count_nonzero(logical)
|
83
|
-
if temp<d_min:
|
84
|
-
d_min=temp
|
85
|
-
min_indices=[i]
|
86
|
-
min_logicals=[logical]
|
87
|
-
elif temp==d_min:
|
88
|
-
min_indices.append(i)
|
89
|
-
min_logicals.append(logical)
|
90
|
-
|
91
|
-
# d_min=np.min( np.sum(all_logicals,axis=1) )
|
92
|
-
self.D=d_min
|
93
|
-
|
94
|
-
# print(all_logicals)
|
95
|
-
|
96
|
-
if return_logicals:
|
97
|
-
return np.array(min_logicals)
|
98
|
-
|
99
|
-
return d_min
|
100
|
-
|
101
|
-
def test(self):
|
102
|
-
#check the logical operators are in the kernel of the pcm
|
103
|
-
assert ((self.hx@self.lz.T %2 + self.hz@self.lx.T %2)%2).any()==0
|
104
|
-
assert mod2.rank((self.lx@self.lz.T%2 + self.lz@self.lx.T%2) %2)==self.l.shape[0]
|
105
|
-
|
106
|
-
self.compute_logical_operators()
|
107
|
-
|
108
|
-
#check commutativity relation (non CSS code)
|
109
|
-
assert (( (self.hz@self.hx.T %2) + (self.hx@self.hz.T %2) ) %2 ).any() == 0
|
110
|
-
|
111
|
-
# #check the logical operators valid
|
112
|
-
assert ((self.hx@self.lz.T %2 + self.hz@self.lx.T %2)%2).any()==0
|
113
|
-
assert mod2.rank((self.lx@self.lz.T%2 + self.lz@self.lx.T%2) %2)==self.l.shape[0]
|
114
|
-
|
115
|
-
@property
|
116
|
-
def code_params(self):
|
117
|
-
return f"[[{self.N},{self.K},{self.D}]]"
|
118
|
-
|
119
|
-
|
qec/xzzx_codes.py
DELETED
@@ -1,333 +0,0 @@
|
|
1
|
-
from ldpc.mod2 import nullspace
|
2
|
-
import numpy as np
|
3
|
-
from ldpc.codes import rep_code,ring_code
|
4
|
-
from ldpc.code_util import get_code_parameters
|
5
|
-
from qec.css import css_code
|
6
|
-
from qec.stab import stab_code
|
7
|
-
from qec.hgp import hgp
|
8
|
-
from qec.protograph import protograph_transpose,protograph_to_qc_code
|
9
|
-
from qec.lifted_hgp import lifted_hgp
|
10
|
-
|
11
|
-
def gf2_to_gf4(bin):
|
12
|
-
n=int(len(bin)/2)
|
13
|
-
gf4=np.zeros(n).astype(int)
|
14
|
-
for i in range(n):
|
15
|
-
if bin[i]==1 and bin[i+n]==0:
|
16
|
-
gf4[i]=1
|
17
|
-
elif bin[i]==0 and bin[i+n]==1:
|
18
|
-
gf4[i]=3
|
19
|
-
elif bin[i]==1 and bin[i+n]==1:
|
20
|
-
gf4[i]=2
|
21
|
-
|
22
|
-
return gf4
|
23
|
-
|
24
|
-
def hadamard_rotate(css_code,sector1_length):
|
25
|
-
|
26
|
-
hx_css=css_code.hx
|
27
|
-
hz_css=css_code.hz
|
28
|
-
|
29
|
-
mx,n=hx_css.shape
|
30
|
-
mz,nz=hz_css.shape
|
31
|
-
|
32
|
-
assert n==nz
|
33
|
-
|
34
|
-
hx=np.zeros((mx+mz,n)).astype(int)
|
35
|
-
hz=np.zeros((mx+mz,n)).astype(int)
|
36
|
-
|
37
|
-
hx[mz:,:sector1_length]=hx_css[:,:sector1_length]
|
38
|
-
hx[:mz,sector1_length:]=hz_css[:,sector1_length:]
|
39
|
-
|
40
|
-
hz[:mz,:sector1_length]=hz_css[:,:sector1_length]
|
41
|
-
hz[mz:,sector1_length:]=hx_css[:,sector1_length:]
|
42
|
-
|
43
|
-
return stab_code(hx,hz)
|
44
|
-
|
45
|
-
class xzzx_surface_code(stab_code):
|
46
|
-
|
47
|
-
def __init__(self,nx,nz=None):
|
48
|
-
|
49
|
-
if nz is None:
|
50
|
-
nz=nx
|
51
|
-
|
52
|
-
h1=rep_code(nx)
|
53
|
-
h2=rep_code(nz)
|
54
|
-
|
55
|
-
css_sc=hgp(h1,h2)
|
56
|
-
xzzx_sc=hadamard_rotate(css_sc,css_sc.hx1.shape[1])
|
57
|
-
|
58
|
-
self.__dict__=xzzx_sc.__dict__.copy()
|
59
|
-
|
60
|
-
self.m1,self.n1=h1.shape
|
61
|
-
self.m2,self.n2=h2.shape
|
62
|
-
|
63
|
-
self.twist_boundaries()
|
64
|
-
|
65
|
-
def twist_boundaries(self):
|
66
|
-
|
67
|
-
for i in range(self.m1):
|
68
|
-
|
69
|
-
self.hz[self.m2*self.n1+i*self.n2, i*self.n2+self.n2-1]=1
|
70
|
-
self.hz[self.m2*self.n1+i*self.n2+(self.n2-1), (i+1)*self.n2]=1
|
71
|
-
|
72
|
-
for i in range(self.m2):
|
73
|
-
self.hx[i, self.n2*(self.n1-1) +i +1]=1
|
74
|
-
self.hx[self.m2*(self.n1-1) +i, i]=1
|
75
|
-
|
76
|
-
self.compute_logical_operators()
|
77
|
-
self.h=np.hstack([self.hx,self.hz])
|
78
|
-
self.l=np.hstack([self.lx,self.lz])
|
79
|
-
|
80
|
-
class xzzx_toric_code_old(stab_code):
|
81
|
-
|
82
|
-
def __init__(self,nx,nz=None):
|
83
|
-
|
84
|
-
if nz is None:
|
85
|
-
nz=nx
|
86
|
-
|
87
|
-
h1=ring_code(nx)
|
88
|
-
h2=ring_code(nz)
|
89
|
-
|
90
|
-
css_tc=hgp(h1,h2)
|
91
|
-
xzzx_tc=hadamard_rotate(css_tc,css_tc.hx1.shape[1])
|
92
|
-
|
93
|
-
self.__dict__=xzzx_tc.__dict__.copy()
|
94
|
-
|
95
|
-
self.m1,self.n1=h1.shape
|
96
|
-
self.m2,self.n2=h2.shape
|
97
|
-
|
98
|
-
self.twist_boundaries()
|
99
|
-
|
100
|
-
def twist_boundaries(self):
|
101
|
-
|
102
|
-
hz1_n=self.n1*self.n2
|
103
|
-
|
104
|
-
self.hz[:hz1_n,:hz1_n]=ring_code(hz1_n)
|
105
|
-
self.hz[hz1_n:,hz1_n:]=ring_code(hz1_n).T
|
106
|
-
|
107
|
-
self.compute_logical_operators()
|
108
|
-
self.h=np.hstack([self.hx,self.hz])
|
109
|
-
self.l=np.hstack([self.lx,self.lz])
|
110
|
-
|
111
|
-
def to_css(self):
|
112
|
-
|
113
|
-
hz1_n=self.n1*self.n2
|
114
|
-
hz1=self.hz[:hz1_n,:hz1_n]
|
115
|
-
hx2=self.hz[hz1_n:,hz1_n:]
|
116
|
-
|
117
|
-
hx1=self.hx[hz1_n:,:hz1_n]
|
118
|
-
hz2=self.hx[:hz1_n,hz1_n:]
|
119
|
-
|
120
|
-
hx=np.hstack([hx1,hx2])
|
121
|
-
hz=np.hstack([hz1,hz2])
|
122
|
-
|
123
|
-
qcode_css=css_code(hx,hz)
|
124
|
-
qcode_css.hx1=hx1
|
125
|
-
qcode_css.hx2=hx2
|
126
|
-
qcode_css.hz1=hz1
|
127
|
-
qcode_css.hz2=hz2
|
128
|
-
|
129
|
-
return qcode_css
|
130
|
-
|
131
|
-
|
132
|
-
class rotated_xzzx_code(stab_code):
|
133
|
-
|
134
|
-
def __init__(self,nx,nz):
|
135
|
-
|
136
|
-
n=nx*nz
|
137
|
-
m=(nx-1)*(nz-1) + nz//2 +(nz-1)//2 +nx//2 +(nx-1)//2
|
138
|
-
|
139
|
-
|
140
|
-
hx=np.zeros((m,n)).astype(int)
|
141
|
-
hz=np.zeros((m,n)).astype(int)
|
142
|
-
|
143
|
-
# print(hx)
|
144
|
-
|
145
|
-
for j in range(nx-1):
|
146
|
-
|
147
|
-
#main grid
|
148
|
-
for k in range(nz-1):
|
149
|
-
temp=j*(nz-1)
|
150
|
-
hx[temp+k,j*(nz)+k]=1
|
151
|
-
hx[temp+k,j*(nz)+k+nz+1]=1
|
152
|
-
|
153
|
-
hz[temp+k,j*(nz)+k+1]=1
|
154
|
-
hz[temp+k,j*(nz)+k+nz]=1
|
155
|
-
|
156
|
-
temp=(nx-1)*(nz-1)
|
157
|
-
count=0
|
158
|
-
for j in range(0,nz-1,2):
|
159
|
-
|
160
|
-
#the extra checks top
|
161
|
-
hz[temp+count,j]=1
|
162
|
-
hz[temp+count,(n-1)-(nz-1)+1+j]=1
|
163
|
-
|
164
|
-
hx[temp+count,j+1]=1
|
165
|
-
hx[temp+count,(n-1)-(nz-1)+j]=1
|
166
|
-
|
167
|
-
count+=1
|
168
|
-
|
169
|
-
temp=(nx-1)*(nz-1) + nz//2
|
170
|
-
count=0
|
171
|
-
for j in range(1,nz-1,2):
|
172
|
-
#extra checks bottom
|
173
|
-
|
174
|
-
hx[temp+count,j+1]=1
|
175
|
-
hx[temp+count,(n-1)-(nz-1)+j]=1
|
176
|
-
|
177
|
-
hz[temp+count,j]=1
|
178
|
-
hz[temp+count,(n-1)-(nz-1)+1+j]=1
|
179
|
-
|
180
|
-
count+=1
|
181
|
-
|
182
|
-
temp=(nx-1)*(nz-1) + nz//2 +(nz-1)//2
|
183
|
-
count=0
|
184
|
-
for j in range(0,nx-1,2):
|
185
|
-
|
186
|
-
#extra checks #right
|
187
|
-
|
188
|
-
hz[temp+count,(j+1)*nz+nz-1]=1
|
189
|
-
hz[temp+count,j*nz]=1
|
190
|
-
|
191
|
-
|
192
|
-
hx[temp+count,(j+1)*nz] =1
|
193
|
-
hx[temp+count,j*nz+nz-1] =1
|
194
|
-
|
195
|
-
count+=1
|
196
|
-
|
197
|
-
|
198
|
-
temp=(nx-1)*(nz-1) + nz//2 +(nz-1)//2 +(nx)//2
|
199
|
-
count=0
|
200
|
-
for j in range(1,nx-1,2):
|
201
|
-
|
202
|
-
#extra checks #left
|
203
|
-
|
204
|
-
hz[temp+count,(j+1)*nz+nz-1]=1
|
205
|
-
hz[temp+count,j*nz]=1
|
206
|
-
|
207
|
-
hx[temp+count,(j+1)*nz] =1
|
208
|
-
hx[temp+count,j*nz+nz-1] =1
|
209
|
-
|
210
|
-
count+=1
|
211
|
-
|
212
|
-
|
213
|
-
super().__init__(hx,hz)
|
214
|
-
self.nx=nx
|
215
|
-
self.nz=nz
|
216
|
-
|
217
|
-
def to_css(self):
|
218
|
-
|
219
|
-
if not self.nx%2==0 and not self.nz%2:
|
220
|
-
raise Exception(f"Attribute error: the XZZX code must have even lattice parameters to be converted to a CSS code. Not nx={self.nx} and nz={self.nz}.")
|
221
|
-
|
222
|
-
sector1_qubits=np.nonzero(nullspace(self.hx)[0])[0]
|
223
|
-
sector2_qubits=np.nonzero(nullspace(self.hx)[1])[0]
|
224
|
-
|
225
|
-
qubit_ordering=np.concatenate([sector1_qubits,sector2_qubits])
|
226
|
-
|
227
|
-
print(qubit_ordering)
|
228
|
-
|
229
|
-
self.hx=self.hx[:,qubit_ordering]
|
230
|
-
self.hz=self.hz[:,qubit_ordering]
|
231
|
-
|
232
|
-
|
233
|
-
temp1=np.copy(self.hx[:,self.N//2:])
|
234
|
-
temp2=np.copy(self.hz[:,self.N//2:])
|
235
|
-
|
236
|
-
self.hx[:,self.N//2:]=temp2
|
237
|
-
self.hz[:,self.N//2:]=temp1
|
238
|
-
|
239
|
-
delete_zero_rows = lambda mat: np.delete(mat,np.where(~mat.any(axis=1))[0], axis=0)
|
240
|
-
self.hx=delete_zero_rows(self.hx)
|
241
|
-
self.hz=delete_zero_rows(self.hz)
|
242
|
-
|
243
|
-
print(self.hx)
|
244
|
-
print(self.hz)
|
245
|
-
|
246
|
-
# print(self.hx)
|
247
|
-
# print(self.hz)
|
248
|
-
|
249
|
-
return css_code(self.hx,self.hz)
|
250
|
-
|
251
|
-
class xzzx_toric_code(stab_code):
|
252
|
-
def __init__(self,nx,nz):
|
253
|
-
|
254
|
-
self.nx=nx
|
255
|
-
self.nz=nz
|
256
|
-
self.N=int(2*self.nx*self.nz)
|
257
|
-
|
258
|
-
self.proto_1=np.array([[{0,1}]])
|
259
|
-
self.proto_2=np.array([[{0,nz}]])
|
260
|
-
|
261
|
-
self.css=lifted_hgp(self.N//2,self.proto_2,self.proto_1)
|
262
|
-
|
263
|
-
lp=hadamard_rotate(self.css,self.N//2)
|
264
|
-
|
265
|
-
# for key in lp.__dict__.keys():
|
266
|
-
# if key not in self.__dict__.keys():
|
267
|
-
# self.__dict__[key]=lp.__dict__[key]
|
268
|
-
|
269
|
-
super().__init__(lp.hx,lp.hz)
|
270
|
-
|
271
|
-
def to_css(self):
|
272
|
-
return self.css
|
273
|
-
|
274
|
-
|
275
|
-
class xzzx_sc(stab_code):
|
276
|
-
def __init__(self,nx,nz):
|
277
|
-
|
278
|
-
def Pfr(n,shift):
|
279
|
-
base=np.hstack([np.identity(n-1),np.zeros((n-1,1))]).astype(int)
|
280
|
-
perm=np.arange(n)
|
281
|
-
perm=(perm-shift)%(n)
|
282
|
-
return base[:,perm]
|
283
|
-
|
284
|
-
N=nx*nz+(nx-1)*(nz-1)
|
285
|
-
hz=Pfr(N,0)+Pfr(N,1)
|
286
|
-
hx=Pfr(N,nz)+Pfr(N,(1-nz))
|
287
|
-
super().__init__(hx,hz)
|
288
|
-
|
289
|
-
|
290
|
-
def main():
|
291
|
-
|
292
|
-
print("Rotated XZZX codes")
|
293
|
-
tsc=rotated_xzzx_code(4,3)
|
294
|
-
tsc.test()
|
295
|
-
# tsc=tsc.to_css()
|
296
|
-
tsc.test()
|
297
|
-
tsc.compute_code_distance()
|
298
|
-
print(f"[[{tsc.N},{tsc.K},{tsc.D}]]")
|
299
|
-
print(get_code_parameters(tsc.hx))
|
300
|
-
print(get_code_parameters(tsc.hz))
|
301
|
-
print()
|
302
|
-
|
303
|
-
|
304
|
-
# print("Toric code lifted")
|
305
|
-
# #xzzx toric from lifted product
|
306
|
-
# tsc=xzzx_toric_code(2,2)
|
307
|
-
# logicals=tsc.compute_code_distance(return_logicals=True)
|
308
|
-
# tsc.test()
|
309
|
-
# print(tsc.code_params)
|
310
|
-
# print(logicals)
|
311
|
-
# print()
|
312
|
-
|
313
|
-
|
314
|
-
print("XZZX Surface code constructed")
|
315
|
-
#xzzx toric from lifted product
|
316
|
-
sc=xzzx_sc(3,2)
|
317
|
-
logicals=sc.compute_code_distance(return_logicals=True)
|
318
|
-
sc.test()
|
319
|
-
print(sc.code_params)
|
320
|
-
print(get_code_parameters(sc.hx))
|
321
|
-
print(get_code_parameters(sc.hz))
|
322
|
-
print(logicals)
|
323
|
-
# print(sc.hz)
|
324
|
-
# print(sc.hx)
|
325
|
-
|
326
|
-
# assert np.array_equal(sc.hz,sc2.hz)
|
327
|
-
|
328
|
-
# print(logicals)
|
329
|
-
print()
|
330
|
-
|
331
|
-
|
332
|
-
if __name__ == "__main__":
|
333
|
-
main()
|
qec-0.0.11.dist-info/METADATA
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
Metadata-Version: 2.1
|
2
|
-
Name: qec
|
3
|
-
Version: 0.0.11
|
4
|
-
Summary: UNKNOWN
|
5
|
-
Home-page: https://www.roffe.eu
|
6
|
-
Author: Joschka Roffe
|
7
|
-
Author-email: joschka@roffe.eu
|
8
|
-
License: UNKNOWN
|
9
|
-
Platform: UNKNOWN
|
10
|
-
Classifier: Development Status :: 1 - Planning
|
11
|
-
Requires-Python: >=3.6
|
12
|
-
Requires-Dist: numpy
|
13
|
-
Requires-Dist: ldpc
|
14
|
-
Requires-Dist: tqdm
|
15
|
-
|
16
|
-
Python Tools for Quantum Error Correction
|
17
|
-
|
18
|
-
|
qec-0.0.11.dist-info/RECORD
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
qec/css.py,sha256=DnVxU6HNySoly8_rlgqPATSw2_yWiMvoTHRpswc5Sb8,5211
|
2
|
-
qec/hgp.py,sha256=wf_F_RdnAdFny8aA0E9_4201j6jvallfQnU5jAfBPJY,2085
|
3
|
-
qec/lifted_hgp.py,sha256=_uIXULX5Q3NLza5SUo7IWPkRwuZ8ah824Reitjn-6GQ,2538
|
4
|
-
qec/protograph.py,sha256=8un7qYs0LIjm0WOs1Qr0wGaNzToIuPy3WFtY02FcPR0,3953
|
5
|
-
qec/quantum_codes.py,sha256=JUWGJmcZocNC7pT0_jTGOaIIx4VdV9ig1yhLA9aZMy0,4550
|
6
|
-
qec/stab.py,sha256=04EQDOrmKorgGTCn9jFZfc9JkUcNjJcdmiOOJVMcCaM,3508
|
7
|
-
qec/xzzx_codes.py,sha256=ilUH5xbxYZ9vb4hCAW6_erNd34cT7gfsaoQX7ZFvtVo,8050
|
8
|
-
qec-0.0.11.dist-info/METADATA,sha256=xO4tBRgbPYjDvTmai9HcWvqLI1gJ_m8a5j6BqOaaIE4,361
|
9
|
-
qec-0.0.11.dist-info/WHEEL,sha256=ewwEueio1C2XeHTvT17n8dZUJgOvyCWCt0WVNLClP9o,92
|
10
|
-
qec-0.0.11.dist-info/top_level.txt,sha256=d8l_7pJ5u9uWdviNp0FUK-j8VPZqywkDek7qa4NDank,4
|
11
|
-
qec-0.0.11.dist-info/RECORD,,
|
File without changes
|