Skip to content

Commit ca943aa

Browse files
committed
feat: allow tracing out any list of qubits in stim example
1 parent 15aa34a commit ca943aa

File tree

1 file changed

+18
-14
lines changed

1 file changed

+18
-14
lines changed

examples/stabilizer_simulation.py

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,12 @@ def get_binary_matrix(z_stabilizers):
6767
return binary_matrix
6868

6969

70-
def get_bipartite_binary_matrix(binary_matrix, cut):
70+
def get_cut_binary_matrix(binary_matrix, cut):
7171
N = len(binary_matrix)
72-
bipartite_binary_matrix = np.zeros((N, 2 * cut))
73-
74-
bipartite_binary_matrix[:, :cut] = binary_matrix[:, :cut]
75-
bipartite_binary_matrix[:, cut:] = binary_matrix[:, N : N + cut]
76-
77-
return bipartite_binary_matrix
72+
new_indices = [i for i in range(N) if i not in set(cut)] + [
73+
i + N for i in range(N) if i not in set(cut)
74+
]
75+
return binary_matrix[:, new_indices]
7876

7977

8078
# ref: https://gist.github.com/StuartGordonReid/eb59113cb29e529b8105?permalink_comment_id=3268301#gistcomment-3268301
@@ -107,8 +105,9 @@ def simulate_stim_circuit_with_mid_measurement(stim_circuit):
107105
for instruction in stim_circuit.flattened():
108106
if instruction.name == "M":
109107
for t in instruction.targets_copy():
110-
expectaction_value = simulator.peek_z(t.value)
111-
if expectaction_value != -1: # non-zero probability to measure "0"
108+
expectaction_value = simulator.peek_z(t.value) # 1, 0, -1
109+
# there is a non-zero probability to measure "0" if expectaction_value is not -1
110+
if expectaction_value != -1:
112111
simulator.postselect_z(t.value, desired_value=0)
113112
else:
114113
simulator.do(instruction)
@@ -117,8 +116,12 @@ def simulate_stim_circuit_with_mid_measurement(stim_circuit):
117116

118117

119118
if __name__ == "__main__":
120-
num_qubits = 10
121-
depth = 20
119+
# Number of qubits
120+
num_qubits = 8
121+
# Depth of the circuit
122+
depth = 10
123+
# index list that is traced out to calculate the entanglement entropy
124+
cut = [i for i in range(num_qubits // 2)]
122125

123126
tc_circuit, op_list = random_clifford_circuit_with_mid_measurement(
124127
num_qubits, depth
@@ -131,16 +134,17 @@ def simulate_stim_circuit_with_mid_measurement(stim_circuit):
131134
stabilizer_tableau = simulate_stim_circuit_with_mid_measurement(stim_circuit)
132135
zs = [stabilizer_tableau.z_output(k) for k in range(len(stabilizer_tableau))]
133136
binary_matrix = get_binary_matrix(zs)
134-
bipartite_matrix = get_bipartite_binary_matrix(binary_matrix, num_qubits // 2)
135-
stim_entropy = (gf2_rank(bipartite_matrix.tolist()) - num_qubits // 2) * np.log(2)
137+
bipartite_matrix = get_cut_binary_matrix(binary_matrix, cut)
138+
stim_entropy = (gf2_rank(bipartite_matrix.tolist()) - len(cut)) * np.log(2)
136139
print("Stim Entanglement Entropy:", stim_entropy)
137140

138141
# Entanglement entropy calculation using TensorCircuit
139142
state_vector = tc_circuit.wavefunction()
140143
assert np.linalg.norm(state_vector) > 0
141144
# Normalize the state vector because mid-measurement operation is not unitary
142145
state_vector /= np.linalg.norm(state_vector)
143-
tc_entropy = tc.quantum.entanglement_entropy(state_vector, num_qubits // 2)
146+
tc_entropy = tc.quantum.entanglement_entropy(state_vector, cut)
144147
print("TensorCircuit Entanglement Entropy:", tc_entropy)
145148

149+
# Check if the entanglement entropies are close
146150
np.testing.assert_allclose(stim_entropy, tc_entropy, atol=1e-8)

0 commit comments

Comments
 (0)