python 计算谐波级数的Python程序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/404346/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python program to calculate harmonic series
提问by marc lincoln
Does anyone know how to write a program in Python that will calculate the addition of the harmonic series. i.e. 1 + 1/2 +1/3 +1/4...
有谁知道如何用 Python 编写一个程序来计算谐波级数的相加。即 1 + 1/2 +1/3 +1/4 ...
回答by jfs
@Kiv's answeris correct but it is slow for large n if you don't need an infinite precision. It is better to use an asymptotic formulain this case:
@Kiv 的答案是正确的,但是如果您不需要无限精度,对于大 n 来说它会很慢。在这种情况下最好使用渐近公式:
#!/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)
@Kiv's answerfor Python 2.6:
from fractions import Fraction
harmonic_number = lambda n: sum(Fraction(1, d) for d in xrange(1, n+1))
Example:
例子:
>>> 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
At N = 100
relative error is less then 1e-15
.
在N = 100
相对误差小于那么1e-15
。
回答by Kiv
@recursive's solutionis correct for a floating point approximation. If you prefer, you can get the exact answer in Python 3.0 using the fractions module:
@recursive 的解决方案对于浮点近似值是正确的。如果您愿意,您可以在 Python 3.0 中使用分数模块获得确切答案:
>>> 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)
Note that the number of digits grows quickly so this will require a lot of memory for large n. You could also use a generator to look at the series of partial sums if you wanted to get really fancy.
请注意,位数增长很快,因此对于大 n,这将需要大量内存。如果您想变得非常花哨,您还可以使用生成器来查看部分和的系列。
回答by FutureNerd
A fast, accurate, smooth, complex-valued version of the H function can be calculated using the digamma function as explained here. The Euler-Mascheroni (gamma) constant and the digamma function are available in the numpy and scipy libraries, respectively.
可以使用此处解释的 digamma 函数计算快速、准确、平滑、复值版本的 H 函数。Euler-Mascheroni (gamma) 常数和 digamma 函数分别在 numpy 和 scipy 库中可用。
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)
Here's a comparison of the three methods for speed and precision (with Kiv_H for reference):
下面是三种方法的速度和精度的比较(以Kiv_H为参考):
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
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
回答by joel.neely
Just a footnote on the other answers that used floating point; starting with the largest divisor and iterating downward(toward the reciprocals with largest value) will put off accumulated round-off error as much as possible.
只是对使用浮点数的其他答案的脚注;从最大的除数开始向下迭代(朝着具有最大值的倒数)将尽可能推迟累积的舍入误差。
回答by dancavallaro
The harmonic series diverges, i.e. its sum is infinity..
谐波级数发散,即它的总和是无穷大..
edit: Unless you want partial sums, but you weren't really clear about that.
编辑:除非您想要部分金额,但您对此并不十分清楚。
回答by recursive
This ought to do the trick.
这应该可以解决问题。
def calc_harmonic(n):
return sum(1.0/d for d in range(2,n+1))
回答by zenazn
How about this:
这个怎么样:
partialsum = 0
for i in xrange(1,1000000):
partialsum += 1.0 / i
print partialsum
where 1000000 is the upper bound.
其中 1000000 是上限。
回答by duffymo
Homework?
在家工作?
It's a divergent series, so it's impossible to sum it for all terms.
这是一个发散级数,因此不可能对所有项求和。
I don't know Python, but I know how to write it in Java.
我不会 Python,但我知道如何用 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;
}
}
回答by srikar saggurthi
Using the simple for loop
使用简单的 for 循环
def harmonicNumber(n):
x=0
for i in range (0,n):
x=x+ 1/(i+1)
return x
回答by George Gkasdrogkas
I add another solution, this time using recursion, to find the n-th Harmonic number.
我添加了另一个解决方案,这次使用递归来找到第 n 个谐波数。
General implementation details
一般实施细节
Function Prototype:harmonic_recursive(n)
函数原型:harmonic_recursive(n)
Function Parameters:n
- the n-th Harmonic number
函数参数:n
- 第 n 个谐波数
Base case:If n
equals 1
return 1.
基本情况:如果n
等于1
返回 1。
Recur step:If not the base case, call harmonic_recursive
for the n-1
term and add that result with 1/n
. This way we add each time the i-th term of the Harmonic series with the sum of all the previous terms until that point.
重复步骤:如果不是基本情况,则调用harmonic_recursive
该n-1
术语并将该结果与 相加1/n
。通过这种方式,我们每次都将谐波级数的第 i 项与之前所有项的总和相加,直到该点为止。
Pseudocode
伪代码
(this solution can be implemented easily in other languages too.)
(这个解决方案也可以用其他语言轻松实现。)
harmonic_recursive(n):
if n == 1:
return 1
else:
return 1/n + harmonic_recursive(n-1)
Python code
Python代码
def harmonic_recursive(n):
if n == 1:
return 1
else:
return 1.0/n + harmonic_recursive(n-1)