Checked circuit
qiskit_paulice.checked_circuit
A class for specifying a circuit containing coherent spacetime Pauli checks.
CheckedCircuit
class CheckedCircuit(circuit, target_qubits=(), check_qubits=(), check_support=(), cost=None, cost_metric=None)
Bases: object
A quantum circuit and information about spacetime Pauli checks it contains.
Instances returned by add_pauli_checks() build circuit on first access rather than up front, so reading the check metadata of every variant (cost, check_support, …) builds no circuit. The circuit is built once and kept; circuit is otherwise an ordinary attribute. Anything that reads circuit builds it, including repr(). Concurrent first reads of the same instance may each build the circuit, but they yield equal circuits.
circuit
A quantum circuit containing 0 or more spacetime Pauli checks.
Type
target_qubits
Qubit indices of circuit which were used to entangle the check qubits to the payload. Empty if circuit contains no checks.
Type
check_qubits
Qubit indices of the ancilla qubits in circuit. The i``th check uses ``check_qubits[i] to detect errors on target_qubits[i] and other qubits in check_support[i].
Type
check_support
For each check, the qubit indices whose measurement outcomes XOR together to give that check’s syndrome bit. For a check found for stabilizers of the prepared state this is just its ancilla.
Type
cost
cost_metric
Raises
ValueError – circuit has a qubit with an instruction other than a barrier after its measurement.
box
box(payload_layers=None, **kwargs)
Box circuit while maintaining concurrent scheduling of payload layers.
This method stratifies the entangling layers of the checked circuit into boxes such that the number of unique entangling layers is minimized. This is done by scheduling the entangling gates from the Pauli checks into boxes of their own, resulting in one unique layer per Pauli check in addition to the payload_layers.
Scheduling check gates into boxes of their own is beneficial in that the number of unique entangling layers is minimized, but it comes at a cost of sub-optimal gate scheduling.
Parameters
- payload_layers (Iterable[Iterable[tuple[int, int]]] | None) – The unique entangling layers of the bare payload circuit. Each inner list contains the edges for one unique layer. Edges should not be repeated within the same layer, but may appear in multiple layers; each stratum of the boxed circuit is then consistent with (a subset of) one of these layers.
- **kwargs – Overrides for
generate_boxing_pass_manager(). Defaults to the key-value pairs inBOXING_DEFAULTS.
Returns
circuit, boxed and annotated.
Raises
- ValueError –
payload_layersdoes not describe this circuit’s payload gates. - ValueError –
circuitcontains an instruction other than one- and two-qubit unitary gates, measurements, and barriers.
Return type
dope
dope(num_sites=None, *, wires='all', angle=0.7853981633974483, seed=None, box=False, payload_layers=None, box_options=None)
Dope self.circuit with RZGate rotations that commute with check stabilizers.
Parameters
-
num_sites (int | None) – Number of
RZGaterotations to place in the circuit.Noneuses every possible location. -
wires (Literal['all', 'after_entangling', 'before_entangling']) –
Which wires may hold a rotation:
"all": Dope every possible wire."after_entangling": Dope only wires directly after multi-qubit gates."before_entangling": Dope only wires directly before multi-qubit gates.
-
angle (float | None) – Rotation angle for each inserted
RZGate.Noneinstead gives each rotation its own parameter from aParameterVectornameddope. The rotation on the returneddoped_wires[i]getsdope[i], so a list of angles binds indoped_wiresorder. -
seed (int |Generator | None) – Seed or generator for the random site selection.
-
box (bool) – Whether to box the doped circuit, as
box()boxescircuit. -
payload_layers (Iterable[Iterable[tuple[int, int]]] | None) – The
payload_layersargument ofbox(). Only used withbox=True. -
box_options (Mapping[str, Any] | None) – Overrides for
generate_boxing_pass_manager(), as the**kwargsofbox(). Only used withbox=True.
Returns
a copy of circuit with the rotations inserted, and the Wire holding each rotation, in circuit order and with instruction indices into circuit. The checks and classical bits are unchanged, so get_postselection_method() applies to the doped circuit’s results.
Return type
(doped_circuit, doped_wires)
Raises
- ValueError –
circuitcontains a non-Clifford instruction. - ValueError –
wiresis not one of the allowed values. - ValueError –
payload_layersorbox_optionsis given withoutbox=True, orbox()rejects the doped circuit. - ValueError –
num_sitesis negative, larger than the number of valid sites, or that many sites could not be drawn at random from them.
Example
Dope a one-qubit circuit with parametrized rotations, then bind their angles:
import numpy as np
from qiskit import QuantumCircuit
from qiskit_paulice import CheckedCircuit
circuit = QuantumCircuit(1)
circuit.h(0)
circuit.h(0)
circuit.h(0)
circuit.measure_all()
doped_circuit, doped_wires = CheckedCircuit(circuit).dope(angle=None)
print(doped_wires)
# (Wire(qubit=0, after_instruction=0), Wire(qubit=0, after_instruction=1))
# dope[0] follows the first H gate, and dope[1] follows the second.
bound = doped_circuit.assign_parameters([np.pi / 4, np.pi / 8])References
S. Martiel et al., Sampling hard circuits with verifiably high fidelity, arXiv:2607.25941.
estimate_fault_rates
estimate_fault_rates(noise_model, shots=100000, seed=None)
Estimate acceptance, harmless-fault, logical-error, and check trigger rates.
One noisy Monte Carlo sampling under noise_model yields all rates. A shot is accepted if all check syndromes are . An error is harmless if it is non-identity yet backpropagates to a diagonal Pauli on the input, acting as a global phase on . A logical error is a sample corrupted by a logical error that evaded the checks. The check trigger rate is the probability that a given check flags a non-zero syndrome. All fault rates are with respect to all shots taken.
Parameters
- noise_model (NoiseModel) – Noise to apply during Monte Carlo sampling.
- shots (int) – Number of fault configurations to sample.
- seed (int |Generator | None) – Seed or generator for the fault sampling.
Returns
The estimated fault rates with their standard errors.
Raises
ValueError – The noise model is empty or unsupported, or circuit contains a non-Clifford instruction.
Return type
get_postselection_method
get_postselection_method()
Return a function that maps a single shot’s outcome to a syndrome vector.
No errors were detected iff every entry of the returned vector is zero. The returned function accepts either bitstrings or bit arrays.
Return type
uncovered_paulis
Type: tuple[UncoveredPauli, ...]
Locations where a single qubit Pauli error is undetectable by the checks.
Each entry is an UncoveredPauli(qubit, after_instruction, pauli) triple. Only input wires and wires immediately after 2-qubit gates are enumerated; errors after single qubit gates are folded into the next 2-qubit-gate wire.
Raises
ValueError – circuit contains a non-Clifford instruction.
UncoveredPauli
class UncoveredPauli(qubit, after_instruction, pauli)
Bases: NamedTuple
A spacetime location at which a single qubit Pauli error is undetectable by the set of checks.
qubit
after_instruction
Index (into circuit.data) of the instruction the error occurs after. None means the error sits on the qubit’s input wire.
Type
int | None
pauli
The undetected Pauli error ("X", "Y", or "Z")
Type
Literal[‘X’, ‘Y’, ‘Z’]
Create new instance of UncoveredPauli(qubit, after_instruction, pauli)
count
count(value, /)
Return number of occurrences of value.
index
index(value, start=0, stop=9223372036854775807, /)
Return first index of value.
Raises ValueError if the value is not present.
FaultRates
class FaultRates(harmless_rate, harmless_stderr, logical_error_rate, logical_error_stderr, acceptance_rate, acceptance_stderr, check_trigger_rates, check_trigger_stderrs, shots)
Bases: NamedTuple
Monte Carlo fault-rate estimates for a checked circuit, from one common sample set.
harmless_rate
Probability that a shot contains errors that only act on the quantum state as a global phase. Harmless samples are always accepted; however, this probability is not conditioned on acceptance. To condition on acceptance: .
Type
harmless_stderr
logical_error_rate
Probability that a shot is accepted and its error flips one or more payload measurement outcomes. If the circuit measures no payload qubit, as when its checks were found for stabilizers of the prepared state, it is instead the probability that a shot is accepted and its error changes the prepared state. Logical errors are always accepted; however, this probability is not conditioned on acceptance. To condition on acceptance: .
Type
logical_error_stderr
acceptance_rate
acceptance_stderr
check_trigger_rates
check_trigger_stderrs
shots
Create new instance of FaultRates(harmless_rate, harmless_stderr, logical_error_rate, logical_error_stderr, acceptance_rate, acceptance_stderr, check_trigger_rates, check_trigger_stderrs, shots)
count
count(value, /)
Return number of occurrences of value.
index
index(value, start=0, stop=9223372036854775807, /)
Return first index of value.
Raises ValueError if the value is not present.
BOXING_DEFAULTS
Default value: {'inject_noise_site': 'after', 'inject_noise_strategy': 'individual_modification', 'inject_noise_targets': 'gates', 'measure_annotations': 'all', 'remove_barriers': 'after_stratification', 'twirling_strategy': 'active'}
Options CheckedCircuit.box() passes to generate_boxing_pass_manager(), before **kwargs overrides.