/// <summary> /// Returns the value of the Associated Laguerre polynomial of degree <paramref name="n"/> and order <paramref name="m"/> at point <paramref name="x"/> /// </summary> /// <param name="n">Polynomial degree. Requires <paramref name="n"/> ≥ 0. Limited to <paramref name="n"/> ≤ 127</param> /// <param name="m">Polynomial order. Requires <paramref name="m"/> ≥ 0</param> /// <param name="x">Polynomial argument</param> public static double LaguerreL(int n, int m, double x) { if ((n < 0) || (m < 0)) { Policies.ReportDomainError("LaguerreL(n: {0}, m: {1}, x: {2}): Requires n,m >= 0", n, m, x); return(double.NaN); } if (n >= 128) { Policies.ReportNotImplementedError("LaguerreL(n: {0}, m: {1}, x: {2}): Not implemented for n >= 128", n, m, x); return(double.NaN); } // Special cases: if (m == 0) { return(Math2.LaguerreL(n, x)); } if (n == 0) { return(1); } if (double.IsNaN(x)) { Policies.ReportDomainError("LaguerreL(n: {0}, m: {1}, x: {2}): NaN not allowed", n, m, x); return(double.NaN); } if (double.IsInfinity(x)) { return((x > 0 && IsOdd(n)) ? double.NegativeInfinity : double.PositiveInfinity); } // use recurrence // p0 - current // p1 - next double p0 = 1; double p1 = m + 1 - x; for (uint k = 1; k < (uint)n; k++) { double next = ((2 * k + (uint)m + 1 - x) * p1 - (k + (uint)m) * p0) / (k + 1); p0 = p1; p1 = next; } return(p1); }