Skip to content

Commit e1ef65f

Browse files
Add stabilizer
1 parent bad38eb commit e1ef65f

File tree

1 file changed

+105
-75
lines changed

1 file changed

+105
-75
lines changed

quantumreservoirpy/stabilizer.py

Lines changed: 105 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,11 @@
33
from qiskit import QuantumCircuit, ClassicalRegister, QuantumRegister, AncillaRegister
44
from qiskit.quantum_info import random_clifford, Clifford, Pauli
55
from qiskit.circuit.library import PauliEvolutionGate
6-
76
from quantumreservoirpy.util import randomIsing, get_Ising_circuit
87
from quantumreservoirpy.reservoirs import Static
9-
108
from typing import Iterable
11-
12-
9+
import itertools
10+
import random
1311
class 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

Comments
 (0)