用于计算谐波系列的Python程序

时间:2009-01-01 00:55:17

标签: python math

有没有人知道如何用Python编写程序来计算谐波系列的加法。即1 + 1/2 +1/3 +1/4 ......

11 个答案:

答案 0 :(得分:21)

@Kiv's answer是正确的,但如果你不需要无限精度,它对于大n来说很慢。在这种情况下最好使用asymptotic formula

asymptotic expansion for harmonic number

#!/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)
Python 2.6的

@Kiv's answer

from fractions import Fraction

harmonic_number = lambda n: sum(Fraction(1, d) for d in xrange(1, n+1))

示例:

>>> 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

N = 100相对误差小于1e-15

答案 1 :(得分:12)

@recursive's solution对于浮点近似是正确的。如果您愿意,可以使用分数模块在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)

请注意,位数会快速增长,因此对于较大的n,这将需要大量内存。如果你想真正想要的话,你也可以使用生成器来查看一系列的部分和。

答案 2 :(得分:5)

使用浮点的其他答案的脚注;从最大除数开始并向向下(向具有最大值的倒数)迭代将尽可能地推迟累积的舍入误差。

答案 3 :(得分:4)

谐波系列发散,即其总和为无穷大。

编辑:除非你想要部分总和,否则你并不是很清楚。

答案 4 :(得分:4)

可以使用digamma函数计算快速,准确,平滑,复值的H函数版本,如here所述。 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)


以下是速度和精度的三种方法的比较(以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

答案 5 :(得分:2)

这应该可以解决问题。

def calc_harmonic(n):
    return sum(1.0/d for d in range(2,n+1))

答案 6 :(得分:0)

这个怎么样:

partialsum = 0
for i in xrange(1,1000000):
    partialsum += 1.0 / i
print partialsum

其中1000000是上限。

答案 7 :(得分:0)

作业?

这是一个不同的系列,因此无法对所有术语进行总结。

我不懂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;
     }
 }

答案 8 :(得分:0)

我添加另一个解决方案,这次使用递归,找到第n个谐波数。

一般实施细节

功能原型: harmonic_recursive(n)

功能参数: n - 第n个谐波数

基本情况:如果n等于1则返回1.

重复步骤:如果不是基本案例,请为harmonic_recursive字词调用n-1,并将结果添加到1/n。这样我们每次将Harmonic系列的第i个项加上所有先前项的总和,直到那一点。

伪代码

(此解决方案也可以在其他语言中轻松实现。)

harmonic_recursive(n):
    if n == 1:
        return 1
    else:
        return 1/n + harmonic_recursive(n-1)

Python代码

def harmonic_recursive(n):
    if n == 1:
        return 1
    else:
        return 1.0/n + harmonic_recursive(n-1)

答案 9 :(得分:0)

通过使用numpy模块,您还可以使用:

import numpy as np
def HN(n):
    return sum(1/arange(1,n+1))

答案 10 :(得分:-1)

使用简单的for循环

def harmonicNumber(n):
x=0
for i in range (0,n):
    x=x+ 1/(i+1)
return x