Skip to content

Add noise model API for Stim circuit compilation#160

Open
masa10-f wants to merge 14 commits intomasterfrom
feature/stim-noise-model
Open

Add noise model API for Stim circuit compilation#160
masa10-f wants to merge 14 commits intomasterfrom
feature/stim-noise-model

Conversation

@masa10-f
Copy link
Collaborator

@masa10-f masa10-f commented Feb 6, 2026

Summary

  • Add event-based NoiseModel API for injecting custom noise into Stim circuits during pattern compilation
  • Add typed NoiseOp dataclasses (PauliChannel1, PauliChannel2, HeraldedPauliChannel1, HeraldedErase, RawStimOp, MeasurementFlip)
  • Add built-in DepolarizingNoiseModel and MeasurementFlipNoiseModel implementations
  • Add depolarize1_probs() and depolarize2_probs() utility functions
  • Extend stim_compile() to accept noise_models parameter with Sequence[NoiseModel] support

Test plan

  • All existing tests pass
  • New tests for noise model API (71 tests in test_noise_model.py)
  • Updated stim_compiler tests to use new NoiseModel API
  • Sphinx documentation builds without warnings
  • ruff, mypy, pyright checks pass

🤖 Generated with Claude Code

masa10-f and others added 10 commits February 2, 2026 18:17
Enhance noise_model.py with detailed NumPy-style docstrings including:
- Module-level documentation with usage examples
- NoiseKind enum descriptions for each event type
- NoiseOp and NoiseEvent parameter documentation with examples
- NoiseModel abstract class with comprehensive examples and notes

Add Sphinx documentation:
- Create docs/source/noise_model.rst for API reference
- Add noise_model to module reference in references.rst

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…odel]

- Replace string-based noise API with typed NoiseOp dataclasses
  (PauliChannel1, PauliChannel2, HeraldedPauliChannel1, HeraldedErase, RawStimOp)
- Add typed event classes (PrepareEvent, EntangleEvent, MeasureEvent, IdleEvent)
  with NodeInfo and Coordinate for position-dependent noise models
- Change NoiseModel method return type from Iterable[NoiseOp] to Sequence[NoiseOp]
  for covariance (allows subclasses to return Sequence[PauliChannel1] etc.)
- Update stim_compile to accept Sequence[NoiseModel] instead of single NoiseModel
  for composing multiple independent noise sources
- Add NoisePlacement enum (AUTO, BEFORE, AFTER) for controlling noise insertion
- Add comprehensive tests for noise_model module

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update module docstrings to use the standard "This module provides:"
format with a list of public exports. Replace all double backticks
with single backticks for inline code references to match the project's
documentation style conventions.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use double backticks for non-Python references (Stim instruction names,
parameter names, example values) and proper Sphinx roles (:data:) for
module constants. Single backticks remain only for Python object cross-
references.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add utility function that creates a probability dict with all 15 Pauli
pairs having equal probability p/15. Update the module docstring example
to use this utility for proper 2-qubit depolarizing noise instead of
the simplified ZZ-only version.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add utility function that creates px, py, pz probabilities each set
to p/3 for single-qubit depolarizing channel. Update the module
docstring example to use both depolarize1_probs and depolarize2_probs.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace old parameter-based noise API with the new NoiseModel classes:
- Use DepolarizingNoiseModel instead of p_depol_after_clifford
- Use MeasurementFlipNoiseModel instead of p_before_meas_flip

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@codecov
Copy link

codecov bot commented Feb 6, 2026

Codecov Report

❌ Patch coverage is 96.34146% with 15 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.20%. Comparing base (ad07ddf) to head (1347640).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #160      +/-   ##
==========================================
+ Coverage   83.65%   85.20%   +1.54%     
==========================================
  Files          21       22       +1     
  Lines        2313     2650     +337     
  Branches      416      456      +40     
==========================================
+ Hits         1935     2258     +323     
- Misses        287      293       +6     
- Partials       91       99       +8     
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a571d0fef9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 190 to 191
if self._noise_models:
return self._noise_models[0].default_placement(event)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Apply AUTO placement using each model's default

The compiler flattens ops from all noise_models, but AUTO placement is resolved with only self._noise_models[0].default_placement(event). This means any later model that overrides default_placement has its AUTO ops inserted on the wrong side of the event (for example, AFTER-intended measurement noise can be emitted BEFORE), producing incorrect circuits whenever multiple models are combined.

Useful? React with 👍 / 👎.

Comment on lines 136 to 137
if isinstance(op, MeasurementFlip) and op.target == node:
meas_flip_p = max(meas_flip_p, op.p)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Combine MeasurementFlip contributions instead of taking max

When more than one model emits MeasurementFlip for the same measurement, this logic keeps only the maximum probability and drops the rest. Because stim_compile explicitly supports multiple noise models, this underestimates measurement noise in combined-model runs (e.g., two independent flip sources do not both contribute), so simulation error rates are systematically too low.

Useful? React with 👍 / 👎.

@masa10-f masa10-f self-assigned this Feb 8, 2026
@masa10-f masa10-f added the enhancement New feature or request label Feb 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant