Skip to content

Commit 0b57bd0

Browse files
Add stabilizer (#34)
correct stabilizer
1 parent bad38eb commit 0b57bd0

File tree

1 file changed

+103
-75
lines changed

1 file changed

+103
-75
lines changed

quantumreservoirpy/stabilizer.py

Lines changed: 103 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
from itertools import combinations, product
22
import numpy as np
3+
from typing import Iterable
4+
import random
5+
36
from qiskit import QuantumCircuit, ClassicalRegister, QuantumRegister, AncillaRegister
47
from qiskit.quantum_info import random_clifford, Clifford, Pauli
58
from qiskit.circuit.library import PauliEvolutionGate
69

710
from quantumreservoirpy.util import randomIsing, get_Ising_circuit
811
from quantumreservoirpy.reservoirs import Static
912

10-
from typing import Iterable
11-
12-
1313
class 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

Comments
 (0)