symop.modes.envelopes.filtered

Spectrally filtered envelopes.

This module defines FilteredEnvelope, an envelope constructed by multiplying a base spectrum with a transfer function in the frequency domain. The resulting time-domain field is obtained via FFT-based inverse transformation and interpolation.

It also provides numerical helpers for spectral interpolation, linear phase (delay) estimation, and window selection for frequency-domain quadrature.

Classes

FilteredEnvelope(base, transfer[, n_fft, ...])

Envelope defined by spectral multiplication.

class FilteredEnvelope(base: TimeFrequencyEnvelope, transfer: TransferFunction, n_fft: int = 32768, w_span_sigma: float = 12.0) None

Bases: BaseEnvelope

Envelope defined by spectral multiplication.

Given an input spectrum \(Z_\mathrm{in}(\omega)\) and a transfer function \(H(\omega)\), the output spectrum is

\[Z_\mathrm{out}(\omega) = H(\omega)\,Z_\mathrm{in}(\omega).\]

The time-domain field \(\zeta_\mathrm{out}(t)\) is obtained numerically using an FFT-based inverse transform on a fixed grid, followed by complex interpolation.

Notes

  • This class is intended to make basis changes “real”: generic overlaps may call time_eval() via numeric fallback, so time_eval() should be coherent with freq_eval().

  • The absolute Fourier convention is not critical as long as internal operations (overlap, plotting) are consistent. If you later care about absolute scaling, unify the convention across all envelopes.

  • Instances are treated as mode descriptors and are numerically normalized:

freq_eval() applies a cached real scale factor chosen so that

\[\frac{1}{2\pi}\int |Z(\omega)|^2\,d\omega \approx 1\]

where the integral is approximated by trapezoidal quadrature on an automatically chosen finite frequency window. The normalization is therefore subject to window truncation and discretization error.

Parameters:
  • base (TimeFrequencyEnvelope)

  • transfer (TransferFunction)

  • n_fft (int)

  • w_span_sigma (float)

_abc_impl = <_abc._abc_data object>
_freq_eval_raw(w: ndarray[tuple[Any, ...], dtype[float64]]) ndarray[tuple[Any, ...], dtype[complex128]] | ndarray[tuple[Any, ...], dtype[float64]]

Evaluate the unnormalized filtered spectrum.

Given a base spectrum \(Z_{\mathrm{in}}(\omega)\) and transfer \(H(\omega)\), this returns

\[Z_{\mathrm{raw}}(\omega) = H(\omega)\,Z_{\mathrm{in}}(\omega).\]

This method intentionally does not apply the mode-normalization factor. Use freq_eval() for the normalized spectrum.

Parameters:

w (ndarray[tuple[Any, ...], dtype[double]]) – Angular-frequency grid.

Returns:

Complex samples of \(Z_{\mathrm{raw}}(\omega)\).

Return type:

RCArray

property _norm2: float

Return the squared mode norm of the unnormalized filtered spectrum.

We treat envelopes as mode descriptors, so they are expected to be normalized such that

\[\langle \zeta, \zeta \rangle = 1.\]

Using the package Fourier convention, the overlap can be evaluated in the frequency domain as

\[\langle \zeta, \zeta \rangle = \frac{1}{2\pi}\int_{-\infty}^{\infty} |Z(\omega)|^2\,d\omega.\]

This method computes that quantity for the raw filtered spectrum

\[Z_{\mathrm{raw}}(\omega) = H(\omega)\,Z_{\mathrm{in}}(\omega),\]

on a finite window and returns a positive finite scalar.

Notes

  • The window is chosen from spectral hints of the base envelope.

  • The returned value is cached, so the normalization cost is paid once.

property _norm_scale: float

Return the scalar that normalizes the filtered envelope.

If

\[N^2 = \frac{1}{2\pi}\int |Z_{\mathrm{raw}}(\omega)|^2\,d\omega,\]

then the normalized spectrum is

\[Z(\omega) = \frac{1}{N}\,Z_{\mathrm{raw}}(\omega).\]

This method returns \(1/N\).

approx_signature(*, decimals: int = 12, ignore_global_phase: bool = False) tuple[object, ...]

Approximate signature with rounded base-envelope parameters.

Parameters:
  • decimals (int) – Number of decimals for rounding in the base envelope’s approx signature.

  • ignore_global_phase (bool) – If True, request that the base envelope ignore its global phase (if supported).

Returns:

Approximate signature tuple.

Return type:

Signature

base: TimeFrequencyEnvelope
center_and_scale() tuple[float, float]

Estimate a time-domain center and scale from the filtered spectrum.

The estimate is invariant under global real rescaling of the spectrum, so it uses the raw spectrum \(Z_{\mathrm{raw}}(\omega)\).

This computes a temporary time-domain signal via an FFT-based inverse transform, then estimates the mean and standard deviation of \(|\zeta(t)|^2\).

Returns:

  • center – Center time.

  • scale – Characteristic scale.

Return type:

tuple[float, float]

delayed(dt: float) Self

Return a delayed copy of this filtered envelope.

Parameters:

dt (float) – Delay applied to the base envelope.

Returns:

Delayed filtered envelope.

Return type:

FilteredEnvelope

property eta: float

Power transmissivity of the raw filtered mode.

Defined as the squared norm of the unnormalized filtered spectrum:

\[\eta = \frac{1}{2\pi}\int |H(\omega)|^2 |Z_{\mathrm{in}}(\omega)|^2 d\omega.\]

This is computed numerically on the same finite window used for normalization.

freq_eval(w: ndarray[tuple[Any, ...], dtype[float64]]) ndarray[tuple[Any, ...], dtype[complex128]] | ndarray[tuple[Any, ...], dtype[float64]]

Evaluate the normalized filtered spectrum \(Z(\omega)\).

The filtered (raw) spectrum is

\[Z_{\mathrm{raw}}(\omega) = H(\omega)\,Z_{\mathrm{in}}(\omega).\]

We then normalize to enforce the mode condition

\[\frac{1}{2\pi}\int_{-\infty}^{\infty} |Z(\omega)|^2\,d\omega = 1,\]

by applying a global real scale factor

\[Z(\omega) = \alpha\,Z_{\mathrm{raw}}(\omega), \qquad \alpha = \frac{1}{\sqrt{\frac{1}{2\pi}\int |Z_{\mathrm{raw}}(\omega)|^2\,d\omega}}.\]
Parameters:

w (ndarray[tuple[Any, ...], dtype[double]]) – Angular-frequency grid.

Returns:

Complex samples of the normalized spectrum.

Return type:

RCArray

n_fft: int = 32768
overlap_with_generic(other: TimeFrequencyEnvelope) complex

Compute overlap using a frequency-domain quadrature.

This approximates

\[\langle \zeta_1, \zeta_2 \rangle \;\approx\; \frac{1}{2\pi}\int \overline{Z_1(\omega)}\,Z_2(\omega)\,d\omega,\]

using a finite window and trapezoidal quadrature.

Parameters:

other (TimeFrequencyEnvelope) – Envelope to overlap with.

Returns:

Approximate overlap.

Return type:

complex

phased(dphi: float) Self

Return a phased copy of this filtered envelope.

Parameters:

dphi (float) – Phase increment applied to the base envelope.

Returns:

Phased filtered envelope.

Return type:

FilteredEnvelope

property signature: tuple[object, ...]

Stable signature for caching/comparison.

time_eval(t: ndarray[tuple[Any, ...], dtype[float64]]) ndarray[tuple[Any, ...], dtype[complex128]] | ndarray[tuple[Any, ...], dtype[float64]]

Evaluate the filtered time-domain field \(\zeta_\mathrm{out}(t)\).

The output spectrum is constructed as

\[Z(\omega) = \alpha\,H(\omega)\,Z_{\mathrm{in}}(\omega),\]

where \(\alpha\) is a global real normalization chosen such that \(\langle \zeta, \zeta \rangle = 1\).

The method: 1. Builds a centered frequency grid around \(\omega_0\). 2. Samples \(Z(\omega)\) on that grid. 3. Applies an FFT-based inverse transform to obtain a centered time grid. 4. Re-applies the carrier \(e^{i\omega_0 t}\) and interpolates onto t.

Parameters:

t (ndarray[tuple[Any, ...], dtype[double]]) – Time grid.

Returns:

Complex samples of \(\zeta_\mathrm{out}(t)\).

Return type:

RCArray

transfer: TransferFunction
w_span_sigma: float = 12.0
_estimate_spectral_window(env: TimeFrequencyEnvelope, *, w0_fallback: float, sigma_w_fallback: float) tuple[float, float]

Estimate a reasonable spectral window center and width for FFT-based evaluation.

This prefers envelope metadata if available: - \(\omega_0\) from env.omega0 (if present) - a spectral width hint from env.omega_sigma (if present)

Parameters:
  • env (TimeFrequencyEnvelope) – Envelope providing (optional) metadata.

  • w0_fallback (float) – Fallback center frequency if the envelope does not provide omega0.

  • sigma_w_fallback (float) – Fallback width hint if the envelope does not provide any width metadata.

Returns:

Center and width hint for building a spectral window.

Return type:

(w0, sigma_w)

_fit_linear_phase_delay(w_rel: ndarray, Z: ndarray, *, frac: float = 0.2) float

Estimate a time delay from the linear phase of a spectrum.

If, locally around \(\omega_\mathrm{rel}=0\), the spectrum behaves like

\[Z(\omega_\mathrm{rel}) \approx A(\omega_\mathrm{rel})\, e^{-i\omega_\mathrm{rel} t_0},\]

then the unwrapped phase satisfies \(\phi(\omega_\mathrm{rel}) \approx -t_0\,\omega_\mathrm{rel} + b\). This function estimates \(t_0\) from a least-squares fit of the phase slope.

Parameters:
  • w_rel (ndarray) – Relative angular-frequency samples centered near 0.

  • Z (ndarray) – Complex spectrum values at w_rel.

  • frac (float) – Fraction of the central bins used for fitting (default: 0.2).

Returns:

Estimated delay \(t_0\). Returns 0.0 if the fit is ill-conditioned.

Return type:

float

_interp_complex_1d(x: ndarray[tuple[Any, ...], dtype[float64]], xp: ndarray[tuple[Any, ...], dtype[float64]], fp: ndarray[tuple[Any, ...], dtype[complex128]] | ndarray[tuple[Any, ...], dtype[float64]]) ndarray[tuple[Any, ...], dtype[complex128]] | ndarray[tuple[Any, ...], dtype[float64]]

Interpolate a complex-valued 1D function on a real grid.

This interpolates real and imaginary parts separately using numpy.interp(), with values outside the interpolation domain set to zero.

Parameters:
Returns:

Interpolated complex samples at x.

Return type:

RCArray

_remove_linear_phase(w_rel: ndarray, Z: ndarray, t0: float) ndarray

Remove a linear phase ramp corresponding to a delay.

This multiplies

\[Z(\omega_\mathrm{rel}) \leftarrow Z(\omega_\mathrm{rel})\,e^{+i\omega_\mathrm{rel} t_0}.\]
Parameters:
  • w_rel (ndarray) – Relative angular-frequency samples.

  • Z (ndarray) – Complex spectrum values.

  • t0 (float) – Delay estimate.

Returns:

Phase-corrected spectrum.

Return type:

ndarray