Reputation: 11670
I'm trying to plot a function in python that has infinite sum in it. Now, since there are no infinities in computing, for my upper bound I can choose a really big number, and that's fine.
So I tried to plot it:
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)
And I tried to decrease the xrange (or range), and increase the linspace (from 0, 35 in more than 1000 points), but I'm getting either:
OverflowError: long int too large to convert to int
or
OverflowError: range() result has too many items
So what seems to be the problem here? How can I make the sum big? Is the syntax of the sum correct?
Upvotes: 1
Views: 3844
Reputation: 21035
That loop can't possibly end during your lifetime. 10 ** 100
is a really really enormous number. It's bigger than the number of particles in the universe, it's bigger than the number of the tiniest time periods that have passed since the creation of the universe. On an impossibly fast computer - 3 * 10 ** 46
millennia for the loop to complete. To calculate an infinite sum you'd wish to calculate until the sum has stopped changing significantly (e.g. the summands have fallen under certain very small threshold).
Also, xrange
and range
in Python 2 are limited to the platform's long integers, which means that you can't have numbers higher than 2 ** 31 on a 32 bit machine and 2 ** 63 on a 64 bit one, (the latter is still too big to ever complete in your lifetime), this is why you get an OverflowError
in Python 2. In Python 3 you'd get no error, but the summation will continue forever.
And calculation factorial of such a large number is even slower, so you don't have a chance to ever exceed the maximum even on a 32 bit machine.
Search for a function for calculating infinite sums, or do it yourself
>>> 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
Also, I do not recognize the formula, but is this supposed to be (e ** 16) * factorial(n)
or e ** (16 * factorial(n))
? I just want to point out that you've written the former because of the other answer.
Upvotes: 6
Reputation: 123612
EDIT: misread the parentheses
Your sum has 1/n!
in it. That means that the terms decay REALLY REALLY REALLY fast, so there's no need whatsoever to make the sum go up to 10*100: try instead 100, which should be a perfectly good upper limit for you. In fact, it's absurd to try to work out the terms up to that kind of order of magnitude, because it means the computer has to work out (10**100)!.
Upvotes: 0