-
airy_zeta_q(K, beta, chi, turn_chi, zeta, q, sin_k)
Liouville variable zeta (positive below the turning point, negative above)
from zeta*(dzeta/dchi)^2 = q, together with q = 1/S_K^2 - beta^2.
Within 1e-7 of the turning point both are replaced by their exact linear
limits, zeta = -a*(chi-chi_t) and q = -a^3*(chi-chi_t) with a = airy_turn_a.
Optionally returns S_K(chi) so callers need not recompute it.
-
integer intent(in) :: K
-
real(dp) intent(in) :: beta
-
real(dp) intent(in) :: chi
-
real(dp) intent(in) :: turn_chi
-
real(dp) intent(out) :: zeta
-
real(dp) intent(out) :: q
-
real(dp) intent(out), optional :: sin_k
compute_airy_second_norm_fast(l, K, nu, log_norm)
log of the single scalar that fixes the overall Airy normalization, by
matching the chi -> 0 limit of amp*Ai(lambda^(2/3) zeta) to the exact
origin behaviour u ~ u0 chi^(l+1). Returned as a log because both
factors overflow badly at large l.
integer intent(in) :: l
integer intent(in) :: K
real(dp) intent(in) :: nu
real(dp) intent(out) :: log_norm
eval_second_scaled_poly(c, zscale, zeta, rescaled, b0, a1)
psi(v) = sum_i c(i) * (v/zscale)**i.
Then
B0(zeta) = sum_i c(i)*(zeta/zscale)**i/(2*i + 1)
and A1 follows from A1' = 0.5*(psi*B0 - B0''), A1(0)=0.
This keeps the evaluation scaled, avoiding large powers of 1/zeta.
rescaled is false when zscale is just zeta, in which case every power of
zeta/zscale is one and the power ladder is skipped; the caller knows this
exactly, so it is passed in rather than tested for.
real(dp) intent(in) :: c(0:AIRY_SECOND_FAST_DEG)
real(dp) intent(in) :: zscale
real(dp) intent(in) :: zeta
logical intent(in) :: rescaled
real(dp) intent(out) :: b0
real(dp) intent(out) :: a1
interp_power_from_nodes(x, y, c)
Convert interpolation data (x_i,y_i), i = 0..n, to power coefficients
c such that p(x) = sum_i c(i)*x**i. Uses Newton divided differences;
for n<=4 this is cheaper and better conditioned than a dense solve.
real(dp) intent(in) :: x(0:AIRY_SECOND_FAST_DEG)
real(dp) intent(in) :: y(0:AIRY_SECOND_FAST_DEG)
real(dp) intent(out) :: c(0:AIRY_SECOND_FAST_DEG)
second_coeffs_onepoint_fast(K, beta, turn_chi, chi, zeta, b0, a1)
Build B0(zeta) and A1(zeta) for this one point only.
This version avoids both expensive zeta->chi inversion and the small
dense Vandermonde solve. It samples psi directly along a same-side chi
segment from the turning point, interpolates in scaled zeta using Newton
divided differences, and then evaluates the Olver B0/A1 functionals
analytically. Very small |zeta| uses a slightly enlarged same-side fit
segment to avoid cancellation in airy_psi_from_s near the turn.
integer intent(in) :: K
real(dp) intent(in) :: beta
real(dp) intent(in) :: turn_chi
real(dp) intent(in) :: chi
real(dp) intent(in) :: zeta
real(dp) intent(out) :: b0
real(dp) intent(out) :: a1