Skip to content

Fix single-qubit depolarizing noise channel#352

Merged
hayekr merged 5 commits into
sequence-toolbox:RnDfrom
HasanTasdiq:fix/single-qubit-depolarizing-noise
May 27, 2026
Merged

Fix single-qubit depolarizing noise channel#352
hayekr merged 5 commits into
sequence-toolbox:RnDfrom
HasanTasdiq:fix/single-qubit-depolarizing-noise

Conversation

@HasanTasdiq

Copy link
Copy Markdown
Contributor

Summary

Noise.apply_depolarizing_noise (in sequence/utils/noise.py) is documented to support 1 or 2 target qubits, but it hardcodes the Pauli index combinations as 2-qubit tuples:

idx_tuples = [(i, j) for i in range(4) for j in range(4)]

For the single-qubit case (k = 1) only idx_tuple[0] is used, which produces two problems:

  • Spurious identity terms: the tuples (0, 1), (0, 2), (0, 3) map the target qubit (and every other qubit) to I, so the full identity operator is added to the Pauli sum three times.
  • Wrong normalization: the channel is divided by len(pauli_ops) = 15 instead of 4^1 - 1 = 3.

As a result the single-qubit depolarizing channel is mathematically incorrect. For example, applying p = 0.3 to |0><0|:

output
current code diag(0.84, 0.16)
correct channel (1-p)ρ + (p/3)(XρX + YρY + ZρZ) diag(0.8, 0.2)

Fix

Generate the Pauli index tuples from the actual number of target qubits:

idx_tuples = itertools.product(range(4), repeat=k)
  • The two-qubit path is unchanged: 16 tuples, identity excluded → 15 operators (verified identical output to the previous implementation).
  • The single-qubit path now yields the correct 3 operators (X, Y, Z) and matches the standard depolarizing channel.

Test plan

  • Added test_apply_depolarizing_noise_single_qubit comparing the k=1 output against the standard single-qubit depolarizing channel.
  • Confirmed the new test fails on the current code and passes with the fix.
  • Existing test_apply_depolarizing_noise (two-qubit) still passes — the two-qubit path is unaffected.

🤖 Generated with Claude Code

Noise.apply_depolarizing_noise hardcoded the Pauli index combinations as
2-qubit tuples ([(i, j) for i in range(4) for j in range(4)]). For the
documented single-qubit case (k=1) this had two effects:

- spurious full-identity operators were included in the Pauli sum (the
  tuples (0, 1), (0, 2), (0, 3) map every qubit to I), and
- the normalization used 15 operators instead of 3.

The result was a mathematically incorrect channel: applying p=0.3 to
|0><0| returned diag(0.84, 0.16) instead of the correct diag(0.8, 0.2).

Generate the index tuples from the actual number of target qubits with
itertools.product(range(4), repeat=k). The two-qubit path is unchanged
(15 operators); the single-qubit path now matches the standard
depolarizing channel. Adds a regression test for k=1.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@hayekr hayekr changed the base branch from master to RnD May 21, 2026 14:59

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Fixes Noise.apply_depolarizing_noise so the single-qubit (k=1) depolarizing channel uses the correct set of Pauli operators and normalization, matching the standard definition while keeping the two-qubit (k=2) behavior unchanged.

Changes:

  • Generate Pauli index tuples based on the actual number of target qubits via itertools.product(..., repeat=k) (instead of hardcoding 2-qubit tuples).
  • Add a regression test verifying the k=1 depolarizing channel matches the standard (1-p)ρ + (p/3)(XρX + YρY + ZρZ) behavior.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
sequence/utils/noise.py Fixes Pauli operator enumeration/normalization for k=1 by generating index tuples with repeat=k.
tests/utils/test_noise.py Adds a single-qubit depolarizing regression test comparing against a manual reference implementation.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@caitaozhan caitaozhan left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks good!

@hayekr hayekr merged commit d3db78a into sequence-toolbox:RnD May 27, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants