Polar decomposition#
- class petal2d.PolarDecomposition(f_xy, x, y, Nr=None, Ntheta=512, rmax=None, m_abs_max=None, recon_err_tol=1.0, radial_power_tail_fraction=1e-06, radial_relative_amplitude_threshold=0.001, origin='centroid', normalize=False, interp_method='cubic')[source]#
Bases:
MappingPolar angular-harmonic decomposition of a localized 2D scalar field.
PolarDecompositionconverts a scalar field from Cartesian coordinates to a polar representation about a chosen origin and expands the angular dependence at every radius as\[f(r,\theta) = \sum_m \rho_m(r)e^{im\theta}.\]PETAL2D defines the radial power of angular harmonic
mas\[P_m = \int_0^{r_{\max}} |\rho_m(r)|^2 r\,dr.\]The angular FFT is computed first for the complete discrete spectrum. Adaptive truncation then ranks admissible angular channels by power and retains the smallest set that satisfies
recon_err_tol. For real input, nonzero conjugate harmonics(+m, -m)are selected together so the automatic reconstruction remains real-valued.- Parameters:
f_xy (callable or ndarray of shape (Nx, Ny)) – Input field. A callable must accept array-valued
xandyand return either a scalar or an array with the supplied mesh shape. Callable inputs are evaluated directly on the final polar grid after centering. Array inputs are interpolated from the Cartesian grid.x (array_like) – One-dimensional, finite, strictly increasing, uniformly spaced Cartesian coordinates. For array input,
f_xy.shapemust equal(len(x), len(y)).y (array_like) – One-dimensional, finite, strictly increasing, uniformly spaced Cartesian coordinates. For array input,
f_xy.shapemust equal(len(x), len(y)).Nr (int or None, optional) – Number of radial samples. If
None, usemin(len(x), len(y)). The radial grid includes both zero andrmax.Ntheta (int, default=512) – Number of uniformly spaced angular samples on
[0, 2*pi).rmax (float or None, optional) – Maximum analyzed polar radius. If
None, use the largest disk centered onoriginthat is fully contained in the Cartesian rectangle. The resulting value is available assafe_rmax.m_abs_max (int or None, optional) – Optional bound on admissible
|m|during adaptive selection. It may not exceedm_nyquist. This does not change the complete spectrum stored inm_allandrho_all.recon_err_tol (float, default=1.0) – Target relative polar-area-weighted L2 reconstruction error, in percent. The selector uses a Parseval power identity;
target_reachedreports whether the admissible spectrum can meet the target.radial_power_tail_fraction (float, default=1e-6) – Maximum fraction of a retained mode’s integrated radial power allowed outside
radial_power_support_radius[m]. Must satisfy0 <= radial_power_tail_fraction < 1.radial_relative_amplitude_threshold (float, default=1e-3) – Fraction of
max_r |rho_m(r)|used to defineradial_amplitude_support_radius[m]. The outermost threshold crossing is used so significant outer radial lobes are retained. Must satisfy0 <= value < 1.origin ({"centroid"} or array_like of length 2, default="centroid") – Expansion origin.
"centroid"uses the Cartesian L2 power centroid of|f|^2. A finite length-two input is interpreted as the explicit Cartesian coordinate(x0, y0).normalize (bool, default=False) – If
True, divide the Cartesian field by the square root of its Cartesian L2 power before polar analysis.interp_method ({"linear", "cubic"}, default="cubic") – Cartesian-to-polar interpolation used only for sampled array input.
- centroid#
Numerically evaluated Cartesian L2 power centroid, regardless of whether an explicit
originwas requested.
- r#
Radial sample coordinates.
- Type:
ndarray of shape (Nr,)
- theta#
Angular sample coordinates in radians.
- Type:
ndarray of shape (Ntheta,)
- safe_rmax#
Radius of the largest centered disk fully contained in the Cartesian rectangle.
- Type:
- nyquist_mode#
For even
Ntheta, the single NumPy FFT Nyquist index-Ntheta/2; otherwiseNone.- Type:
int or None
- f_polar#
Input field evaluated or interpolated on the polar grid.
- Type:
ndarray of shape (Nr, Ntheta)
- f_recon#
Adaptive retained-mode reconstruction.
- Type:
ndarray of shape (Nr, Ntheta)
- domain_consistency#
Ratio
polar_power / cartesian_power. It quantifies captured field weight, not pointwise interpolation accuracy.- Type:
- is_real_input#
Whether the analyzed input is real-valued to PETAL2D’s numerical tolerance.
- Type:
- m_all#
Complete discrete FFT harmonic indices in NumPy FFT order.
- Type:
ndarray of shape (Ntheta,)
- rho_all#
Complete radial harmonic coefficients.
- Type:
ndarray of shape (Nr, Ntheta)
- powers_all#
Complete radial mode powers
P_m.- Type:
ndarray of shape (Ntheta,)
- power_fracs_all#
powers_allnormalized by their sum.- Type:
ndarray of shape (Ntheta,)
- selected_pairs#
Adaptive selection units actually retained. Real fields use conjugate
(+m, -m)pairs except form=0and the even-grid Nyquist singleton. Complex fields use singleton channels.
- selected_pair_powers#
Power of each retained adaptive selection unit.
- Type:
ndarray
- selected_pair_power_fracs#
Fractional power of each retained adaptive selection unit.
- Type:
ndarray
- retained_power_fraction#
Fraction of the complete discrete polar spectral power retained.
- Type:
- recon_error_measured#
Directly evaluated polar weighted L2 reconstruction error in percent.
- Type:
- parseval_relative_error#
Relative mismatch between direct polar power and the sum of discrete harmonic powers; useful as a numerical consistency diagnostic.
- Type:
- radial_power_support_radius#
Per-retained-mode smallest radius satisfying the integrated radial power-tail criterion.
- radial_amplitude_support_radius#
Per-retained-mode outermost radius satisfying the relative-amplitude criterion.
- cutoff_radius#
Per-retained-mode maximum of the power- and amplitude-support radii. This is a diagnostic only and never truncates reconstruction.
Notes
PETAL2D uses the Fourier convention
\[\rho_m(r) = \frac{1}{2\pi}\int_0^{2\pi} f(r,\theta)e^{-im\theta}\,d\theta.\]Therefore
\[\|f\|_{L^2(D)}^2 = 2\pi\sum_m P_m.\]The factor
2*picancels from all power fractions and reconstruction error ratios. The package documentation contains full proofs of Parseval error certification, real-field conjugacy, rotation covariance, centering, discrete aliasing, and rotational selection rules.Examples
Analyze a real
p_x-like orbital. The automatic selector retains the conjugate pair(+1, -1):>>> import numpy as np >>> from petal2d import PolarDecomposition >>> x = np.linspace(-5.0, 5.0, 101) >>> y = np.linspace(-5.0, 5.0, 101) >>> def px(x, y): ... return x * np.exp(-0.5 * (x*x + y*y)) >>> dec = PolarDecomposition(px, x, y, Ntheta=128) >>> dec.selected_pairs [(1, -1)] >>> dec.reconstruction_error() < 1e-10 True
See also
numpy.fft.fftDiscrete Fourier transform used for the angular spectrum.
scipy.ndimage.map_coordinatesInterpolation used for sampled input.
- reconstruct(modes=None)[source]#
Reconstruct the polar field from selected angular harmonics.
- Parameters:
modes (None, {"all"}, or iterable of int, optional) – Harmonics to include.
Noneuses the adaptively retained spectrum."all"uses the complete discrete FFT spectrum. An iterable uses exactly the requested harmonics. Explicit mode lists are never silently conjugate-paired.- Returns:
Field reconstructed on the stored polar grid. For real input, adaptive, complete, or explicitly conjugate-closed requests return a real array. An intentionally asymmetric explicit subset can return a complex array.
- Return type:
ndarray of shape (Nr, Ntheta)
Notes
Reconstruction uses the full analyzed radial grid.
cutoff_radiusis diagnostic and never crops the result.
- reconstruction_error(modes=None)[source]#
Return polar-area-weighted relative L2 reconstruction error.
- Parameters:
modes (None, {"all"}, or iterable of int, optional) – Uses the same mode-selection semantics as
reconstruct().- Returns:
Relative weighted L2 error in percent.
- Return type:
Notes
The norm uses the polar area measure
r dr dtheta. For the adaptive subset this directly measured value should agree withrecon_error, which is predicted from omitted spectral power by Parseval’s identity.
- spectrum_table(retained_only=True)[source]#
Return spectrum rows as dependency-free Python dictionaries.
- Parameters:
retained_only (bool, default=True) – If
True, return only adaptively retained harmonics. IfFalse, return every discrete FFT harmonic.- Returns:
Rows sorted by decreasing individual harmonic power. Every row has keys
m,power,power_fraction,radial_power_support_radius,radial_amplitude_support_radius,cutoff_radius, andretained. Radius entries areNonefor non-retained modes.- Return type:
Notes
power_fractionrefers to an individual harmonic, whereasselected_pair_power_fracsrefers to adaptive selection units when real-field conjugate pairing is active. No pandas dependency is used.
- print_spectrum(retained_only=True, file=None)[source]#
Print a compact human-readable table of the angular spectrum.
- Parameters:
- Return type:
None
- plot_harmonics_with_hist(title='')[source]#
Plot retained radial profiles and ranked angular power fractions.
- Parameters:
title (str, optional) – Figure-level title.
- Returns:
fig (matplotlib.figure.Figure) – Created figure.
axes (ndarray of matplotlib.axes.Axes) – Two axes: radial profiles on the left and retained power-ranked harmonics on the right.
Notes
The left panel shows
|rho_m(r)|for each retained harmonic. A color-matched dashed line markscutoff_radius[m]. The cutoff radius is diagnostic only and never truncates reconstruction.The right panel is categorical rather than a linear
maxis. Only retained harmonics are shown, ordered from greatest to least fractional power, so sparse spectra with large angular indices do not create large empty ranges.
- plot_original_vs_reconstructions(title='Reconstruction comparison', display_radius=None)[source]#
Compare the analyzed polar field with the adaptive reconstruction.
- Parameters:
title (str, default="Reconstruction comparison") – Figure-level title.
display_radius (float or None, optional) – Half-width of the displayed Cartesian window in the same length units as
xandy. IfNone, use 115% of the largest retainedcutoff_radius, capped at the analyzed radial-domain radius. This changes only the viewport.
- Returns:
fig (matplotlib.figure.Figure) – Created figure.
axes (ndarray of matplotlib.axes.Axes) – Two axes containing the analyzed field and adaptive reconstruction.
Notes
Real sign-changing fields are displayed with sign preserved and a symmetric zero-centered color scale. Real nonnegative fields use a sequential map. Complex fields are displayed as magnitudes. Both panels always share the same color normalization.