77
88tc .set_dtype ("complex128" )
99
10- clifford_one_qubit_gates = ["h " , "x " , "y " , "z " , "s " ]
11- clifford_two_qubit_gates = ["cnot " ]
10+ clifford_one_qubit_gates = ["H " , "X " , "Y " , "Z " , "S " ]
11+ clifford_two_qubit_gates = ["CNOT " ]
1212clifford_gates = clifford_one_qubit_gates + clifford_two_qubit_gates
1313
1414
@@ -22,42 +22,32 @@ def genpair(num_qubits, count):
2222
2323def random_clifford_circuit_with_mid_measurement (num_qubits , depth ):
2424 c = tc .Circuit (num_qubits )
25+ operation_list = []
2526 for _ in range (depth ):
2627 for j , k in genpair (num_qubits , 2 ):
2728 c .cnot (j , k )
29+ operation_list .append (("CNOT" , (j , k )))
2830 for j in range (num_qubits ):
29- getattr (c , np .random .choice (clifford_one_qubit_gates ))(j )
31+ gate_name = np .random .choice (clifford_one_qubit_gates )
32+ getattr (c , gate_name )(j )
33+ operation_list .append ((gate_name , (j ,)))
3034 measured_qubit = np .random .randint (0 , num_qubits - 1 )
3135 sample , p = c .measure_reference (measured_qubit , with_prob = True )
3236 # Check if there is a non-zero probability to measure "0" for post-selection
33- if (sample == "0" and p > 0.0 ) or (sample == "1" and p < 1.0 ):
37+ if (sample == "0" and not np .isclose (p , 0.0 )) or (
38+ sample == "1" and not np .isclose (p , 1.0 )
39+ ):
3440 c .mid_measurement (measured_qubit , keep = 0 )
35- c . measure_instruction ( measured_qubit )
36- return c
41+ operation_list . append (( "M" , ( measured_qubit ,)) )
42+ return c , operation_list
3743
3844
39- def convert_tc_circuit_to_stim_circuit ( tc_circuit ):
45+ def convert_operation_list_to_stim_circuit ( operation_list ):
4046 stim_circuit = stim .Circuit ()
41- for instruction in tc_circuit ._qir :
42- gate_name = instruction ["gate" ].name
43- qubits = instruction .get ("index" , [])
44- if gate_name == "x" :
45- stim_circuit .append ("X" , qubits )
46- elif gate_name == "y" :
47- stim_circuit .append ("Y" , qubits )
48- elif gate_name == "z" :
49- stim_circuit .append ("Z" , qubits )
50- elif gate_name == "h" :
51- stim_circuit .append ("H" , qubits )
52- elif gate_name == "cnot" :
53- stim_circuit .append ("CNOT" , qubits )
54- elif gate_name == "s" :
55- stim_circuit .append ("S" , qubits )
56- else :
57- raise ValueError (f"Unsupported gate: { gate_name } " )
58- for measurement in tc_circuit ._extra_qir :
59- qubits = measurement ["index" ]
60- stim_circuit .append ("M" , qubits )
47+ for instruction in operation_list :
48+ gate_name = instruction [0 ]
49+ qubits = instruction [1 ]
50+ stim_circuit .append (gate_name , qubits )
6151 return stim_circuit
6252
6353
@@ -118,13 +108,8 @@ def simulate_stim_circuit_with_mid_measurement(stim_circuit):
118108 if instruction .name == "M" :
119109 for t in instruction .targets_copy ():
120110 expectaction_value = simulator .peek_z (t .value )
121- desired_measurement_outcome = 0
122- if expectaction_value == - 1 : # zero probability to measure "0"
123- desired_measurement_outcome = 1
124- simulator .postselect_z (
125- t .value ,
126- desired_value = desired_measurement_outcome ,
127- )
111+ if expectaction_value != - 1 : # non-zero probability to measure "0"
112+ simulator .postselect_z (t .value , desired_value = 0 )
128113 else :
129114 simulator .do (instruction )
130115
@@ -133,12 +118,14 @@ def simulate_stim_circuit_with_mid_measurement(stim_circuit):
133118
134119if __name__ == "__main__" :
135120 num_qubits = 10
136- depth = 8
121+ depth = 20
137122
138- tc_circuit = random_clifford_circuit_with_mid_measurement (num_qubits , depth )
123+ tc_circuit , op_list = random_clifford_circuit_with_mid_measurement (
124+ num_qubits , depth
125+ )
139126 print (tc_circuit .draw (output = "text" ))
140127
141- stim_circuit = convert_tc_circuit_to_stim_circuit ( tc_circuit )
128+ stim_circuit = convert_operation_list_to_stim_circuit ( op_list )
142129
143130 # Entanglement entropy calculation using stabilizer formalism
144131 stabilizer_tableau = simulate_stim_circuit_with_mid_measurement (stim_circuit )
0 commit comments