Программа Python для вычисления гармонических рядов

Кто-нибудь знает, как написать программу на Python, которая будет вычислять добавление гармонического ряда. т.е. 1 + 1/2 +1/3 +1/4 …

10 Solutions collect form web for “Программа Python для вычисления гармонических рядов”

@ Ответ Кива правильный, но он медленный для больших 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) 

@ Ответ Кива для Python 2.6:

 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 .

Рекурсивное решение является правильным для приближения с плавающей запятой. Если вы предпочитаете, вы можете получить точный ответ в 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 потребуется много памяти. Вы также можете использовать генератор, чтобы посмотреть на серию частичных сумм, если вы хотите получить действительно фантазию.

Просто примечание к другим ответам, в которых используется плавающая точка; начиная с самого большого делителя и итерируя вниз (в сторону обратных с наибольшим значением), максимально отложит скопированную ошибку округления.

Гармонический ряд расходится, т. Е. Его сумма бесконечна.

edit: Если вы не хотите частичных сумм, но вы не совсем поняли об этом.

Быстрая, точная, гладкая, комплекснозначная версия функции H может быть рассчитана с использованием функции дигаммы, как объяснено здесь . Константа Эйлера-Маскерони (гамма) и функция дигама доступны в библиотеках 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)
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

Это должно сделать трюк.

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

Как насчет этого:

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

где 1000000 – верхняя граница.

Домашнее задание?

Это расходящаяся серия, поэтому невозможно суммировать ее для всех условий.

Я не знаю 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; } } 

Я добавлю другое решение, на этот раз используя рекурсию, чтобы найти n-й номер гармоники.

Общие сведения о реализации

Функция Prototype: harmonic_recursive(n)

Параметры функции: n – n-й гармонический номер

Базовый регистр: если n равно 1 возвращайте 1.

Шаг повтора: если нет базового случая, вызовите harmonic_recursive для n-1 и добавьте этот результат с 1/n . Таким образом мы каждый раз добавляем 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) 

Использование простого цикла

 def harmonicNumber(n): x=0 for i in range (0,n): x=x+ 1/(i+1) return x 
  • Требуется ли выражение math.sqrt ()?
  • Оценка выражения математики
  • Что делает оператор ^ (XOR)?
  • Ошибка ValueError: ошибка в области математики, продолжает появляться
  • Установка Mathics под Mac OS X
  • вращающаяся система координат через кватернион
  • Ошибки в программе для вычисления интегралов
  • Почему 0 ** 0 равно 1 в python
  • Python - лучший язык программирования в мире.