Skip to content

Noise

Noise for simulations

NoiseHandler(protocol, options=dict())

A container for multiple sources of noise.

Note NoiseProtocol.ANALOG and NoiseProtocol.DIGITAL sources cannot be both present. Also NoiseProtocol.READOUT can only be present once as the last noise sources, and only exclusively with NoiseProtocol.DIGITAL sources.

PARAMETER DESCRIPTION
protocol

The protocol(s) applied. To be defined from NoiseProtocol.

TYPE: NoiseEnum | list[NoiseEnum]

options

A list of options defining the protocol. For NoiseProtocol.ANALOG, options should contain a field noise_probs. For NoiseProtocol.DIGITAL, options should contain a field error_probability.

TYPE: dict | list[dict] DEFAULT: dict()

Examples:

    from qadence import NoiseProtocol, NoiseHandler

    analog_options = {"noise_probs": 0.1}
    digital_options = {"error_probability": 0.1}
    readout_options = {"error_probability": 0.1, "seed": 0}

    # single noise sources
    analog_noise = NoiseHandler(NoiseProtocol.ANALOG.DEPOLARIZING, analog_options)
    digital_depo_noise = NoiseHandler(NoiseProtocol.DIGITAL.DEPOLARIZING, digital_options)
    readout_noise = NoiseHandler(NoiseProtocol.READOUT, readout_options)

    # init from multiple sources
    protocols: list = [NoiseProtocol.DIGITAL.DEPOLARIZING, NoiseProtocol.READOUT]
    options: list = [digital_options, readout_noise]
    noise_combination = NoiseHandler(protocols, options)

    # Appending noise sources
    noise_combination = NoiseHandler(NoiseProtocol.DIGITAL.BITFLIP, digital_options)
    noise_combination.append([digital_depo_noise, readout_noise])
Source code in qadence/noise/protocols.py
def __init__(
    self,
    protocol: NoiseEnum | list[NoiseEnum],
    options: dict | list[dict] = dict(),
) -> None:
    self.protocol = protocol if isinstance(protocol, list) else [protocol]
    self.options = options if isinstance(options, list) else [options] * len(self.protocol)
    self.verify_all_protocols()

append(other)

Append noises.

PARAMETER DESCRIPTION
other

The noises to add.

TYPE: NoiseHandler | list[NoiseHandler]

Source code in qadence/noise/protocols.py
def append(self, other: NoiseHandler | list[NoiseHandler]) -> None:
    """Append noises.

    Args:
        other (NoiseHandler | list[NoiseHandler]): The noises to add.
    """
    # To avoid overwriting the noise_sources list if an error is raised, make a copy
    other_list = other if isinstance(other, list) else [other]
    protocols = self.protocol[:]
    options = self.options[:]

    for noise in other_list:
        protocols += noise.protocol
        options += noise.options

    # init may raise an error
    temp_handler = NoiseHandler(protocols, options)
    # if verify passes, replace protocols and options
    self.protocol = temp_handler.protocol
    self.options = temp_handler.options

verify_all_protocols()

Make sure all protocols are correct in terms and their combination too.

Source code in qadence/noise/protocols.py
def verify_all_protocols(self) -> None:
    """Make sure all protocols are correct in terms and their combination too."""

    if len(self.protocol) == 0:
        raise ValueError("NoiseHandler should be specified with one valid configuration.")

    if len(self.protocol) != len(self.options):
        raise ValueError("Specify lists of same length when defining noises.")

    for protocol, option in zip(self.protocol, self.options):
        self._verify_single_protocol(protocol, option)

    types = [type(p) for p in self.protocol]
    unique_types = set(types)
    if NoiseProtocol.DIGITAL in unique_types and NoiseProtocol.ANALOG in unique_types:
        raise ValueError("Cannot define a config with both Digital and Analog noises.")

    if NoiseProtocol.ANALOG in unique_types:
        if NoiseProtocol.READOUT in unique_types:
            raise ValueError("Cannot define a config with both READOUT and Analog noises.")
        if types.count(NoiseProtocol.ANALOG) > 1:
            raise ValueError("Multiple Analog Noises are not supported yet.")

    if NoiseProtocol.READOUT in self.protocol:
        if (
            self.protocol[-1] != NoiseProtocol.READOUT
            or self.protocol.count(NoiseProtocol.READOUT) > 1
        ):
            raise ValueError("Only define a NoiseHandler with one READOUT as the last Noise.")

apply_readout_noise(noise, samples)

Apply readout noise to samples if provided.

PARAMETER DESCRIPTION
noise

Noise to apply.

TYPE: NoiseHandler

samples

Samples to alter

TYPE: list[Counter]

RETURNS DESCRIPTION
list[Counter]

list[Counter]: Altered samples.

Source code in qadence/noise/protocols.py
def apply_readout_noise(noise: NoiseHandler, samples: list[Counter]) -> list[Counter]:
    """Apply readout noise to samples if provided.

    Args:
        noise (NoiseHandler): Noise to apply.
        samples (list[Counter]): Samples to alter

    Returns:
        list[Counter]: Altered samples.
    """
    if noise.protocol[-1] == NoiseProtocol.READOUT:
        error_fn = noise.get_noise_fn(-1)
        # Get the number of qubits from the sample keys.
        n_qubits = len(list(samples[0].keys())[0])
        # Get the number of shots from the sample values.
        n_shots = sum(samples[0].values())
        noisy_samples: list = error_fn(
            counters=samples, n_qubits=n_qubits, options=noise.options[-1], n_shots=n_shots
        )
        return noisy_samples
    else:
        return samples