Skip to content

Commit 4b88085

Browse files
authored
Random XYZ strings (#36)
fixed weight tableau generator with random XYZ string
1 parent 3ecdea5 commit 4b88085

File tree

2 files changed

+59
-32
lines changed

2 files changed

+59
-32
lines changed
Lines changed: 57 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import numpy as np
22
import stim
33
from bitarray import bitarray
4+
from qiskit.quantum_info import Pauli, PauliList
45

56

67
def fixed_weight_tableau(n_qubits, n_meas, weight, XYZ = False):
@@ -20,6 +21,7 @@ def fixed_weight_tableau(n_qubits, n_meas, weight, XYZ = False):
2021
"Your Paulis are overweight :( weight should be strictly less than n_qubits"
2122
)
2223

24+
2325
# bistring generation in lexicographic order: https://stackoverflow.com/a/58072652
2426
def kbits(n, k):
2527
limit=1<<n
@@ -41,41 +43,66 @@ def kbits(n, k):
4143

4244
rng = np.random.default_rng()
4345
rng.shuffle(Stabz)
44-
45-
46+
4647
if XYZ:
4748

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
49+
# Currently I'm letting Stim take care of choosing a set of linearly independent stabilizers
50+
# but I'm leaving this rank function here in case we need it later.
51+
52+
# def gf2_rank(rows):
53+
# """
54+
# Find rank of a matrix over GF2.
55+
56+
# The rows of the matrix are given as nonnegative integers, thought
57+
# of as bit-strings.
58+
59+
# This function modifies the input list. Use gf2_rank(rows.copy())
60+
# instead of gf2_rank(rows) to avoid modifying rows.
61+
# """
62+
# rank = 0
63+
# while rows:
64+
# pivot_row = rows.pop()
65+
# if pivot_row:
66+
# rank += 1
67+
# lsb = pivot_row & -pivot_row
68+
# for index, row in enumerate(rows):
69+
# if row & lsb:
70+
# rows[index] = row ^ pivot_row
71+
# return rank
72+
73+
Paulis = ['X', 'Y', 'Z']
74+
signs = ['+', '-']
75+
76+
def generate_random_Paulistring():
77+
PauliArray = rng.choice(Paulis, n_qubits)
78+
mask = rng.choice(Stabz).astype(bool)
79+
newPaulistring = rng.choice(signs) + ''.join(np.where(mask, PauliArray, 'I'))
80+
return newPaulistring
81+
82+
83+
Stabxyz = PauliList(generate_random_Paulistring())
84+
print(Stabxyz)
85+
86+
while (Stabxyz.size < 3*n_qubits) & (Stabxyz.size < 2**(weight-1)): # generate enough strings that at least n_qubit of them are linearly independent
87+
88+
commute = False
89+
already_here = False
90+
while not commute or already_here:
91+
newPaulistring = Pauli(generate_random_Paulistring())
92+
commute = newPaulistring.commutes(Stabxyz).all()
93+
already_here = Stabxyz.equiv(newPaulistring).any()
94+
95+
Stabxyz = Stabxyz.insert(0, newPaulistring)
96+
print(Stabxyz)
7297

98+
Stab = Stabxyz.to_labels()
7399

100+
else:
101+
Stab = (3*Stabz).tolist() # In Stim, 0=I, 1=X, 2=Y, 3=Z
74102

75-
stimStabz = (3*Stabz).tolist() # In Stim, 0=I, 1=X, 2=Y, 3=Z
76-
stimStabz = [stim.PauliString(stab) for stab in stimStabz]
103+
stimStabz = [stim.PauliString(stab) for stab in Stab]
77104

78-
tableau = stim.Tableau.from_stabilizers(stimStabz, allow_redundant=True, allow_underconstrained=True)
105+
tableau = stim.Tableau.from_stabilizers(stimStabz, allow_redundant=True, allow_underconstrained=not XYZ)
79106

80107
# Translate to Qiskit and choose n_meas stabilizers
81108
stabilizer = [str(tableau.z_output(i)).replace('_','I') for i in range(n_meas)]
@@ -84,4 +111,4 @@ def commutes_with_all(Stabxyz_list, newstab):
84111

85112
return(tableau_dict)
86113

87-
# print(fixed_weight_tableau(10,5,5,XYZ=True))
114+
# print(fixed_weight_tableau(10,9,9,XYZ=True))

setup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
"qiskit-aer>=0.12.0",
99
"numpy>=1.17",
1010
"scikit-learn",
11-
"ipykernel"
12-
"stim"
11+
"ipykernel",
12+
"Stim @ git+https://github.com/deltark/Stim.git",
1313
"bitarray"
1414
]
1515

0 commit comments

Comments
 (0)