En matemáticas , la aproximación de Lanczos es un método para calcular numéricamente la función gamma , publicado por Cornelius Lanczos en 1964. Es una alternativa práctica a la aproximación de Stirling, más popular , para calcular la función gamma con precisión fija.
La aproximación de Lanczos consta de la fórmula
para la función gamma, con
Aquí g es una constante real que puede elegirse arbitrariamente sujeta a la restricción de que Re( z + g + 1/2 ) > 0. [1] Los coeficientes p , que dependen de g , son un poco más difíciles de calcular (ver más abajo). Aunque la fórmula indicada aquí solo es válida para argumentos en el semiplano complejo derecho , se puede extender a todo el plano complejo mediante la fórmula de reflexión ,
La serie A es convergente y puede truncarse para obtener una aproximación con la precisión deseada. Al elegir una g apropiada (normalmente un número entero pequeño), sólo se necesitan entre 5 y 10 términos de la serie para calcular la función gamma con la típica precisión de punto flotante simple o doble . Si se elige una g fija, los coeficientes se pueden calcular de antemano y, gracias a la descomposición en fracciones parciales , la suma se transforma en la siguiente forma:
Por tanto, calcular la función gamma se convierte en una cuestión de evaluar sólo un pequeño número de funciones elementales y multiplicarlas por constantes almacenadas. La aproximación de Lanczos fue popularizada por Numerical Recipes , según la cual calcular la función gamma se vuelve "no mucho más difícil que otras funciones integradas que damos por sentado, como sin x o e x ". El método también se implementa en la Biblioteca Científica GNU , Boost , CPython y musl .
Los coeficientes están dados por
donde representa el ( n , m )ésimo elemento de la matriz de coeficientes de los polinomios de Chebyshev , que se puede calcular recursivamente a partir de estas identidades:
Godfrey (2001) describe cómo obtener los coeficientes y también el valor de la serie truncada A como producto matricial . [2]
Lanczos derivó la fórmula de la integral de Leonhard Euler
realizando una secuencia de manipulaciones básicas para obtener
y derivar una serie para la integral.
La siguiente implementación en el lenguaje de programación Python funciona para argumentos complejos y normalmente proporciona 13 decimales correctos. Tenga en cuenta que omitir los coeficientes más pequeños (en busca de velocidad, por ejemplo) da resultados totalmente inexactos; los coeficientes deben recalcularse desde cero para una expansión con menos términos.
desde cmath importar pecado , sqrt , pi , exp""" Los coeficientes utilizados en el código son para cuando g = 7 y n = 9 Aquí hay algunos otros ejemplosg = 5 n = 5 p = [ 1.0000018972739440364, 76.180082222642137322, -86.505092037054859197, 24.012898581922685900, -1.2296028490285820 771 ]g = 5 n = 7 p = [ 1.0000000001900148240, 76.180091729471463483, -86.505320329416767652, 24.014098240830910490, -1.2317395724501553 875, 0.0012086509738661785061, -5.3952393849531283785e-6 ]g = 8 n = 12 p = [ 0.9999999999999999298, 1975.3739023578852322, -4397.3823927922428918, 3462.6328459862717019, -1156.9851431631167820, 154.53815050252775060, -6.2536716123689161798, 0.034642762454736807441, -7.4776171974442977377e-7, 6.3041253821852264261e-8, -2.7405717035683877489e-8, 4.0486948817567609101e-9 ] """g = 7 n = 9 p = [ 0.99999999999980993 , 676.5203681218851 , - 1259.1392167224028 , 771.32342877765313 , - 176.61502916214059 12. 507343278686905 , - 0.13857109526572012 , 9.9843695780195716e -6 , 1.5056327351493116e-7 ] EPSILON = 1e-07 def drop_imag ( z ): si abs ( z . imag ) <= EPSILON : z = z . retorno real z def gamma ( z ): z = complejo ( z ) si z . real < 0.5 : y = pi / ( sin ( pi * z ) * gamma ( 1 - z )) # Fórmula de reflexión else : z -= 1 x = p [ 0 ] para i en el rango ( 1 , len ( p )) : x += p [ i ] / ( z + i ) t = z + g + 0.5 y = sqrt ( 2 * pi ) * t ** ( z + 0.5 ) * exp ( - t ) * x return drop_imag ( y ) """ El uso anterior de la reflexión (por lo tanto la estructura if-else) es necesario, aunque pueda parecer extraño, ya que permite extender la aproximación a valores de z donde Re(z) < 0,5, donde los Lanczos El método no es válido.imprimir ( gamma ( 1 )) imprimir ( gamma ( 5 )) imprimir ( gamma ( 0.5 ))