Source code for surface_sim.experiments.rot_surface_code_xzzx_google
from collections.abc import Collection
from copy import deepcopy
from stim import Circuit
from ..circuit_blocks.rot_surface_code_xzzx import (
init_qubits,
qec_round_google,
qec_round_google_with_log_meas,
qubit_coords,
)
from ..detectors import Detectors
from ..layouts.layout import Layout
from ..models import Model
[docs]
def memory_experiment(
model: Model,
layout: Layout,
detectors: Detectors,
num_rounds: int,
data_init: dict[str, int] | list[int],
anc_detectors: Collection[str] | None = None,
rot_basis: bool = False,
gauge_detectors: bool = True,
) -> Circuit:
"""Returns the circuit for running a memory experiment.
Parameters
----------
model
Noise model for the gates.
layout
Code layout.
detectors
Detector definitions to use.
num_rounds
Number of QEC round to run in the memory experiment.
data_init
Bitstring for initializing the data qubits.
rot_basis
If ``True``, the memory experiment is performed in the X basis.
If ``False``, the memory experiment is performed in the Z basis.
By deafult ``False``.
anc_detectors
List of ancilla qubits for which to define the detectors.
If ``None``, adds all detectors.
By default ``None``.
gauge_detectors
If ``True``, adds gauge detectors (coming from the first QEC round).
If ``False``, the resulting circuit does not have gauge detectors.
By default ``True``.
"""
if not isinstance(num_rounds, int):
raise ValueError(f"num_rounds expected as int, got {type(num_rounds)} instead.")
if num_rounds <= 0:
raise ValueError("num_rounds needs to be a (strickly) positive integer.")
if not isinstance(data_init, dict):
raise TypeError(f"'data_init' must be a dict, but {type(data_init)} was given.")
if not isinstance(layout, Layout):
raise TypeError(f"'layout' must be a layout, but {type(layout)} was given.")
if anc_detectors is None:
anc_detectors = layout.anc_qubits
model.new_circuit()
detectors.new_circuit()
experiment = Circuit()
experiment += qubit_coords(model, layout)
experiment += init_qubits(model, layout, detectors, data_init, rot_basis)
if num_rounds == 1:
first_dets = deepcopy(anc_detectors)
if not gauge_detectors:
stab_type = "x_type" if rot_basis else "z_type"
stab_qubits = layout.get_qubits(role="anc", stab_type=stab_type)
first_dets = set(anc_detectors).intersection(stab_qubits)
experiment += qec_round_google_with_log_meas(
model, layout, detectors, first_dets, rot_basis
)
return experiment
for r in range(num_rounds - 1):
if r == 0 and (not gauge_detectors):
stab_type = "x_type" if rot_basis else "z_type"
stab_qubits = layout.get_qubits(role="anc", stab_type=stab_type)
first_dets = set(anc_detectors).intersection(stab_qubits)
experiment += qec_round_google(model, layout, detectors, first_dets)
continue
experiment += qec_round_google(model, layout, detectors, anc_detectors)
experiment += qec_round_google_with_log_meas(
model, layout, detectors, anc_detectors, rot_basis
)
return experiment