@@ -48,6 +48,15 @@ class GateNoiseParams:
4848
4949@dataclass (frozen = True )
5050class MoveNoiseParams :
51+ idle_px_rate : float = field (default = 1e-6 , kw_only = True )
52+ """The error rate (prob/microsecond) for a Pauli-X error during an idle operation."""
53+ idle_py_rate : float = field (default = 1e-6 , kw_only = True )
54+ """The error rate (prob/microsecond) for a Pauli-Y error during an idle operation."""
55+ idle_pz_rate : float = field (default = 1e-6 , kw_only = True )
56+ """The error rate (prob/microsecond) for a Pauli-Z error during an idle operation."""
57+ idle_loss_rate : float = field (default = 1e-6 , kw_only = True )
58+ """The error rate (prob/microsecond) for a loss during an idle operation."""
59+
5160 move_px_rate : float = field (default = 1e-6 , kw_only = True )
5261 """The error rate (prob/microsecond) for a Pauli-X error during a move operation."""
5362 move_py_rate : float = field (default = 1e-6 , kw_only = True )
@@ -259,14 +268,79 @@ def parallel_cz_errors(
259268 px_time = self .poisson_pauli_prob (self .params .move_px_rate , move_duration )
260269 py_time = self .poisson_pauli_prob (self .params .move_py_rate , move_duration )
261270 px_time = self .poisson_pauli_prob (self .params .move_pz_rate , move_duration )
262- p_loss_time = self .poisson_pauli_prob (self .params .move_loss_rate , move_duration )
271+ move_p_loss_time = self .poisson_pauli_prob (
272+ self .params .move_loss_rate , move_duration
273+ )
263274
264- errors = {(px_time , py_time , px_time , p_loss_time ): rest }
275+ errors = {(px_time , py_time , px_time , move_p_loss_time ): rest }
265276
266277 px_moved = self .join_binary_probs (self .params .pick_px , px_time )
267278 py_moved = self .join_binary_probs (self .params .pick_py , py_time )
268279 pz_moved = self .join_binary_probs (self .params .pick_pz , px_time )
269- p_loss_moved = self .join_binary_probs (self .params .pick_loss_prob , p_loss_time )
280+ p_loss_moved = self .join_binary_probs (
281+ self .params .pick_loss_prob , move_p_loss_time
282+ )
283+
284+ errors [(px_moved , py_moved , pz_moved , p_loss_moved )] = sorted (ctrls + qargs )
285+
286+ return errors
287+
288+
289+ @dataclass
290+ class SingleZoneLayoutABC (MoveNoiseModelABC ):
291+ gate_noise_params : GateNoiseParams = field (
292+ default_factory = GateNoiseParams , kw_only = True
293+ )
294+
295+ @abc .abstractmethod
296+ def calculate_move_duration (self , ctrls : List [int ], qargs : List [int ]) -> float :
297+ """Calculate the time it takes to reconfigure the atom for executing the CZ gates."""
298+
299+ def parallel_cz_errors (
300+ self , ctrls : List [int ], qargs : List [int ], rest : List [int ]
301+ ) -> Dict [Tuple [float , float , float , float ], List [int ]]:
302+ """Apply parallel gates by moving ctrl qubits to qarg qubits."""
303+
304+ move_duration = self .calculate_move_duration (ctrls , qargs )
305+
306+ # idle errors during atom moves
307+ idle_px_time = self .poisson_pauli_prob (self .params .idle_px_rate , move_duration )
308+ idle_py_time = self .poisson_pauli_prob (self .params .idle_py_rate , move_duration )
309+ idle_pz_time = self .poisson_pauli_prob (self .params .idle_pz_rate , move_duration )
310+ idle_p_loss_time = self .poisson_pauli_prob (
311+ self .params .idle_loss_rate , move_duration
312+ )
313+
314+ # even qubits not involved in the gate can still experience unpaired errors
315+ idle_px = self .join_binary_probs (
316+ self .gate_noise_params .cz_unpaired_gate_px , idle_px_time
317+ )
318+ idle_py = self .join_binary_probs (
319+ self .gate_noise_params .cz_unpaired_gate_py , idle_py_time
320+ )
321+ idle_pz = self .join_binary_probs (
322+ self .gate_noise_params .cz_unpaired_gate_pz , idle_pz_time
323+ )
324+ idle_p_loss = self .join_binary_probs (
325+ self .gate_noise_params .cz_unpaired_loss_prob , idle_p_loss_time
326+ )
327+
328+ errors = {(idle_px , idle_py , idle_pz , idle_p_loss ): rest }
329+
330+ # error during the move
331+ move_px_time = self .poisson_pauli_prob (self .params .move_px_rate , move_duration )
332+ move_py_time = self .poisson_pauli_prob (self .params .move_py_rate , move_duration )
333+ move_pz_time = self .poisson_pauli_prob (self .params .move_pz_rate , move_duration )
334+ move_p_loss_time = self .poisson_pauli_prob (
335+ self .params .move_loss_rate , move_duration
336+ )
337+ # error coming from picking up the qubits
338+ px_moved = self .join_binary_probs (self .params .pick_px , move_px_time )
339+ py_moved = self .join_binary_probs (self .params .pick_py , move_py_time )
340+ pz_moved = self .join_binary_probs (self .params .pick_pz , move_pz_time )
341+ p_loss_moved = self .join_binary_probs (
342+ self .params .pick_loss_prob , move_p_loss_time
343+ )
270344
271345 errors [(px_moved , py_moved , pz_moved , p_loss_moved )] = sorted (ctrls + qargs )
272346
0 commit comments