Source code for quchip.engine.reference

"""Reference-plane transforms applied outside the Markovian core."""

from __future__ import annotations

from collections.abc import Callable, Mapping
from dataclasses import dataclass
from typing import Any

import numpy as np

from quchip.utils.constants import TWO_PI
from quchip.utils.jax_utils import contains_tracer, maybe_concrete_scalar, select_array_module


[docs] @dataclass(frozen=True) class ReferenceDelay: """One reference section with propagation duration ``duration`` ns.""" label: str duration: Any def __post_init__(self) -> None: concrete = maybe_concrete_scalar(self.duration) if concrete is not None and concrete < 0: raise ValueError(f"Delay {self.label!r} duration must be non-negative, got {self.duration}.") @property def tracked_values(self) -> tuple[Any, ...]: """Return the values that can carry JAX tracers.""" return (self.duration,)
[docs] @dataclass(frozen=True) class ReferenceFilter: """One passive filter reference section and its tracked parameters. ``transfer(frequency, **parameters)`` accepts a scalar or array frequency in GHz and returns a complex amplitude transfer. """ label: str transfer: Callable[..., Any] parameters: Mapping[str, Any] loss_occupation: Any = None @property def tracked_values(self) -> tuple[Any, ...]: """Return the values that can carry JAX tracers.""" return (*self.parameters.values(), self.loss_occupation) def __call__(self, frequency: Any) -> Any: """Evaluate the complex transfer at ``frequency`` in GHz. ``frequency`` can be scalar or array-valued. Reject a concrete result whose magnitude is more than one. Do not concretize traced results for this check. """ value = self.transfer(frequency, **self.parameters) if not contains_tracer(value) and np.any(np.abs(np.asarray(value)) > 1.0 + 1e-12): raise ValueError( f"Filter {self.label!r} must be passive, but its evaluated transfer has |H| > 1. " "Gain requires an amplifier section." ) return value
[docs] @dataclass(frozen=True) class ReferenceAmplifier: """A phase-preserving output-line amplifier. ``gain`` is the power gain ``G``. ``added_noise`` is the input-referred symmetrized noise ``n_add`` in quanta, with the quantum floor ``(1 - 1/G) / 2``. """ label: str gain: Any added_noise: Any def __post_init__(self) -> None: gain = maybe_concrete_scalar(self.gain) noise = maybe_concrete_scalar(self.added_noise) if gain is not None and gain < 1.0: raise ValueError(f"Amplifier {self.label!r} power gain must be at least 1; got {self.gain}.") if gain is not None and noise is not None: floor = (1.0 - 1.0 / gain) / 2.0 if noise < floor - 1e-12: raise ValueError( f"Amplifier {self.label!r} added_noise={self.added_noise} is below the " f"phase-preserving quantum limit {floor} input-referred symmetrized quanta " f"for gain={self.gain}." ) @property def tracked_values(self) -> tuple[Any, ...]: """Return the values that can carry JAX tracers.""" return (self.gain, self.added_noise) @property def added_noise_density(self) -> Any: """Return the output-referred normally ordered added noise density. For power gain ``G`` and input-referred noise ``n_add``, the density is ``G n_add + (G - 1) / 2``. """ return self.gain * self.added_noise + (self.gain - 1.0) / 2.0
[docs] @dataclass(frozen=True) class ReferenceLoss: """One directed traversal of a matched passive output-line component.""" label: str eta: Any occupation: Any = None @property def tracked_values(self) -> tuple[Any, ...]: """Return numerical source and transmission parameters.""" return (self.eta, self.occupation)
ReferenceElement = ReferenceDelay | ReferenceFilter | ReferenceAmplifier | ReferenceLoss
[docs] @dataclass(frozen=True) class ReferencePlane: """Inbound and outbound reference runs for one exposure, in propagation order.""" inbound: tuple[ReferenceElement, ...] = () outbound: tuple[ReferenceElement, ...] = ()
[docs] @dataclass(frozen=True) class FieldChannel: """Field metadata shared by mode-space and operator-space acquisition.""" key: str reference: ReferencePlane input_occupation: Any = None
def _array_module(elements: tuple[ReferenceElement, ...], frequency: Any, xp: Any) -> Any: """Return ``xp``, or the module matching traced content in ``elements`` and ``frequency``.""" if xp is not None: return xp values: list[Any] = [frequency] for element in elements: values.extend(element.tracked_values) return select_array_module(contains_tracer(tuple(values)))
[docs] def cw_transfer(elements: tuple[ReferenceElement, ...], frequency: Any, xp: Any = None) -> Any: """Return the exact continuous-wave transfer of one reference leg. At ``frequency`` in GHz, each delay contributes ``exp(+i 2π frequency duration)`` and each filter contributes ``H(frequency)``. Delay durations are in ns. """ xp = _array_module(elements, frequency, xp) transfer = xp.asarray(1.0 + 0.0j) for element in elements: if isinstance(element, ReferenceDelay): transfer = transfer * xp.exp( 1j * TWO_PI * xp.asarray(frequency) * xp.asarray(element.duration) ) elif isinstance(element, ReferenceFilter): transfer = transfer * xp.asarray(element(frequency)) elif isinstance(element, ReferenceLoss): transfer = transfer * xp.sqrt(xp.asarray(element.eta)) else: transfer = transfer * xp.sqrt(xp.asarray(element.gain)) return transfer
[docs] def carrier_transfer(elements: tuple[ReferenceElement, ...], carrier: Any, xp: Any = None) -> Any: """Return the narrowband filter transfer of one reference leg. Evaluate every filter at ``carrier`` in GHz. Ignore delays because transient propagation applies them as time shifts. """ xp = _array_module(elements, carrier, xp) flat = tuple(element for element in elements if not isinstance(element, ReferenceDelay)) return cw_transfer(flat, carrier, xp)
[docs] def noise_contributions(elements: tuple[ReferenceElement, ...], frequency: Any, xp: Any = None) -> dict[str, Any]: """Return the chain's output-referred normally ordered added noise density. At ``frequency`` in GHz, walk ``elements`` in propagation order. A filter applies ``N <- |H(f)|^2 N``. An amplifier applies ``N <- G N + G n_add + (G - 1) / 2``. """ xp = _array_module(elements, frequency, xp) contributions: dict[str, Any] = {} for element in elements: if isinstance(element, ReferenceDelay): continue if isinstance(element, ReferenceAmplifier): gain, added = element.gain, element.added_noise_density else: gain = (xp.abs(xp.asarray(element(frequency))) ** 2 if isinstance(element, ReferenceFilter) else element.eta) occupation = element.loss_occupation if isinstance(element, ReferenceFilter) else element.occupation added = (1 - gain) * (0.0 if occupation is None else occupation) contributions = {label: gain * value for label, value in contributions.items()} contributions[element.label] = xp.zeros_like(xp.asarray(frequency, dtype=float)) + added return contributions
[docs] def noise_density(elements: tuple[ReferenceElement, ...], frequency: Any, xp: Any = None) -> Any: """Return total normally ordered added noise from the source-wise propagation.""" xp = _array_module(elements, frequency, xp) return sum(noise_contributions(elements, frequency, xp).values(), xp.zeros_like(xp.asarray(frequency, dtype=float)))
[docs] def noise_colors(elements: tuple[ReferenceElement, ...]) -> dict[str, bool]: """Mark sources whose emission passes through a frequency-dependent filter.""" colored = False sources = {} for element in reversed(elements): colored = colored or isinstance(element, ReferenceFilter) if not isinstance(element, ReferenceDelay): sources[element.label] = colored return sources
[docs] def has_colored_noise(elements: tuple[ReferenceElement, ...]) -> bool: """Return whether a potentially occupied source emits colored noise.""" colors = noise_colors(elements) for element in elements: if isinstance(element, ReferenceDelay) or not colors[element.label]: continue if isinstance(element, ReferenceLoss) and maybe_concrete_scalar(element.eta) == 1: continue occupation = source_occupation(element) if occupation is not None and maybe_concrete_scalar(occupation) != 0: return True return False
[docs] def source_occupation(element: ReferenceElement) -> Any: """Return a declared source occupation, or None for implicit vacuum.""" if isinstance(element, ReferenceDelay): return None if isinstance(element, ReferenceAmplifier): return element.added_noise_density return element.loss_occupation if isinstance(element, ReferenceFilter) else element.occupation
[docs] def has_filter(elements: tuple[ReferenceElement, ...]) -> bool: """Return whether a reference leg contains a filter section.""" return any(isinstance(element, ReferenceFilter) for element in elements)
[docs] def has_amplifier(elements: tuple[ReferenceElement, ...]) -> bool: """Return ``True`` when ``elements`` contains an amplifier.""" return any(isinstance(element, ReferenceAmplifier) for element in elements)
[docs] def time_shift(elements: tuple[ReferenceElement, ...]) -> Any: """Return the summed delay duration of one reference leg, in ns.""" return sum((element.duration for element in elements if isinstance(element, ReferenceDelay)), 0.0)