Skip to content

Add physical noise to an experiment

Declare channels with NoiseChannel, collect them in NoiseModel, and pass the model through LocalBackend.run(noise=...). Run an ideal control first, then add one channel at a time. Keep the program, parameters, seeds, evolution settings and shot count so you can identify the source of a difference.

Channel Placement and meaning
preparation Independent bit flips in the initial state
dephasing Phase-flip process during Analog evolution, specified by a rate
gate Independent bit flips after each Digital gate
idle Dephasing over an explicit Digital idle duration
crosstalk Coherent XX term on specified targets and control intervals
boundary Amplitude damping at Hybrid block boundaries
atom_loss Occupation erasure at the end of Analog evolution
readout Asymmetric confusion of final measurement records without changing the state

Channels must match the program. A purely Digital circuit has no Analog dephasing duration; atom loss needs trajectory execution; boundary noise needs a Hybrid program. Constructing a model does not make every combination executable. Probabilities, rates and durations are different quantities.

Start with an analytically checkable channel

This H–Analog–H example adds dephasing and computes both an ideal control and an analytic prediction. The nonzero Analog duration provides the noise interval.

"""Execute physical dephasing on a continuous Hybrid state.

``NoiseModel`` selects a noisy-state engine instead of post-processing counts.
The result records the selected method, simulation classification, ordered
channel applications, and the same Hybrid state lineage used by ideal runs.
"""

from __future__ import annotations

import json

from cascaqit import (
    AHSProgram,
    AtomRegister,
    Circuit,
    HybridProgram,
    LocalBackend,
    Waveform,
)
from cascaqit.simulators import NoiseChannel, NoiseModel, SimulationOptions


def main() -> None:
    """Run a one-site D-A-D program with exact density-matrix dephasing."""
    analog = AHSProgram(
        AtomRegister.line(count=1, spacing=5.0),
        program_id="lesson.hybrid.noise.analog",
    ).drive(
        rabi=Waveform.constant(0.4, duration=0.1),
        detuning=Waveform.constant(0.0, duration=0.1),
        phase=0.0,
    )
    program = (
        HybridProgram("lesson.hybrid.noise")
        .digital("prepare", Circuit(1).h(0))
        .analog("evolve", analog)
        .digital("readout_rotation", Circuit(1).h(0))
        .measure_all()
    )
    noise = NoiseModel("lesson.hybrid.dephasing", (NoiseChannel.dephasing(0.3),))
    result = (
        LocalBackend(seed=104, analog_time_steps=4)
        .run(
            program,
            noise=noise,
            shots=32,
            options=SimulationOptions(
                method="density_matrix",
                integrator="fixed_step_krylov",
                max_steps=4,
            ),
        )
        .result()
    )
    report = result.metadata["noise_report"]

    ideal = LocalBackend(seed=104, analog_time_steps=4).run(program, shots=32).result()

    payload = {
        "track": "hybrid_researcher",
        "level": "advanced",
        "lesson": "physical_noise",
        "facts": {
            "method": result.metadata["simulation_execution_config"]["method"],
            "truthfulness": result.metadata["simulation_truthfulness"],
            "channel_types": report["applied_channel_types"],
            "noise_report_hash_present": len(result.metadata["noise_report_hash"])
            == 64,
            "probabilities": result.probabilities,
            "ideal_probabilities": ideal.probabilities,
            "physical_application_count": report["physical_application_count"],
            "measurement_application_count": report["measurement_application_count"],
            "counts_total": sum(result.counts.values()),
        },
        "boundaries": {
            "hardware_execution": False,
            "cloud_execution": False,
            "network_accessed": False,
            "credentials_loaded": False,
        },
    }
    print(json.dumps(payload, sort_keys=True))


if __name__ == "__main__":
    main()

Download the full script

python examples/user/tracks/hybrid_researcher/04_advanced_physical_noise_en.py
{
  "boundaries": {
    "cloud_execution": false,
    "credentials_loaded": false,
    "hardware_execution": false,
    "network_accessed": false
  },
  "facts": {
    "channel_types": [
      "dephasing"
    ],
    "counts_total": 32,
    "ideal_probabilities": {
      "0": 1.0,
      "1": 0.0
    },
    "measurement_application_count": 0,
    "method": "density_matrix",
    "noise_report_hash_present": true,
    "physical_application_count": 1,
    "probabilities": {
      "0": 0.9852227667742534,
      "1": 0.014777233225746552
    },
    "truthfulness": "physical_state_evolution"
  },
  "lesson": "physical_noise",
  "level": "advanced",
  "track": "hybrid_researcher"
}

Compare ideal and noisy state probabilities before interpreting finite-shot counts. Readout errors change measurement records, so their frequency changes should not be described as state evolution. More shots reduce measurement fluctuations without removing physical noise. More trajectories address trajectory-estimation error.

With method="auto", the executor chooses a method based on noise and resources. Request density-matrix execution explicitly for an exact noisy reference and allow unsupported combinations to fail validation. Algorithm interfaces can impose tighter restrictions than the general backend; noisy exact VQE objectives, for example, require density-matrix execution.

See NoiseChannel for channel parameters and NoiseModel for combinations. The noisy Hybrid project compares several error sources. Legacy NoiseModelIR and deterministic counts postprocessing are not the physical evolution described here.

中文版

SDK 1.0.8a · `8b227bff`