Cálculos de registro en Python
Estoy buscando calcular algo como:
Dóndef(i)
es una función que devuelve un número real en[-1,1]
para cualquieri
en{1,2,...,5000}
.
Obviamente, el resultado de la suma está en algún lugar de[-1,1]
, pero cuando parece que no puedo calcularlo en Python usando una codificación directa, como0.55000
se convierte0
ycomb(5000,2000)
se convierteinf
, que dan como resultado que la suma calculada se convierta enNaN
.
La solución requerida es usar el registro en ambos lados.
Eso es usar la identidada × b = 2log(a) + log(b)
, si pudiera calcularlog(a)
ylog(b)
Podría calcular la suma, incluso sia
es grande yb
es casi0
.
Supongo que lo que pregunto es si hay una manera fácil de computar
log2(scipy.misc.comb(5000,2000))
Entonces podría calcular mi suma simplemente por
sum([2**(log2comb(5000,i)-5000) * f(i) for i in range(1,5000) ])
La solución de @ abarnert, mientras trabaja para la cifra de 5000, aborda el problema al aumentar la precisión en la que se calcula el peine. Esto funciona para este ejemplo, pero no escala, ya que la memoria requerida aumentaría significativamente si en lugar de 5000 tuviéramos 1e7, por ejemplo.
Actualmente, estoy usando una solución alternativa que es fea, pero mantiene bajo el consumo de memoria:
log2(comb(5000,2000)) = sum([log2 (x) for x in 1:5000])-sum([log2 (x) for x in 1:2000])-sum([log2 (x) for x in 1:3000])
¿Hay alguna manera de hacerlo en una expresión legible?