spharapy.spectral_filters: SPHARA Spectral Filter Design

Spectral filter design utilities for SPHARA-based spatial filtering.

This module provides small helper functions to design transfer functions in the SPHARA spectral domain. The resulting arrays are typically passed to the spharapy.spharafilter.SpharaFilter class as the specification argument, i.e. as a diagonal transfer vector in the SPHARA basis.

The design functions are purely spectral (they only see the frequency grid f and return a real-valued magnitude response H(f)). They do not depend on any mesh or SPHARA basis object and therefore can be used for arbitrary SPHARA spectra.

Main use cases

  • Ideal (brick-wall) filters

  • Gaussian filters (amplitude-based dB specification at the cutoff)

  • Butterworth filters (order N and amplitude-based dB specification)

For convenience, each family provides

  • low-pass

  • high-pass

  • band-pass

variants, where the high-pass and band-pass functions are built from the low-pass prototypes.

All filter families support both

  • absolute cutoffs in the same units as the SPHARA frequency axis, and

  • relative cutoffs expressed as fractions of max(|f|) via relative=True.

Notes

The input f is typically the vector of SPHARA “spatial frequencies” (e.g. \(\sqrt{\boldsymbol{\tau}}\) for FEM-based bases) ordered in the same way as the columns of the SPHARA basis used by spharapy.spharafilter.SpharaFilter.

Examples

Design an ideal SPHARA low-pass and apply it via spharapy.spharafilter.SpharaFilter:

import numpy as np
import spharapy.spharafilter as sf
from spharapy.spectral_filters import transfer_func_ideal_lowpass

# frequencies obtained from a SPHARA basis (e.g. FEM-based)
f = np.linspace(0.0, 50.0, 256)

# design an ideal low-pass with cutoff at 10 spatial frequency units
h_lp = transfer_func_ideal_lowpass(f, fc=10.0)

# use as "specification" in a SpharaFilter (example: simple mesh)
# sphara_filter = sf.SpharaFilter(trimesh, mode="fem", specification=h_lp)
spharapy.spectral_filters.as_bandpass(h_lowpass_low, h_lowpass_high)[source]

Construct a band-pass transfer function from two low-pass curves.

Given two low-pass curves \(H_\text{low}(f; f_c^\text{low})\) and \(H_\text{low}(f; f_c^\text{high})\) with \(f_c^\text{high} \ge f_c^\text{low}\), the band-pass is defined as

\[H_\text{bp}(f) = H_\text{low}(f; f_c^\text{high}) - H_\text{low}(f; f_c^\text{low}).\]
Parameters:
  • h_lowpass_low (ArrayLike) – Low-pass curve corresponding to the lower cutoff.

  • h_lowpass_high (ArrayLike) – Low-pass curve corresponding to the upper cutoff. Must have the same shape as h_lowpass_low.

Returns:

Band-pass transfer function. The result has the same shape as the input curves.

Return type:

FloatArray

Raises:

ValueError – If h_lowpass_low and h_lowpass_high do not have the same shape.

Examples

>>> import numpy as np
>>> from spharapy.spectral_filters import as_bandpass
>>> lo = np.array([0., 0.3, 1. ])
>>> hi = np.array([0., 1. , 1. ])
>>> as_bandpass(lo, hi)
array([0. , 0.7, 0. ])
spharapy.spectral_filters.as_highpass(h_lowpass)[source]

Convert a low-pass transfer function into a high-pass transfer function.

For a given low-pass magnitude response \(H_\text{low}(f)\), the corresponding high-pass is defined as

\[H_\text{high}(f) = 1 - H_\text{low}(f).\]
Parameters:

h_lowpass (ArrayLike) – Low-pass transfer function values. Can be any array-like object convertible to a 1D or ND numpy.ndarray of float.

Returns:

High-pass transfer function values with the same shape as h_lowpass.

Return type:

FloatArray

Examples

>>> import numpy as np
>>> from spharapy.spectral_filters import as_highpass
>>> as_highpass(np.array([1., 0.5, 0.]))
array([0. , 0.5, 1. ])
spharapy.spectral_filters.transfer_func_butterworth_bandpass(f, low, high, order, dB=-3.0, *, relative=False)[source]

Butterworth band-pass filter built from two Butterworth low-passes.

Parameters:
  • f (ArrayLike) – SPHARA frequency axis.

  • low (float) – Lower cutoff (absolute or relative).

  • high (float) – Upper cutoff (absolute or relative). Must satisfy high > low.

  • order (int) – Butterworth filter order.

  • dB (float, optional) – Desired attenuation (amplitude dB) at the cutoffs.

  • relative (bool, optional) – If True, interpret low and high as fractions of max(|f|).

Returns:

Butterworth band-pass transfer function values.

Return type:

FloatArray

spharapy.spectral_filters.transfer_func_butterworth_highpass(f, fc, order, dB=-3.0, *, relative=False)[source]

Butterworth high-pass filter computed as the complement of a low-pass.

Parameters:
  • f (ArrayLike) – SPHARA frequency axis.

  • fc (float) – Cutoff frequency.

  • order (int) – Butterworth filter order.

  • dB (float, optional) – Desired attenuation (amplitude dB) at the cutoff of the underlying low-pass.

  • relative (bool, optional) – If True, interpret fc as a fraction of max(|f|).

Returns:

Butterworth high-pass transfer function values.

Return type:

FloatArray

spharapy.spectral_filters.transfer_func_butterworth_lowpass(f, fc, order, dB=-3.0, *, relative=False)[source]

Butterworth low-pass filter of order N.

The generalized Butterworth magnitude response with amplitude-based dB specification at the cutoff is defined by

\[\begin{split}|H(f_c)| = 10^{\text{dB} / 20} = R,\\ \kappa = \frac{1}{R^2} - 1,\\ H(f) = \frac{1}{\sqrt{1 + \kappa (|f| / f_c)^{2N}}}.\end{split}\]
Parameters:
  • f (ArrayLike) – SPHARA frequency axis.

  • fc (float) – Cutoff frequency (absolute or relative).

  • order (int) – Butterworth order \(N\) (must be an integer >= 1).

  • dB (float, optional) – Desired attenuation (amplitude dB) at \(f = f_c\). Must be negative. For a classic half-power Butterworth cutoff, use dB -3.0103.

  • relative (bool, optional) – If True, interpret fc as a fraction of max(|f|).

Returns:

Butterworth low-pass transfer function values.

Return type:

FloatArray

Raises:

ValueError – If order is not a valid integer >= 1 or if dB is not a finite negative number.

Warns:

UserWarning – If the cutoff lies outside the SPHARA frequency range.

Examples

>>> import numpy as np
>>> from spharapy.spectral_filters import transfer_func_butterworth_lowpass
>>> f = np.linspace(0.0, 1.0, 128)
>>> H = transfer_func_butterworth_lowpass(f, fc=0.25, order=4, dB=-3.0103)
>>> H.min() >= 0
True
spharapy.spectral_filters.transfer_func_gaussian_bandpass(f, low, high, dB=-3.0, *, relative=False)[source]

Gaussian band-pass filter built from two Gaussian low-passes.

The band-pass is defined as

\[H_\text{bp}(f) = H_\text{lp}(f; f_\text{high}) - H_\text{lp}(f; f_\text{low}),\]

where both low-passes share the same dB specification.

Parameters:
  • f (ArrayLike) – SPHARA frequency axis.

  • low (float) – Lower cutoff (absolute or relative).

  • high (float) – Upper cutoff (absolute or relative). Must satisfy high > low.

  • dB (float, optional) – Desired attenuation (amplitude dB) at the respective cutoffs.

  • relative (bool, optional) – If True, interpret low and high as fractions of max(|f|).

Returns:

Gaussian band-pass transfer function values.

Return type:

FloatArray

spharapy.spectral_filters.transfer_func_gaussian_highpass(f, fc, dB=-3.0, *, relative=False)[source]

Gaussian high-pass filter computed as the complement of a Gaussian low-pass.

Parameters:
  • f (ArrayLike) – SPHARA frequency axis.

  • fc (float) – Cutoff frequency (absolute or relative).

  • dB (float, optional) – Desired attenuation (amplitude dB) at the cutoff of the underlying low-pass.

  • relative (bool, optional) – If True, interpret fc as a fraction of max(|f|).

Returns:

Gaussian high-pass transfer function values.

Return type:

FloatArray

spharapy.spectral_filters.transfer_func_gaussian_lowpass(f, fc, dB=-3.0, *, relative=False)[source]

Gaussian low-pass filter with amplitude-based dB specification at fc.

The Gaussian low-pass magnitude response is given by

\[H(f) = \exp\bigl(-\kappa \, (f / f_c)^2\bigr),\]

where the parameter \(\kappa\) is chosen such that

\[|H(f_c)| = 10^{\text{dB} / 20}.\]

Thus,

\[\kappa = -\frac{\text{dB}}{20}\,\ln(10).\]
Parameters:
  • f (ArrayLike) – SPHARA frequency axis.

  • fc (float) – Cutoff frequency. Interpreted as absolute or relative (see relative).

  • dB (float, optional) – Desired attenuation (in amplitude dB) at \(f = f_c\). Must be negative. For exact half-power, dB = -20*log10(1/sqrt(2)) -3.0103.

  • relative (bool, optional) – If True, interpret fc as a fraction of max(|f|).

Returns:

Gaussian low-pass transfer function values.

Return type:

FloatArray

Raises:

ValueError – If the frequency grid contains non-finite values or dB is not a finite negative number.

Warns:

UserWarning – If the cutoff lies outside the SPHARA frequency range.

Examples

>>> import numpy as np
>>> from spharapy.spectral_filters import transfer_func_gaussian_lowpass
>>> f = np.linspace(0.0, 50.0, 101)
>>> H = transfer_func_gaussian_lowpass(f, fc=10.0, dB=-3.0)
>>> H.shape
(101,)
spharapy.spectral_filters.transfer_func_ideal_bandpass(f, low, high, *, relative=False)[source]

Ideal band-pass filter in the SPHARA domain.

The ideal band-pass is constructed from two ideal low-passes via

\[H_\text{bp}(f) = H_\text{lp}(f; f_\text{high}) - H_\text{lp}(f; f_\text{low}),\]

where \(f_\text{low} < f_\text{high}\).

Parameters:
  • f (ArrayLike) – SPHARA frequency axis.

  • low (float) – Lower cutoff (absolute or relative).

  • high (float) – Upper cutoff (absolute or relative). Must satisfy high > low.

  • relative (bool, optional) – If True, interpret low and high as fractions of max(|f|). Default: False.

Returns:

Ideal band-pass transfer function.

Return type:

FloatArray

Raises:

ValueError – If high <= low or if any cutoff is invalid.

Warns:

UserWarning – If the band lies (partly) outside the range of the SPHARA frequency axis.

spharapy.spectral_filters.transfer_func_ideal_highpass(f, fc, *, relative=False)[source]

Ideal high-pass filter in the SPHARA domain.

This is defined as the complement of the ideal low-pass:

\[H_\text{hp}(f) = 1 - H_\text{lp}(f; f_c).\]
Parameters:
  • f (ArrayLike) – SPHARA frequency axis.

  • fc (float) – Cutoff frequency (absolute or relative, see relative).

  • relative (bool, optional) – If True, interpret fc as a fraction of max(|f|).

Returns:

Ideal high-pass transfer function values.

Return type:

FloatArray

spharapy.spectral_filters.transfer_func_ideal_lowpass(f, fc, *, relative=False)[source]

Ideal (brick-wall) low-pass filter in the SPHARA domain.

The ideal low-pass magnitude response is defined as

\[\begin{split}H(f) = \begin{cases} 1, & \text{if } |f| \le f_c,\\ 0, & \text{otherwise.} \end{cases}\end{split}\]
Parameters:
  • f (ArrayLike) – SPHARA frequency axis (1D or ND). Typically contains non-negative spatial frequencies (e.g. \(\sqrt{\boldsymbol{\tau}}\) of a FEM-based SPHARA basis), but negative values are supported.

  • fc (float) – Cutoff frequency. If relative=False, fc is interpreted as an absolute frequency in the same units as f. If relative=True, fc is interpreted as a fraction of max(|f|).

  • relative (bool, optional) – If True, interpret fc as relative cutoff f_c = fc * max(|f|). Default: False.

Returns:

Ideal low-pass transfer function values with the same shape as f and values in {0.0, 1.0}.

Return type:

FloatArray

Raises:

ValueError – If the frequency grid contains non-finite values or the cutoff is not a finite positive number.

Warns:

UserWarning – If fc lies outside the range [min(f), max(f)]. In that case, the filter will be effectively all-ones or all-zeros.

Examples

>>> import numpy as np
>>> from spharapy.spectral_filters import transfer_func_ideal_lowpass
>>> f = np.linspace(-1, 1, 5)
>>> transfer_func_ideal_lowpass(f, fc=0.5)
array([0., 1., 1., 1., 0.])