Skip to content

Commit 3ecdea5

Browse files
authored
Fixed weight stabilizer tableau generation (#35)
* added stim in the environment setup * fixed weight tableau with randomly picked Z-strings
1 parent 0b57bd0 commit 3ecdea5

File tree

2 files changed

+89
-0
lines changed

2 files changed

+89
-0
lines changed
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import numpy as np
2+
import stim
3+
from bitarray import bitarray
4+
5+
6+
def fixed_weight_tableau(n_qubits, n_meas, weight, XYZ = False):
7+
8+
"""Generates a tableau in dict form, with n_meas pure Z stabilizers of given weight
9+
and pure X destabilizes of arbitrary weight
10+
This can be given as the argument "tableau" to the Stabilizer constructor
11+
12+
If XYZ is False, will yield random Z stabilizers only"""
13+
14+
if n_meas >= n_qubits:
15+
raise Exception(
16+
"n_meas should be strictly less than n_qubits"
17+
)
18+
if weight >= n_qubits:
19+
raise Exception(
20+
"Your Paulis are overweight :( weight should be strictly less than n_qubits"
21+
)
22+
23+
# bistring generation in lexicographic order: https://stackoverflow.com/a/58072652
24+
def kbits(n, k):
25+
limit=1<<n
26+
val=(1<<k)-1
27+
while val<limit:
28+
yield "{0:0{1}b}".format(val,n)
29+
minbit=val&-val #rightmost 1 bit
30+
fillbit = (val+minbit)&~val #rightmost 0 to the left of that bit
31+
val = val+minbit | (fillbit//(minbit<<1))-1
32+
33+
Stabz = np.zeros(n_qubits)
34+
35+
for val in kbits(n_qubits, weight):
36+
valarray = bitarray(val).tolist()
37+
Stabz = np.vstack((Stabz, valarray))
38+
39+
Stabz = np.delete(Stabz, 0, 0)
40+
Stabz = Stabz.astype(int)
41+
42+
rng = np.random.default_rng()
43+
rng.shuffle(Stabz)
44+
45+
46+
if XYZ:
47+
48+
def commutes_with_all(Stabxyz_list, newstab):
49+
50+
commutes = True
51+
index = 0
52+
53+
while commutes & index<len(Stabxyz_list):
54+
anticommutations = (newstab != Stabxyz_list[index]) #TODO: just use qiskit lmao
55+
commutes = not sum(anticommutations) % 2
56+
index += 1
57+
58+
return commutes
59+
60+
PauliArray = rng.choice(range(1,4), n_qubits)
61+
mask = rng.choice(Stabz)
62+
Stabxyz = np.array([PauliArray*mask])
63+
64+
while np.linalg.matrix_rank(Stabxyz) < n_meas: # TODO : check linear independence using qiskit symplectic notation or stim
65+
current_rank = np.linalg.rank(Stabxyz)
66+
while np.linalg.matrix_rank(Stabxyz) == current_rank:
67+
PauliArray = rng.choice(range(1,4), n_qubits)
68+
mask = rng.choice(Stabz)
69+
Stabxyz = np.vstack(Stabxyz, PauliArray*mask)
70+
71+
#TODO : randomize signs BUT careful that they're not contradictory like +Z and -Z
72+
73+
74+
75+
stimStabz = (3*Stabz).tolist() # In Stim, 0=I, 1=X, 2=Y, 3=Z
76+
stimStabz = [stim.PauliString(stab) for stab in stimStabz]
77+
78+
tableau = stim.Tableau.from_stabilizers(stimStabz, allow_redundant=True, allow_underconstrained=True)
79+
80+
# Translate to Qiskit and choose n_meas stabilizers
81+
stabilizer = [str(tableau.z_output(i)).replace('_','I') for i in range(n_meas)]
82+
destabilizer = [str(tableau.x_output(i)).replace('_','I') for i in range(n_meas)]
83+
tableau_dict = {"stabilizer" : stabilizer, "destabilizer" : destabilizer}
84+
85+
return(tableau_dict)
86+
87+
# print(fixed_weight_tableau(10,5,5,XYZ=True))

setup.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
"numpy>=1.17",
1010
"scikit-learn",
1111
"ipykernel"
12+
"stim"
13+
"bitarray"
1214
]
1315

1416
setup(

0 commit comments

Comments
 (0)