33from qiskit import QuantumCircuit , ClassicalRegister , QuantumRegister , AncillaRegister
44from qiskit .quantum_info import random_clifford , Clifford , Pauli
55from qiskit .circuit .library import PauliEvolutionGate
6-
76from quantumreservoirpy .util import randomIsing , get_Ising_circuit
87from quantumreservoirpy .reservoirs import Static
9-
108from typing import Iterable
11-
12-
9+ import itertools
10+ import random
1311class Stabilizer (Static ):
1412 def __init__ (
1513 self ,
@@ -22,16 +20,20 @@ def __init__(
2220 memory = np .inf ,
2321 backend = None ,
2422 degree = 1 ,
23+ stab_method = 'random' ,
24+ stab_deg = 1 ,
2525 num_reservoirs = 1 ,
2626 standard = False ,
2727 isingparams = None ,
2828 decode = True , # danger zone: this is only for testing
2929 ) -> None :
3030 super ().__init__ (
31- n_qubits + 1 , memory , backend , degree = degree , num_reservoirs = num_reservoirs
31+ n_qubits , memory , backend , degree = degree , num_reservoirs = num_reservoirs
3232 )
3333 self .n_meas = n_meas
3434 self .decode = decode
35+ self .stab_method = stab_method
36+ self .stab_deg = stab_deg
3537
3638 if not isingparams :
3739 steps = 1
@@ -61,83 +63,112 @@ def __init__(
6163 self .tableau = tableau
6264 else :
6365 self .tableau = Stabilizer .generate_tableau (
64- n_qubits , n_meas , codestate_preparation_circ
66+ n_qubits , n_meas ,self . stab_deg , self . stab_method , codestate_preparation_circ
6567 )
6668
6769 def before (self , circuit ):
6870 if self .decode :
69- circuit .add_register (AncillaRegister (self . n_meas ))
71+ circuit .add_register (AncillaRegister (1 ))
7072
7173 def during (self , circuit , timestep , reservoirnumber ):
7274 circuit .barrier ()
7375
7476 # encode
7577 for k in range (self .n_meas ):
76- beta = 3 ** k
78+ beta = 3 ** ( k / self . n_meas ) / 2 * np . pi
7779 pauliop = Pauli (self .tableau ["destabilizer" ][k ])
78- evo = PauliEvolutionGate (pauliop , - beta / 2 * np . pi * timestep )
79- circuit .append (evo , range (self .n_qubits - 1 ))
80-
80+ evo = PauliEvolutionGate (pauliop , - beta * timestep )
81+ circuit .append (evo , range (self .n_qubits ))
82+ circuit . barrier ()
8183 # reservoir
82- circuit .append (self .U [reservoirnumber ], range (self .n_qubits - 1 ))
84+ circuit .append (self .U [reservoirnumber ], range (self .n_qubits ))
8385
8486 # decode
8587 cr = ClassicalRegister (self .n_meas )
8688 circuit .add_register (cr )
8789
8890 if self .decode :
8991 Stabilizer .decoder (circuit , self .tableau )
90-
92+
9193 @staticmethod
9294 def generate_tableau (
9395 n_qubits : int ,
9496 n_meas : int ,
95- codestate_preparation_circ : Iterable [QuantumCircuit ] | None = None ,
97+ stab_deg : int ,
98+ stab_method : str ,
99+ codestate_preparation_circ : Iterable [QuantumCircuit ] | None = None
96100 ):
97- """generates a tableau for a stabilizer code based on 2**k codestate preparation circuits"""
98-
99- logical_qubits = n_qubits - n_meas # also called k
100-
101- if codestate_preparation_circ == None : # generate random stabilizer code
102- tableau = random_clifford (n_qubits ).to_dict ()
103-
104- # turn the last k stabilizers into logical Zs
105- # tableau["logical_z"] = tableau["stabilizer"][n_meas:] #these are just for QEC fun, not useful here
106- tableau ["stabilizer" ] = tableau ["stabilizer" ][:n_meas ]
107-
108- # turn the last k destabilizers into logical Xs
109- # tableau["logical_x"] = tableau["destabilizer"][n_meas:]
110- tableau ["destabilizer" ] = tableau ["destabilizer" ][:n_meas ]
111-
112- elif len (codestate_preparation_circ ) != 2 ** logical_qubits :
113- print (
114- "Error : number of code state preparation circuits does not match the dimension of the codespace"
115- )
116- return
117-
101+ if stab_method == 'random' :
102+ print ('ok' )
103+ """generates a tableau for a stabilizer code based on 2**k codestate preparation circuits"""
104+
105+ logical_qubits = n_qubits - n_meas # also called k
106+
107+ if codestate_preparation_circ == None : # generate random stabilizer code
108+ tableau = random_clifford (n_qubits ).to_dict ()
109+
110+ # turn the last k stabilizers into logical Zs
111+ # tableau["logical_z"] = tableau["stabilizer"][n_meas:] #these are just for QEC fun, not useful here
112+ tableau ["stabilizer" ] = tableau ["stabilizer" ][:n_meas ]
113+
114+ # turn the last k destabilizers into logical Xs
115+ # tableau["logical_x"] = tableau["destabilizer"][n_meas:]
116+ tableau ["destabilizer" ] = tableau ["destabilizer" ][:n_meas ]
117+
118+ elif len (codestate_preparation_circ ) != 2 ** logical_qubits :
119+ print (
120+ "Error : number of code state preparation circuits does not match the dimension of the codespace"
121+ )
122+ return
123+
124+ else :
125+ tableau = Clifford (codestate_preparation_circ [0 ]).to_dict ()
126+ for circ in codestate_preparation_circ [1 :]:
127+ circ_tableau = Clifford (circ ).to_dict ()
128+ to_pop = []
129+
130+ for i in range (len (tableau ["stabilizer" ])):
131+ if tableau ["stabilizer" ][i ] not in circ_tableau ["stabilizer" ]:
132+ to_pop .append (i )
133+
134+ for i in to_pop :
135+ tableau ["stabilizer" ].pop (i )
136+ tableau ["destabilizer" ].pop (i )
137+
138+ # check the stabilizer has the right dimension
139+ if (
140+ len (tableau ["stabilizer" ]) != n_meas
141+ or len (tableau ["destabilizer" ]) != n_meas
142+ ):
143+ print ("Error : something went wrong with tableau generation" )
144+ print (tableau )
145+
118146 else :
119- tableau = Clifford (codestate_preparation_circ [0 ]).to_dict ()
120- for circ in codestate_preparation_circ [1 :]:
121- circ_tableau = Clifford (circ ).to_dict ()
122- to_pop = []
123-
124- for i in range (len (tableau ["stabilizer" ])):
125- if tableau ["stabilizer" ][i ] not in circ_tableau ["stabilizer" ]:
126- to_pop .append (i )
127-
128- for i in to_pop :
129- tableau ["stabilizer" ].pop (i )
130- tableau ["destabilizer" ].pop (i )
147+ deg = stab_deg
148+ stabilizers = []
149+ destabilizers = []
150+ for i in range (n_qubits - deg + 1 ):
151+ pauli_z = ["I" ] * n_qubits
152+ pauli_x = ["I" ] * n_qubits
153+
154+ # fill in Z’s and X’s
155+ for j in range (deg ):
156+ pauli_z [i + j ] = "Z"
157+ pauli_x [i + j ] = "X"
158+
159+ stabilizers .append ("+" + "" .join (pauli_z ))
160+ destabilizers .append ("+" + "" .join (pauli_x ))
161+ indices = random .sample (range (len (stabilizers )), n_meas )
162+
163+ # Extract stabilizers and destabilizers at those indices
164+ stabs = [stabilizers [i ] for i in indices ]
165+ destabs = [destabilizers [i ] for i in indices ]
166+ tableau = {
167+ "stabilizer" : stabs ,
168+ "destabilizer" : destabs ,
169+ }
170+
131171 print (tableau )
132-
133- # check the stabilizer has the right dimension
134- if (
135- len (tableau ["stabilizer" ]) != n_meas
136- or len (tableau ["destabilizer" ]) != n_meas
137- ):
138- print ("Error : something went wrong with tableau generation" )
139- print (tableau )
140-
141172 return tableau
142173
143174 @staticmethod
@@ -217,29 +248,28 @@ def decoder(circuit: QuantumCircuit, code_tableau: dict):
217248 circuit .barrier ()
218249
219250 # syndrome measurement operations
220- circuit .reset (ar )
221- circuit .h (ar )
251+
222252
223253 for j in range (n_meas ):
254+ circuit .reset (ar )
255+ circuit .h (ar )
224256 P = code_tableau ["stabilizer" ][j ]
225- if P [0 ] == - 1 :
226- circuit .z (ar [j ])
227- for i in range (1 , len (P )):
228- if P [i ] == "X" :
229- circuit .cx (ar [j ], qr [i - 1 ])
230- elif P [i ] == "Y" :
231- circuit .cy (ar [j ], qr [i - 1 ])
232- elif P [i ] == "Z" :
233- circuit .cz (ar [j ], qr [i - 1 ])
234-
235- circuit .h (ar )
236-
237- for j in range (n_meas ):
238- circuit .measure (ar [j ], cr [j ])
257+ P_aux = P [1 :][::- 1 ]
258+ if P [0 ] == str ('-' ):
259+ circuit .z (ar )
260+ for i in range (0 , len (P_aux )):
261+ if P_aux [i ] == "X" :
262+ circuit .cx (ar , qr [i ])
263+ elif P_aux [i ] == "Y" :
264+ circuit .cy (ar , qr [i ])
265+ elif P_aux [i ] == "Z" :
266+ circuit .cz (ar , qr [i ])
267+
268+ circuit .h (ar )
269+ circuit .measure (ar , cr [j ])
239270 circuit .barrier ()
240-
271+
241272 for j in range (n_meas ):
242273 with circuit .if_test ((cr [j ], 1 )):
243- circuit .pauli (code_tableau ["destabilizer" ][j ][1 :], qr [:- 1 ])
244-
274+ circuit .pauli (code_tableau ["destabilizer" ][j ][1 :], qr )
245275 return circuit
0 commit comments