ASSOC_LEGENDRE_ALL_DP Subroutine

private subroutine ASSOC_LEGENDRE_ALL_DP(P, LMAX, X)

All unnormalized associated Legendre functions for , via the Bonnet recurrence, in one pass (amortizing shared recurrence terms across every at fixed -- far cheaper than independent ASSOC_LEGENDRE calls). Condon-Shortley phase; same recurrence and same stability limit as ASSOC_LEGENDRE (see ASSOC_LEGENDRE_NORM_ALL for the far-more-stable normalized alternative, itself safe to ).

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).

PLM_INDEX(l,m).

Arguments

Type IntentOptional Attributes Name
real(kind=dp), intent(out) :: P((LMAX+1)*(LMAX+2)/2)
integer(kind=i4), intent(in) :: LMAX

Maximum degree, .

real(kind=dp), intent(in) :: X

Argument, (typically ).


Calls

proc~~assoc_legendre_all_dp~~CallsGraph proc~assoc_legendre_all_dp ASSOC_LEGENDRE_ALL_DP proc~plm_index PLM_INDEX proc~assoc_legendre_all_dp->proc~plm_index

Called by

proc~~assoc_legendre_all_dp~~CalledByGraph proc~assoc_legendre_all_dp ASSOC_LEGENDRE_ALL_DP interface~assoc_legendre_all ASSOC_LEGENDRE_ALL interface~assoc_legendre_all->proc~assoc_legendre_all_dp proc~batch_alm_cons BATCH_ALM_CONS proc~batch_alm_cons->interface~assoc_legendre_all proc~batch_dalm_cons BATCH_DALM_CONS proc~batch_dalm_cons->interface~assoc_legendre_all proc~ssh_ortho SSH_ORTHO proc~ssh_ortho->interface~assoc_legendre_all program~convergence_main CONVERGENCE_MAIN program~convergence_main->interface~assoc_legendre_all program~convergence_main->proc~batch_alm_cons program~unnorm_stability_main UNNORM_STABILITY_MAIN program~unnorm_stability_main->interface~assoc_legendre_all program~main MAIN program~main->proc~batch_alm_cons program~main->proc~batch_dalm_cons program~main->proc~ssh_ortho

Source Code

  SUBROUTINE ASSOC_LEGENDRE_ALL_DP(P, LMAX, X)
  IMPLICIT NONE
  INTEGER(KIND=i4), INTENT(IN) :: LMAX
  REAL(KIND=dp), INTENT(IN) :: X
  REAL(KIND=dp), INTENT(OUT) :: P((LMAX+1)*(LMAX+2)/2)
  INTEGER(KIND=i4) :: L, M
  REAL(KIND=dp) :: SOMX2

  SOMX2 = SQRT((1.0_dp - X) * (1.0_dp + X))
  P(PLM_INDEX(0, 0)) = 1.0_dp

  DO M = 0, LMAX
    IF (M .GT. 0) &
      P(PLM_INDEX(M, M)) = -(2*M - 1) * SOMX2 * &
        P(PLM_INDEX(M-1, M-1))
      IF (M .LT. LMAX) &
        P(PLM_INDEX(M+1, M)) = X * (2*M + 1) * &
            P(PLM_INDEX(M, M))
      DO L = M+2, LMAX
        P(PLM_INDEX(L, M)) = &
            (X*(2*L-1)*P(PLM_INDEX(L-1, M)) - &
            (L+M-1)*P(PLM_INDEX(L-2, M))) / (L-M)
      END DO
  END DO
  END SUBROUTINE ASSOC_LEGENDRE_ALL_DP