11from itertools import combinations , product
22import numpy as np
3+ from typing import Iterable
4+ import random
5+
36from qiskit import QuantumCircuit , ClassicalRegister , QuantumRegister , AncillaRegister
47from qiskit .quantum_info import random_clifford , Clifford , Pauli
58from qiskit .circuit .library import PauliEvolutionGate
69
710from quantumreservoirpy .util import randomIsing , get_Ising_circuit
811from quantumreservoirpy .reservoirs import Static
912
10- from typing import Iterable
11-
12-
1313class Stabilizer (Static ):
1414 def __init__ (
1515 self ,
@@ -22,16 +22,20 @@ def __init__(
2222 memory = np .inf ,
2323 backend = None ,
2424 degree = 1 ,
25+ stab_method = 'random' ,
26+ stab_deg = 1 ,
2527 num_reservoirs = 1 ,
2628 standard = False ,
2729 isingparams = None ,
2830 decode = True , # danger zone: this is only for testing
2931 ) -> None :
3032 super ().__init__ (
31- n_qubits + 1 , memory , backend , degree = degree , num_reservoirs = num_reservoirs
33+ n_qubits , memory , backend , degree = degree , num_reservoirs = num_reservoirs
3234 )
3335 self .n_meas = n_meas
3436 self .decode = decode
37+ self .stab_method = stab_method
38+ self .stab_deg = stab_deg
3539
3640 if not isingparams :
3741 steps = 1
@@ -61,83 +65,111 @@ def __init__(
6165 self .tableau = tableau
6266 else :
6367 self .tableau = Stabilizer .generate_tableau (
64- n_qubits , n_meas , codestate_preparation_circ
68+ n_qubits , n_meas ,self . stab_deg , self . stab_method , codestate_preparation_circ
6569 )
6670
6771 def before (self , circuit ):
6872 if self .decode :
69- circuit .add_register (AncillaRegister (self . n_meas ))
73+ circuit .add_register (AncillaRegister (1 ))
7074
7175 def during (self , circuit , timestep , reservoirnumber ):
7276 circuit .barrier ()
7377
7478 # encode
7579 for k in range (self .n_meas ):
76- beta = 3 ** k
80+ beta = 3 ** ( k / self . n_meas ) / 2 * np . pi
7781 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-
82+ evo = PauliEvolutionGate (pauliop , - beta * timestep )
83+ circuit .append (evo , range (self .n_qubits ))
84+ circuit . barrier ()
8185 # reservoir
82- circuit .append (self .U [reservoirnumber ], range (self .n_qubits - 1 ))
86+ circuit .append (self .U [reservoirnumber ], range (self .n_qubits ))
8387
8488 # decode
8589 cr = ClassicalRegister (self .n_meas )
8690 circuit .add_register (cr )
8791
8892 if self .decode :
8993 Stabilizer .decoder (circuit , self .tableau )
90-
9194 @staticmethod
9295 def generate_tableau (
9396 n_qubits : int ,
9497 n_meas : int ,
95- codestate_preparation_circ : Iterable [QuantumCircuit ] | None = None ,
98+ stab_deg : int ,
99+ stab_method : str ,
100+ codestate_preparation_circ : Iterable [QuantumCircuit ] | None = None
96101 ):
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-
102+ if stab_method == 'random' :
103+ print ('ok' )
104+ """generates a tableau for a stabilizer code based on 2**k codestate preparation circuits"""
105+
106+ logical_qubits = n_qubits - n_meas # also called k
107+
108+ if codestate_preparation_circ == None : # generate random stabilizer code
109+ tableau = random_clifford (n_qubits ).to_dict ()
110+
111+ # turn the last k stabilizers into logical Zs
112+ # tableau["logical_z"] = tableau["stabilizer"][n_meas:] #these are just for QEC fun, not useful here
113+ tableau ["stabilizer" ] = tableau ["stabilizer" ][:n_meas ]
114+
115+ # turn the last k destabilizers into logical Xs
116+ # tableau["logical_x"] = tableau["destabilizer"][n_meas:]
117+ tableau ["destabilizer" ] = tableau ["destabilizer" ][:n_meas ]
118+
119+ elif len (codestate_preparation_circ ) != 2 ** logical_qubits :
120+ print (
121+ "Error : number of code state preparation circuits does not match the dimension of the codespace"
122+ )
123+ return
124+
125+ else :
126+ tableau = Clifford (codestate_preparation_circ [0 ]).to_dict ()
127+ for circ in codestate_preparation_circ [1 :]:
128+ circ_tableau = Clifford (circ ).to_dict ()
129+ to_pop = []
130+
131+ for i in range (len (tableau ["stabilizer" ])):
132+ if tableau ["stabilizer" ][i ] not in circ_tableau ["stabilizer" ]:
133+ to_pop .append (i )
134+
135+ for i in to_pop :
136+ tableau ["stabilizer" ].pop (i )
137+ tableau ["destabilizer" ].pop (i )
138+
139+ # check the stabilizer has the right dimension
140+ if (
141+ len (tableau ["stabilizer" ]) != n_meas
142+ or len (tableau ["destabilizer" ]) != n_meas
143+ ):
144+ print ("Error : something went wrong with tableau generation" )
145+ print (tableau )
146+
118147 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 )
148+ deg = stab_deg
149+ stabilizers = []
150+ destabilizers = []
151+ for i in range (n_qubits - deg + 1 ):
152+ pauli_z = ["I" ] * n_qubits
153+ pauli_x = ["I" ] * n_qubits
154+
155+ # fill in Z’s and X’s
156+ for j in range (deg ):
157+ pauli_z [i + j ] = "Z"
158+ pauli_x [i + j ] = "X"
159+
160+ stabilizers .append ("+" + "" .join (pauli_z ))
161+ destabilizers .append ("+" + "" .join (pauli_x ))
162+ indices = random .sample (range (len (stabilizers )), n_meas )
163+
164+ # Extract stabilizers and destabilizers at those indices
165+ stabs = [stabilizers [i ] for i in indices ]
166+ destabs = [destabilizers [i ] for i in indices ]
167+ tableau = {
168+ "stabilizer" : stabs ,
169+ "destabilizer" : destabs ,
170+ }
171+
131172 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-
141173 return tableau
142174
143175 @staticmethod
@@ -217,29 +249,25 @@ def decoder(circuit: QuantumCircuit, code_tableau: dict):
217249 circuit .barrier ()
218250
219251 # syndrome measurement operations
220- circuit .reset (ar )
221- circuit .h (ar )
222-
223252 for j in range (n_meas ):
253+ circuit .reset (ar )
254+ circuit .h (ar )
224255 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 ])
256+ P_aux = P [1 :][::- 1 ]
257+ if P [0 ] == str ('-' ):
258+ circuit .z (ar )
259+ for i in range (0 , len (P_aux )):
260+ if P_aux [i ] == "X" :
261+ circuit .cx (ar , qr [i ])
262+ elif P_aux [i ] == "Y" :
263+ circuit .cy (ar , qr [i ])
264+ elif P_aux [i ] == "Z" :
265+ circuit .cz (ar , qr [i ])
266+
267+ circuit .h (ar )
268+ circuit .measure (ar , cr [j ])
239269 circuit .barrier ()
240-
241270 for j in range (n_meas ):
242271 with circuit .if_test ((cr [j ], 1 )):
243- circuit .pauli (code_tableau ["destabilizer" ][j ][1 :], qr [:- 1 ])
244-
272+ circuit .pauli (code_tableau ["destabilizer" ][j ][1 :], qr )
245273 return circuit
0 commit comments