60 votos

¿Función gamma inversa?

Esta es una pregunta de análisis que recuerdo haber pensado en el instituto. Leer algunos de los otros temas aquí me recordó esto, y me gustaría escuchar las soluciones de otras personas a esto.

Tenemos la función gamma, que tiene una forma bastante elemental como todos sabemos,

$\Gamma(z) = \int_0^\infty e^{-t} t^{z-1} dt = \int_0^1 \left[ \ln(t^{-1}) \right]^{z-1}$

Lo que satisface por supuesto, $\Gamma(n) = (n-1)!$ , $n\in \mathbb{N}$ y las diversas relaciones de recurrencia y otras identidades que todos podemos buscar en wikipedia o mathwolrd o donde sea. Observamos que la función gamma es creciente en el intervalo $[a,\infty]$ donde $a\approx 1.46163$ .

La pregunta es: ¿podemos encontrar una función inversa explícita a la función gamma en este intervalo que tenga un aspecto igualmente sencillo?

Mis técnicas en ese momento consistían en escribir una ecuación diferencial que la inversa satisficiera, y resolverla, lo que podía hacer en términos de una expansión de series de potencias (estando en la escuela secundaria, ignorando los problemas de convergencia) para obtener una solución aproximada. Pero nunca fui capaz de obtener una solución muy bonita o exacta. Ahora tengo algunos trucos más sofisticados para hacer esto, pero me interesaría ver cómo la gente con más experiencia con este tipo de cuestiones iría a responder a esto.

La función gamma también satisface un número razonable de relaciones funcionales de aspecto algo interesante como $\Gamma(z)\Gamma(1-z)=\pi/\sin(\pi z)$ . ¿Cumple la función inversa alguna relación similar?

2voto

K K Puntos 1

Esto debería funcionar para Mathematica:

c = 0.036534
l[x_] = Log[(x + c)/Sqrt[2*Pi]]
aig[x_] = l[x]/(ProductLog[l[x]/E]) + 1/2

2voto

Andreas Andreou Puntos 106

La aproximación inversa factorial viene dada por esta fórmula dividida en un par de pasos para simplificarla

$$m=\frac{\ln(x)}{\ln(\ln(x)+1)} $$

$$k=\frac{\ln(\frac{m!}{x})}{\ln(m+1)}$$

$$x¡=m-k+\frac{\ln(\frac{x}{(m-k)!})}{\ln(m-k+1)}$$

Versión entera

$$m=\left \lceil \frac{\ln(x)}{\ln(\ln(x)+1)} \right \rceil$$

$$k= \frac{\ln(\frac{m!}{x})}{\ln(m+1)}$$

$$x¡=\left \lfloor m-k+ \frac{\ln(\frac{x}{(m-k)!})}{\ln(m-k+1)} \right \rceil$$

(Cuidado con la marca de techo/suelo, el último es el redondeo, el primer techo es sólo para mejorar la convergencia y no tener que calcular dos veces el factorial no entero).

La idea es llegar a $y$ de $x=y!$ lo más cerca posible utilizando $\frac{\ln(x)}{\ln(\ln(x)+1)}$ entonces, como se trata de una infravaloración, para estimar cuán bajo estamos y cuántas veces tenemos que multiplicar por $(m+1)(m+2)...(m+k)$ más, redondeando esto por $(m+1)^k$ ya que los números son cercanos, finalmente asumiendo que estamos lo suficientemente cerca usando la estimación $(n+\epsilon)! \sim n!(n+1)^{\epsilon}$ del límite Gamma llegamos al resultado final.

(Marcamos el factorial inverso con el signo de exclamación inverso).

La fórmula funciona para $x>1$ . Sin embargo, la simple $\frac{(x+1)!}{x+1}=x!$ puede desplazarlo hacia arriba.

La principal ventaja es que el método da una evaluación bastante precisa incluso para valores no enteros, ciertamente suficiente para el factorial entero incluso más allá de $10^7!$ . Sin embargo, si se necesita una mayor precisión, basta con repetir el último paso

$$r+\frac{\ln(\frac{x}{r!})}{\ln(r+1)}$$

Podría ser alguna tarea especial que requiriera repetir esto más de una vez, probablemente para valores pequeños pero el paso puede repetirse tantas veces como sea necesario.

Versión de alta precisión

$$m=\frac{\ln(x)}{\ln(\ln(x)+1)} $$

$$k=\frac{\ln(\frac{m!}{x})}{\ln(m+1)}$$

$$r=m-k+\frac{\ln(\frac{x}{(m-k)!})}{\ln(m-k+\frac{1}{2})}$$

$$x¡=r+\frac{\ln(\frac{x}{r!})}{\ln(r+\frac{1}{2})}$$

Algoritmo binario de números enteros

Supongamos que tenemos una entrada entera $x=n!$

  1. Si $x=1$ devolver $1$
  2. Cuenta el número de ceros finales, $t$ en la representación binaria de $x$
  3. Calcular $w=\frac{x}{t!}$
  4. Calcular el número de veces $t+1$ divide $w$ redondeado al número entero más cercano que da este resultado, pero simplificado y optimizado para cualquier lenguaje de programación que se utilice $$r= \left \lfloor \frac{\ln(w)}{\ln(t+1)} \right \rfloor$$
  5. Volver $t+r$

0voto

Mill Puntos 486

Aquí hay un código que escribí para un problema similar hace unos años. Utilicé la aproximación de Stirling y el método de Newton. Puede que no sea la solución más eficiente, pero funcionó bien para mis aplicaciones. Quizás esto pueda ayudar a alguien en el futuro. También me gustaría hacer hincapié en que esto es sólo una aproximación y que puede ser posible obtener la respuesta incorrecta si su entrada es lo suficientemente grande (Sin embargo, no he observado esto)

Aproximación de Stirlings: https://en.wikipedia.org/wiki/Stirling%27s_approximation

Método de Newton: https://en.wikipedia.org/wiki/Newton%27s_method

import math

q = math.log10(int(input())
def function(x):
    y = .5*math.log10(2*math.pi*x) + x*math.log10(x)-x*math.log10(math.e)-q
    return y

def derivative(x):
    y1 = ( (math.log( (1/math.e) * x) / math.log(10)) + (1/(2*math.log(10)*x)) + (1/math.log(10)))
    return y1

x0 = len(str(factorial_n))
arrX = [x0]
for i in range(0,3):
    tempx = arrX[-1]
    X_n = tempx - (function(tempx) / derivative(tempx))
    arrX.append(X_n)
print(math.floor(arrX[-1]))

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X