@@ -67,14 +67,12 @@ def get_binary_matrix(z_stabilizers):
67
67
return binary_matrix
68
68
69
69
70
- def get_bipartite_binary_matrix (binary_matrix , cut ):
70
+ def get_cut_binary_matrix (binary_matrix , cut ):
71
71
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 ]
78
76
79
77
80
78
# 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):
107
105
for instruction in stim_circuit .flattened ():
108
106
if instruction .name == "M" :
109
107
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 :
112
111
simulator .postselect_z (t .value , desired_value = 0 )
113
112
else :
114
113
simulator .do (instruction )
@@ -117,8 +116,12 @@ def simulate_stim_circuit_with_mid_measurement(stim_circuit):
117
116
118
117
119
118
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 )]
122
125
123
126
tc_circuit , op_list = random_clifford_circuit_with_mid_measurement (
124
127
num_qubits , depth
@@ -131,16 +134,17 @@ def simulate_stim_circuit_with_mid_measurement(stim_circuit):
131
134
stabilizer_tableau = simulate_stim_circuit_with_mid_measurement (stim_circuit )
132
135
zs = [stabilizer_tableau .z_output (k ) for k in range (len (stabilizer_tableau ))]
133
136
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 )
136
139
print ("Stim Entanglement Entropy:" , stim_entropy )
137
140
138
141
# Entanglement entropy calculation using TensorCircuit
139
142
state_vector = tc_circuit .wavefunction ()
140
143
assert np .linalg .norm (state_vector ) > 0
141
144
# Normalize the state vector because mid-measurement operation is not unitary
142
145
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 )
144
147
print ("TensorCircuit Entanglement Entropy:" , tc_entropy )
145
148
149
+ # Check if the entanglement entropies are close
146
150
np .testing .assert_allclose (stim_entropy , tc_entropy , atol = 1e-8 )
0 commit comments