@@ -31,14 +31,18 @@ class StabilizerCircuit(AbstractCircuit):
31
31
"sd" : "S_DAG" ,
32
32
}
33
33
34
- def __init__ (self , nqubits : int , inputs : Tensor = None ) -> None :
34
+ def __init__ (
35
+ self , nqubits : int , inputs : Tensor = None , tableau_inputs : Tensor = None
36
+ ) -> None :
35
37
"""
36
38
``StabilizerCircuit`` class based on stim package
37
39
38
40
:param nqubits: Number of qubits
39
41
:type nqubits: int
40
42
:param inputs: initial state by stabilizers, defaults to None
41
43
:type inputs: Tensor, optional
44
+ :param tableau_inputs: initial state by **inverse** tableau, defaults to None
45
+ :type tableau_inputs: Tensor, optional
42
46
"""
43
47
self ._nqubits = nqubits
44
48
self ._stim_circuit = stim .Circuit ()
@@ -49,6 +53,8 @@ def __init__(self, nqubits: int, inputs: Tensor = None) -> None:
49
53
self .current_sim = stim .TableauSimulator ()
50
54
if inputs :
51
55
self .current_sim .set_state_from_stabilizers (inputs )
56
+ if tableau_inputs :
57
+ self .current_sim .set_inverse_tableau (tableau_inputs )
52
58
53
59
def apply_general_gate (
54
60
self ,
@@ -123,6 +129,22 @@ def random_gate(self, *index: int, recorded: bool = False) -> None:
123
129
if recorded :
124
130
self ._stim_circuit += t .to_circuit ()
125
131
132
+ def tableau_gate (self , * index : int , tableau : Any , recorded : bool = False ) -> None :
133
+ """
134
+ Apply a gate indicated by tableau to the circuit.
135
+ This operation will not record in qir
136
+
137
+ :param index: Qubit indices to apply the gate to
138
+ :type index: int
139
+ :param tableau: stim.Tableau representation of the gate
140
+ :type tableau: Any
141
+ :param recorded: Whether the gate is recorded in ``stim.Circuit``, defaults to False
142
+ :type recorded: bool, optional
143
+ """
144
+ self .current_sim .do_tableau (tableau , index )
145
+ if recorded :
146
+ self ._stim_circuit += tableau .to_circuit ()
147
+
126
148
def measure (self , * index : int , with_prob : bool = False ) -> Tensor :
127
149
"""
128
150
Measure qubits in Z basis.
@@ -167,6 +189,27 @@ def cond_measurement(self, index: int) -> Tensor:
167
189
168
190
cond_measure = cond_measurement
169
191
192
+ def cond_measure_many (self , * index : int ) -> Tensor :
193
+ """
194
+ Measure qubits in Z basis with state collapse.
195
+
196
+ :param index: Index of qubit to measure
197
+ :type index: int
198
+ :return: Measurement results and probability (if with_prob=True)
199
+ :rtype: Union[np.ndarray, Tuple[np.ndarray, float]]
200
+ """
201
+ # Convert negative indices
202
+
203
+ # Add measurement instructions
204
+ self ._stim_circuit .append_from_stim_program_text (
205
+ "M " + " " .join (map (str , index ))
206
+ )
207
+ # self.current_sim = None
208
+ m = self .current_simulator ().measure_many (* index )
209
+ # Sample once from the circuit using sampler
210
+
211
+ return m
212
+
170
213
def sample (
171
214
self ,
172
215
batch : Optional [int ] = None ,
@@ -346,6 +389,12 @@ def current_tableau(self) -> stim.Tableau:
346
389
"""
347
390
return self .current_simulator ().current_inverse_tableau () ** - 1
348
391
392
+ def current_inverse_tableau (self ) -> stim .Tableau :
393
+ """
394
+ Return the current inverse tableau of the circuit.
395
+ """
396
+ return self .current_simulator ().current_inverse_tableau ()
397
+
349
398
def entanglement_entropy (self , cut : Sequence [int ]) -> float :
350
399
"""
351
400
Calculate the entanglement entropy for a subset of qubits using stabilizer formalism.
0 commit comments