Associated Legendre function , Condon-Shortley phase convention, computed by the classic Bonnet-type upward recurrence starting from . For negative order, . Unnormalized (unlike ASSOC_LEGENDRE_NORM_ALL); loses numerical stability well before the intermediate values literally overflow, since the later upward-in- recurrence involves a subtraction of two comparably huge terms (catastrophic cancellation).
Warning
Numerical stability: verified accurate (relative error
< 3e-14) for at any -- the worst
case, , occurs near the equator (
degrees) at ; safety improves toward either pole. This
supersedes an earlier "" claim, verified too
optimistic by direct comparison against an arbitrary-precision
reference. Full methodology and per-degree table:
STABILITY_FINDINGS.md at the repo root, Part 2 (regenerable via the
opt-in VSH_BUILD_STABILITY CMake target's vsh_unnorm_stability
executable).
Returns: .
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer(kind=i4), | intent(in) | :: | L |
Degree, . |
||
| integer(kind=i4), | intent(in) | :: | K |
Order, . |
||
| real(kind=dp), | intent(in) | :: | X |
Argument, (typically ). |
FUNCTION ASSOC_LEGENDRE_DP(L, K, X) RESULT(ASSOC_LEGENDRE) IMPLICIT NONE INTEGER(KIND=i4), INTENT(IN) :: L INTEGER(KIND=i4), INTENT(IN) :: K REAL(KIND=dp), INTENT(IN) :: X INTEGER(KIND=i4) :: ABSK, I REAL(KIND=dp) :: ASSOC_LEGENDRE REAL(KIND=dp) :: Pmm, Pmm1, Plm, somx2 ABSK = ABS(K) IF (ABSK > L .OR. ABS(X) > 1.0_dp) THEN ASSOC_LEGENDRE = 0.0_dp RETURN END IF Pmm = 1.0_dp IF (ABSK > 0) THEN somx2 = sqrt((1.0_dp - X) * (1.0_dp + X)) DO I = 1, ABSK Pmm = -Pmm * (2*I - 1) * somx2 END DO END IF IF (L == ABSK) THEN Plm = Pmm ELSE Pmm1 = X * (2 * ABSK + 1) * Pmm IF (L == ABSK + 1) THEN Plm = Pmm1 ELSE DO I = ABSK + 2, L Plm = (X*(2*I-1)*Pmm1-(I+ABSK-1)*Pmm) / (I-ABSK) Pmm = Pmm1 Pmm1 = Plm END DO END IF END IF IF (K < 0) THEN Plm = ((-1.0_dp)**ABSK)* & EXP(LOG_FACT(L-ABSK)-LOG_FACT(L+ABSK))*Plm END IF ASSOC_LEGENDRE = Plm END FUNCTION ASSOC_LEGENDRE_DP