Mathematical tools

All examples use ordinary numeric arguments. Add precision=:quad for quad precision.

Expansion coefficients and connection factors

d = dmn(1, 2, 1.25)   # angular expansion coefficients
K = kmn(1, 2, 1.25)   # joining factor
A = amn(1, 2, 1.25)   # radial factor, also accepts negative order

dmn returns degrees, coefficients, the coefficient derivatives, and convergence metadata. The coefficients expand smn in the Ferrers basis:

\[S_{mn}(c,\eta)=\sum_l d_l\,\mathsf P_l^m(\eta).\]

The basis includes the Condon-Shortley phase. normalize matches smn. In DLMF 30.8.1, $d_l=(-1)^k a_{n,k}^m$ for $l=n+2k$.

amn returns $A_n^m(\sigma c^2)$ from DLMF 30.11.4, accepting $-n\le m\le n$. Here $\sigma=1$ for prolate and $\sigma=-1$ for oblate. It uses Meixner-Schäfke normalization. Positive order includes the finite coefficient extension below degree $m$.

kmn supplies the exterior angular-radial connection DLMF 30.11.8:

\[S_n^{m(1)}(z,\gamma)=K_n^m(\gamma)\,\mathrm{Ps}_n^m(z,\gamma^2).\]

Use $\gamma=c$, $z=x$ for prolate and $\gamma=ic$, $z=-ix$ for oblate. The exterior Legendre branch uses $[z\sqrt{1-z^{-2}}]^m$ without the Ferrers phase. Oblate joining factors are complex. normalize=true gives the factor for a unit-normalized angular expansion.

All three support real or complex parameters, both geometries and precisions. By default at c=0, amn is one and kmn is zero except for $(m,n)=(0,0)$, where it is one. Radial calls at c=0 require normalization=:static. rtol and max_terms control coefficient convergence, not relative accuracy of every small coefficient.

Eigenvalue operators

eigenvalue(m, n, c; operator=:separation) selects:

operatorResultform
:separation (default)Separation constant λₘₙ(c):value
:concentrationConcentration eigenvalue Λₙ(c):value, :log, :complement
:fourierFinite Fourier eigenvalue μₙ(c):value

Separation constant

The angular and radial equations share λₘₙ(c), with λₘₙ(0) = n(n+1). Both geometries and real or complex parameters are supported.

eigenvalue(1, 2, 1.25; precision=:quad)
eigenvalue(1, 2, 1.25; spheroid=:oblate, precision=:quad)

Concentration and finite Fourier eigenvalues

For the first-kind angular mode Sₙ = S₀ₙ on [-1,1]:

\[\int_{-1}^{1}\frac{\sin(c(x-t))}{\pi(x-t)}S_n(t)\,dt =\Lambda_n(c)S_n(x), \qquad \int_{-1}^{1}e^{-icxt}S_n(t)\,dt=\mu_n(c)S_n(x).\]

The sinc kernel is c/π at x=t. For c>0,

\[0<\Lambda_n<1,\qquad \mu_n=(-i)^n\sqrt{\frac{2\pi\Lambda_n}{c}}.\]

These conventions follow DLMF 30.15 with the interval scaled to [-1,1].

eigenvalue(0, 2, 1.0; operator=:concentration, precision=:quad)
eigenvalue(0, 2, 1.0; operator=:fourier, precision=:quad)
eigenvalue(0, 0, 50.0; operator=:concentration,
    form=:complement, precision=:quad)
Integral-operator domain

Requires m=0, n≥0, spheroid=:prolate, and finite real c≥0. At c=0, all Λₙ=0; μ₀=2 and μₙ=0 for n>0.

Small eigenvalues and complements

form=:log returns log(Λₙ); form=:complement returns 1-Λₙ. Use these directly when Λₙ rounds to zero or one. At c=0, they return -Inf and 1, respectively.

Parameter derivatives

The Jacobians differentiate with respect to c; coordinate derivatives are returned by smn and rmn.

CallResult for real c
jacobian_eigen(m,n,c)dλ/dc
jacobian_smn(m,n,c,eta)dvalue_dc = ∂S/∂c, dderivative_dc = ∂²S/(∂c∂η)
jacobian_rmn(m,n,c,x)dvalue_dc = ∂R/∂c, dderivative_dc = ∂²R/(∂c∂x)
jacobian_smn(1, 2, 1.25, [0.3]; kind=2, precision=:quad)
jacobian_rmn(1, 2, 1.25, [2.0]; kind=2, precision=:quad)
jacobian_eigen(0, 2, 1.0; operator=:concentration, precision=:quad)
jacobian_eigen(0, 2, 1.0; operator=:fourier, precision=:quad)
jacobian_smn(1, 2, 1.25, [0.3]; order=2, diagnostics=true)

order=2 selects second parameter derivatives. Wave results use d2value_dc2 and d2derivative_dc2. Complex results use suffixes dcreal2, dcreal_dcimag, and dcimag2. These calculations difference analytic first derivatives with fourth-order stencils. h controls the step and diagnostics=true adds shared step-refinement diagnostics. Standard radial and positive-bandwidth integral stencils require 2h<abs(c).

jacobian_eigen accepts the same operators and forms as eigenvalue. For a real mode ψₙ with unit norm on [-1,1] and c>0:

\[\frac{d\Lambda_n}{dc}=\frac{|\mu_n|^2}{\pi}\psi_n(1)^2, \qquad \frac{d\log\Lambda_n}{dc}=\frac{2\psi_n(1)^2}{c}, \qquad \frac{d(1-\Lambda_n)}{dc}=-\frac{d\Lambda_n}{dc}.\]

For order 1 and complex c=a+ib, results contain real- and imaginary-direction partials (d_dcreal/d_dcimag for eigenvalues; dvalue_dcreal/dvalue_dcimag and dderivative_dcreal/dderivative_dcimag for functions). On a local analytic branch, ∂f/∂b = i ∂f/∂a.

Derivative options and limits

First derivatives use analytic differentiation unless h is supplied. diagnostics=true adds convergence diagnostics, not error bounds. Angular kind=2 parameter derivatives return NaN at η=±1. Radial calls at c=0 require normalization=:static.

Integral derivatives at zero

First derivatives are Λ₀′=2/π and μ₁′=-2im/3, otherwise zero. Second derivatives are μ₀″=-2/9 and μ₂″=-8/45, otherwise zero. form=:log returns Inf for order 1 and -Inf for order 2. Logarithmic derivatives at zero require h=nothing.

Inverse bandwidth

find_c_for_eigenvalue solves for real c within a supplied bracket:

\[\lambda_{mn}(c)=\lambda_{\mathrm{target}} \quad\text{or}\quad \Lambda_n(c)=\Lambda_{\mathrm{target}}.\]

target = eigenvalue(1, 2, 1.25; precision=:quad)
root = find_c_for_eigenvalue(1, 2, target;
    bracket=(0.5, 2.0), precision=:quad)

root = find_c_for_eigenvalue(0, 0, 0.999;
    operator=:concentration, bracket=(0.0, 10.0), precision=:quad)
root.c
root.converged
root.residual

bracket=(c_lo,c_hi) is required: finite endpoints with c_lo<c_hi whose eigenvalues enclose the target. Concentration inversion also requires c_lo>=0. An endpoint matching within tolerance is returned immediately. maxiter=160 limits iterations; use_jacobian=true permits Newton steps. With false, separation inversion uses secant/bisection and concentration uses bisection.

Result fieldMeaning
cEstimated bandwidth
convergedWhether the stopping criteria were met
residualComputed eigenvalue minus target, in the requested form
iterationsIterations performed, not evaluation count; zero for an endpoint match
bracketRemaining search interval at termination
methodFinal step: :newton, :secant, or :bisection; :endpoint for an endpoint match; :maxiter when the iteration limit is reached

For concentration, form defines the target:

FormTargetAllowed range
:valueΛₙ[0,1)
:complement1-Λₙ(0,1]
:loglog(Λₙ)[-Inf,0)
Check convergence

Check root.converged before using root.c; root.residual uses the requested form. Unit concentration has no finite bandwidth. Zero concentration requires a bracket containing zero. Fourier inversion is unsupported. Set atol and rtol explicitly for tighter separation-constant inversion.

See find_c_for_eigenvalue for tolerance defaults and stopping criteria.

Eigenvalue sweeps

sweep = eigenvalue_sweep(1, 2, [0.5, 1.0, 1.5]; precision=:quad)
sweep.lambda

path = ComplexF64[2, 2+3im, 3im, 0, 2]
continued = eigenvalue_sweep(0, 0, path; precision=:quad)
continued.selected_n

Sweeps track separation constants only. Real grids must be monotone; complex grids specify an ordered piecewise-linear path. selected_n records degree labels and switched_branch flags label changes. branch_lock=false evaluates the native label independently at each point.

KeywordEffect
branch_lock=trueContinue by choosing among nearby degree labels; false keeps the original label
branch_window=1Search half-width around the previously selected degree k; real grids search max(m,k-w):k+w, complex paths search same-parity neighbors k-2w, …, k+2w, clipped below at the lowest valid degree of that parity
use_jacobian_predictor=trueReal grids only: predict the second point with dλ/dc; if disabled or unreliable, use the preceding value. Later points use the slope between the previous two results

branch_window must be nonnegative; zero fixes the degree label. It has no effect with branch_lock=false. use_jacobian_predictor has no effect for complex paths, which use angular-profile matching. Both geometries and precision=:double/:quad are supported.

Complex branches

A closed path can exchange eigenmodes. Its final value need not equal its initial value. Nearly coalescing eigenvalues can make continuation and parameter derivatives ill-conditioned.

Multiple degrees

smn(1, 1:24, 1.25, [-0.7, 0.2, 0.8];
    spheroid=:oblate, precision=:quad, normalize=true)
rmn(1, 1:24, 1.25, [0.4, 1.0, 3.0];
    spheroid=:oblate, precision=:quad, kind=3, scaled=true)

Rows correspond to coordinates; columns correspond to degrees. A scalar coordinate gives one row. Single-degree calls return vectors, including length-one vectors for scalar coordinates.

Scaled values and logarithmic derivatives

\[f=M\,10^E,\qquad \ell=\frac{f'}{f}.\]

s = smn(200, 200, 0.0, 0.3; scaled=true, logderivative=true)
s.value.mantissa
s.value.exponent
s.logderivative

r = rmn(1, 2, 1.25, 2.0;
    kind=2, precision=:quad, scaled=true, logderivative=true)

With scaled=true, value and derivative each contain mantissa and integer exponent arrays. For finite nonzero values, 1≤abs(mantissa)<10. Complex mantissas use a common exponent for both components; zeros and nonfinite values use exponent zero.

Range and zeros

Scaling extends the representable magnitude, not the number of accurate digits. logderivative=true uses one-sided endpoint limits and returns NaN at other computed zeros. Unscaled values may overflow even when the logarithmic derivative remains finite.

Higher coordinate derivatives

For λ=λₘₙ(c) and σ=1 (prolate) or σ=-1 (oblate):

\[S''=\frac{2\eta S'- \left(\lambda-\sigma c^2\eta^2-\frac{m^2}{1-\eta^2}\right)S}{1-\eta^2},\]

\[R''=\frac{-2xR'- \left(c^2x^2-\lambda-\frac{\sigma m^2}{x^2-\sigma}\right)R}{x^2-\sigma}.\]

s = smn(1, 2, 1.25, 0.3; second_derivative=true, precision=:quad)
r = rmn(1, 2, 1.25, 2.0; second_derivative=true, precision=:quad)
s.second_derivative
r.second_derivative

Both options also work with scaled outputs and degree ranges.

Use derivatives=3 or 4 to append third_derivative and fourth_derivative. Endpoint derivatives use one-sided limits. Oblate x=0 is supported. derivatives=2 is equivalent to second_derivative=true.

Singular endpoints

The formulas above apply away from singular endpoints. Regular endpoint derivatives use finite or infinite one-sided limits. Angular second-kind derivatives diverge at η=±1. Prolate radial kinds 2–4 at x=1 return NaN for real or complex parameters.

Radial Wronskians

For real c>0 and nonsingular radial coordinates:

\[W=R_1R_2'-R_1'R_2,\qquad \widehat W=c(x^2-\sigma)W=1,\qquad \varepsilon_W=|\widehat W-1|.\]

radial_wronskian formOutput
:raw (default)W
:normalizedŴ
:errorε_W

radial_wronskian(m,n,c,x; spheroid=:prolate, precision=:double, form=:raw) uses radial kinds 1 and 2 and their coordinate derivatives. m,n are integer order and degree with 0≤m≤n. Standard normalization requires finite c≠0. x is a real scalar or nonempty vector: use prolate x>1 or oblate x≥0. spheroid=:oblate selects σ=-1; precision=:quad selects quad precision. normalization=:static includes c=0, with $W=1/(x^2-\sigma)$ and normalized output $(x^2-\sigma)W$.

Every form returns a vector, including for scalar x. Raw and normalized entries are complex; error entries are real. Normalized forms preserve scaling in intermediate products. Complex c is accepted under the same conventions as rmn; the unit-normalization check stated above is for real c>0.

radial_wronskian(1, 2, 1.25, [1.5, 2.0, 4.0];
    precision=:quad, form=:error)

The prolate identity is DLMF 30.11.7; the oblate factor follows its radial equation and normalization.

Accuracy estimates

accuracy(m,n,c,arg; target=:radial, spheroid=:prolate, precision=:double, kind=1, normalize=false, normalization=:standard, diagnostics=false) returns one integer per coordinate.

Argument / keywordMeaning
m, nInteger order and degree, 0≤m≤n
cFinite real or complex parameter. Radial c=0 requires normalization=:static
argNonempty coordinate vector with the domain of smn or rmn. Use [x] for one point
target=:radial:radial estimates rmn values; :angular estimates smn values
spheroid=:prolate:prolate or :oblate geometry
precision=:double:double or :quad evaluation; results remain integer digit counts
kind=1Angular 1 or 2; radial 1:4
normalize=falseDefault angular normalization; true selects unit normalization for real first-kind angular functions and its analytic continuation for complex c. Invalid for angular kind 2; ignored for radial calls

Positive entries estimate decimal digits; 0 reports no reliable digits and -1 means no estimate is available. Invalid inputs raise the corresponding wave-function errors; nonfinite values receive -1 when evaluation returns them.

Available estimates

For real coordinates, only radial kind=2 has a radial estimator, so the default radial call (kind=1) returns -1. Angular second-kind, endpoint, small-parameter (abs(c)≤1e-4), purely imaginary complex-parameter, and refined expansion evaluations and static radial normalization have no calibrated digit estimates. See accuracy.

accuracy(0, 1, 2.0, [1.5]; target=:radial, kind=2)
accuracy(0, 2, 1.0, [0.3]; target=:angular, normalize=true, precision=:quad)
accuracy(0, 2, 0.0, [0.3]; target=:angular) # [-1]

Complex coordinates use higher precision and halved continuation steps to estimate convergence. Add diagnostics=true for per-point refinement changes, condition numbers, and convergence flags. Zeros, endpoints and unresolved estimates return -1.

a = accuracy(1, 2, 1.25, [0.3 + 0.2im]; target=:angular, diagnostics=true)
a.digits
a.diagnostics[1].conditioning_flag
Diagnostics are not error bounds

A small Wronskian error checks consistency of the solution pair. Correlated errors can preserve that identity. Digit estimates do not certify coordinate derivatives.