Skip to content

Draft - Photon error mitigation - #771

Draft
anthonyrtw wants to merge 4 commits into
Quandela:developfrom
anthonyrtw:photon-error-mitigation
Draft

Draft - Photon error mitigation#771
anthonyrtw wants to merge 4 commits into
Quandela:developfrom
anthonyrtw:photon-error-mitigation

Conversation

@anthonyrtw

@anthonyrtw anthonyrtw commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Add Photon Error Mitigation

Description

Adds PhotonErrorMitigation, a new mitigation layer for correcting statistics for photon distinguishability and g2.

Extra features

  • Extent of mitigation determined by order parameter - which indicates the level of noise considered under 'Orthogonal Bad Bits' partial distinguishability model.
  • order may be defined as int or also a Callable - so that it may be specified more abstractly in planned ErrorMitigationFactory.
  • PhotonErrorMitigation.overhead(input_state: FockState) method so that one may determine how many extra jobs are required to perform mitigation based on the specified order.

Notes

  • PhotonErrorMitigation._parse_results expects that the input results reflects the compiled Experiment with the full QPU mode count.
  • PhotonErrorMitigation._parse_results also expects that input results are lossy & contain vacuum counts irrespective of the min_detected_photon_filter.
  • High mitigation orders may be significantly exorbitant in overhead.

To do

  • Establish a method of obtaining the PNR detection pattern for local & remote computations.

@Aubaert Aubaert 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.

Hello, thanks for the draft PR, we'll do the modifications on our side

If a callable is given, it is evaluated on the input photon number.
"""

def __init__(self, order: int | Callable[[int], int]):

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.

dict at best (Callable is not serializable)

"""
states = set()
for current_order in range(order + 1):
partition = _generate_obb_partition(input_state, current_order)

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.

This seems very inefficient


samples = self._split_integer(
computation.parameters.get(KEY_MAX_SAMPLES),
ratios,

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.

The ratios might benefit to be different for samples and shots

sub_computations.append(comp)

# Save some settings for _parse_results
self._settings[computation] = (

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.

This class should be const

input_state=state,
samples=samples[i],
shots=shots[i],
job_name=f"{computation.job_name} pem {i + 1}",

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.

Abbreviation ? Start at 0 ?

raise ValueError("order must be an integer greater than 0.")

if order > 4:
warnings.warn(

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.

perceval.get_logger()

for _ in range(partition_counts[i])
]

if len(corrections) != len(weights_hom):

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.

Remove


# 1 * dist makes a copy to avoid in-place mutation
convolved = BSDistribution.list_tensor_product([
sum((1 * dist for dist in signal_dists), BSDistribution()),

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.

No need for copies

noise = noise or NoiseModel()
g2 = noise.g2

if g2 > .5:

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.

This should be done earlier, at job duplication

transmittance = noise.transmittance
assert transmittance > 0, "Improper calibration has led to zero transmittance."

norm = sum(transmittance ** (-state.n / 2) for state in states)

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.

Ok, I have no idea why this ratio

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.

2 participants