serie - suma en python
Programa de Python para calcular series armónicas (10)
¿Alguien sabe cómo escribir un programa en Python que calculará la adición de la serie armónica? es decir, 1 + 1/2 +1/3 +1/4 ...
¿Deberes?
Es una serie divergente, por lo que es imposible sumar todos los términos.
No conozco Python, pero sé cómo escribirlo en Java.
public class Harmonic
{
private static final int DEFAULT_NUM_TERMS = 10;
public static void main(String[] args)
{
int numTerms = ((args.length > 0) ? Integer.parseInt(args[0]) : DEFAULT_NUM_TERMS);
System.out.println("sum of " + numTerms + " terms=" + sum(numTerms));
}
public static double sum(int numTerms)
{
double sum = 0.0;
if (numTerms > 0)
{
for (int k = 1; k <= numTerms; ++k)
{
sum += 1.0/k;
}
}
return sum;
}
}
Esto debería hacer el truco.
def calc_harmonic(n):
return sum(1.0/d for d in range(2,n+1))
La serie armónica diverge, es decir, su suma es infinito.
editar: a menos que desee sumas parciales, pero no fue muy claro al respecto.
Qué tal esto:
partialsum = 0
for i in xrange(1,1000000):
partialsum += 1.0 / i
print partialsum
donde 1000000 es el límite superior.
Solo una nota al pie en las otras respuestas que usaron el punto flotante; comenzar con el divisor más grande e iterar hacia abajo (hacia los recíprocos con el valor más grande) pospondrá el error acumulado de redondeo tanto como sea posible.
Se puede calcular una versión de la función H rápida, precisa, uniforme y de valores complejos utilizando la función digamma, tal como se explica aquí . La constante Euler-Mascheroni (gamma) y la función digamma están disponibles en las bibliotecas numpy y scipy, respectivamente.
from numpy import euler_gamma
from scipy.special import digamma
def digamma_H(s):
""" If s is complex the result becomes complex. """
return digamma(s + 1) + euler_gamma
from fractions import Fraction
def Kiv_H(n):
return sum(Fraction(1, d) for d in xrange(1, n + 1))
def J_F_Sebastian_H(n):
return euler_gamma + log(n) + 0.5/n - 1./(12*n**2) + 1./(120*n**4)
Aquí hay una comparación de los tres métodos de velocidad y precisión (con Kiv_H para referencia):
Kiv_H(x) J_F_Sebastian_H(x) digamma_H(x) x seconds bits seconds bits seconds bits 1 5.06e-05 exact 2.47e-06 8.8 1.16e-05 exact 10 4.45e-04 exact 3.25e-06 29.5 1.17e-05 52.6 100 7.64e-03 exact 3.65e-06 50.4 1.17e-05 exact 1000 7.62e-01 exact 5.92e-06 52.9 1.19e-05 exact
Usando el simple bucle for
def harmonicNumber(n):
x=0
for i in range (0,n):
x=x+ 1/(i+1)
return x
Agrego otra solución, esta vez usando recursión, para encontrar el n-ésimo número armónico.
Detalles generales de implementación
Prototipo de función: harmonic_recursive(n)
Parámetros de función: n
- el n-ésimo número armónico
Caso base: si n
es igual a 1
devuelve 1.
Paso recurrente: si no es el caso base, llame a harmonic_recursive
para el término n-1
y añada ese resultado con 1/n
. De esta forma, agregamos cada vez el término i-ésimo de la serie Harmonic con la suma de todos los términos anteriores hasta ese punto.
Pseudocódigo
(Esta solución también se puede implementar fácilmente en otros idiomas).
harmonic_recursive(n):
if n == 1:
return 1
else:
return 1/n + harmonic_recursive(n-1)
Código de Python
def harmonic_recursive(n):
if n == 1:
return 1
else:
return 1.0/n + harmonic_recursive(n-1)
La respuesta de @Kiv es correcta pero es lenta para n grande si no necesita una precisión infinita. Es mejor usar una fórmula asintótica en este caso:
#!/usr/bin/env python
from math import log
def H(n):
"""Returns an approximate value of n-th harmonic number.
http://en.wikipedia.org/wiki/Harmonic_number
"""
# Euler-Mascheroni constant
gamma = 0.57721566490153286060651209008240243104215933593992
return gamma + log(n) + 0.5/n - 1./(12*n**2) + 1./(120*n**4)
La respuesta de @ Kiv para Python 2.6:
from fractions import Fraction
harmonic_number = lambda n: sum(Fraction(1, d) for d in xrange(1, n+1))
Ejemplo:
>>> N = 100
>>> h_exact = harmonic_number(N)
>>> h = H(N)
>>> rel_err = (abs(h - h_exact) / h_exact)
>>> print n, "%r" % h, "%.2g" % rel_err
100 5.1873775176396242 6.8e-16
En N = 100
error relativo es menor que 1e-15
.
La solución de @recursive es correcta para una aproximación de coma flotante. Si lo prefiere, puede obtener la respuesta exacta en Python 3.0 usando el módulo de fracciones:
>>> from fractions import Fraction
>>> def calc_harmonic(n):
... return sum(Fraction(1, d) for d in range(1, n + 1))
...
>>> calc_harmonic(20) # sum of the first 20 terms
Fraction(55835135, 15519504)
Tenga en cuenta que la cantidad de dígitos crece rápidamente, por lo que requerirá mucha memoria para n grande. También podrías usar un generador para mirar la serie de sumas parciales si quisieras ser realmente elegante.