freealg.AlgebraicForm.atoms#
- AlgebraicForm.atoms(eta=1e-06, tol=1e-12, real_tol=None, w_tol=1e-10, merge_tol=1e-08)#
Detect atom locations and weights of distribution
- Parameters:
- etafloat, default=1e-6
Small imaginary part used to probe the pole strength.
- tolfloat, default=1e-12
Tolerance for trimming polynomial coefficients.
- real_tolfloat or None, default=None
Tolerance for treating a complex root as real. If None, uses
1e3*tol.- w_tolfloat, default=1e-10
Minimum atom weight to report.
- merge_tolfloat, default=1e-8
Merge roots whose real parts differ by at most this tolerance.
- Returns:
- atomslist of (float, float)
List of tuples of the form
(atom_loc, atom_w). Locations are real numbers and weights are nonnegative.
See also
Notes
This routine uses the necessary condition for a finite pole
\[a_s(z_0) = 0,\]where \(a_s(z)\) is the leading coefficient of \(P\) in powers of \(m\). Candidate atom locations are the (nearly) real roots of \(a_s(z)\). The atom weight is estimated numerically from the Stieltjes transform as
\[w = \eta \, \Im(m(z_0 + i \eta)),\]which follows from \(m(z) \sim -w/(z - z_0)\) near an atom at \(z_0\).
Examples
>>> # Create a distribution with two bulks >>> from freealg.distributions import CompoundFreePoisson >>> cfp = CompoundFreePoisson(t=[2.0, 5.5], w=[0.75, 0.25], ... lam=0.1) >>> # Create AlgebraicForm and fit the distribution >>> from freealg import AlgebraicForm >>> af = AlgebraicForm(cfp) >>> af.fit(deg_m=3, deg_z=1) >>> # Estimate the atoms (using the fitted polynomial). This >>> # distribution has an atom at x=0 with 90% mass of the total >>> # spectral density. >>> atoms = af.atoms() >>> print(atoms) [(1.2538385955639516e-16, 0.9000000001406558)]