在Python中绘制求和图

1 投票
2 回答
3755 浏览
提问于 2025-04-16 18:07

我正在尝试在Python中绘制一个包含无限求和的函数。因为计算机里没有真正的“无穷大”,所以我可以选择一个非常大的数字作为上限,这样就可以了。

于是我尝试绘制这个函数:

from scitools.std import *
from math import *
import numpy as np

def f1(t):
    return 0.5*(1+sum((4**(2*n)*cos(2*n*t))/(e**16*factorial(n)) for n in xrange(0,10**100)))

t = linspace(0, 35, 10000)
y1 = f1(t)

plot(t, y1)

xlabel(r'$\tau$')
ylabel(r'P($\tau$)')
legend(r'P($\tau$)')
grid(True)

然后我试着减小x范围(或者说范围),并增加线性空间(从0到35,分成超过1000个点),但是我得到的结果是:

OverflowError: long int too large to convert to int

或者

OverflowError: range() result has too many items

那么,这里似乎有什么问题呢?我该如何让这个求和变得更大?求和的语法正确吗?

2 个回答

0

编辑:我看错括号了

你的求和公式里有 1/n! 这个部分。这意味着这些项的值下降得非常非常快,所以根本不需要把求和的范围扩大到 10*100。你可以试试用 100,这个上限就足够了。实际上,试图计算到那么大的数是很荒谬的,因为这意味着计算机需要计算 (10**100)!。

6

这个循环在你的一生中是绝对不可能结束的。10 ** 100 是个非常非常大的数字,甚至比宇宙中的粒子数量还要多,比宇宙诞生以来经过的最小时间段还要大。即使是在一个超级快的电脑上,这个循环也需要 3 * 10 ** 46 年才能完成。计算一个无限的总和时,你希望计算到总和不再有明显变化为止(比如说,计算的每一项都小于某个非常小的阈值)。

另外,在 Python 2 中,xrangerange 的数字范围是受限于平台的长整型,这意味着在 32 位机器上你不能有超过 2 ** 31 的数字,而在 64 位机器上不能超过 2 ** 63(后者依然太大,根本不可能在你的一生中完成),这就是为什么在 Python 2 中你会遇到 OverflowError 的原因。在 Python 3 中你不会遇到错误,但总和会一直计算下去。

而计算这么大数字的阶乘会更慢,所以即使在 32 位机器上,你也没有机会超过这个最大值。

你可以搜索一个计算无限总和的函数,或者自己动手做。

>>> from __future__ import division
>>> import itertools
>>> from math import factorial, cos, e
>>> for t in [0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.1]:
...     summables = ((4 ** (2 * n) * cos(2 * n * t)) / (e ** 16 * factorial(n)) 
...                  for n in itertools.count())
...     print 0.5 * (1 + sum(itertools.takewhile(lambda x: abs(x) > 1e-80, summables)))
... 
1.0
0.973104754771
0.89599816753
0.77928588758
0.65382602277
0.569532373683
0.529115621076
0.512624956755
0.505673516974
0.502777962546
0.501396442319

另外,我不太明白这个公式,但它应该是 (e ** 16) * factorial(n) 还是 e ** (16 * factorial(n))?我只是想指出你写的是前者,因为其他回答的原因。

撰写回答