
and

where ζ(s) is the Riemann zeta function. Both formulas follow trivially from the properties of the digamma function, but if I didn't know that, I'd find them pretty neat.


>>> from sympy import *
>>> var('n x')
(n, x)
>>> (log(1+I)/pi).evalf(50)
0.11031780007632579669822821605899884549134487436483 + 0.25*I
>>> (atan(exp(1000))-pi/2).evalf(15, maxprec=1000)
-5.07595889754946e-435
>>> Integral(exp(-x**2), (x, -oo, oo)).evalf(50)
1.7724538509055160272981674833411451827975494561224
>>> Integral(sin(1/x), (x, 0, 1)).transform(x, 1/x).evalf(25, quad='osc')
0.5040670619069283719898561
>>> Sum(1/(9*n**2+4*n+6), (n, 0, oo)).evalf(50)
0.27865709939940301230611638967893239422996461876558
>>> Sum(1/n-log(1+1/n), (n, 1, oo)).evalf(50)
0.57721566490153286060651209008240243104215933593992
>>> Derivative(-gamma(x), x).evalf(50, subs={x:1})
0.57721566490153286060651209008240243104215933593992
>>> time_division(int, 2.0, 20)
size old time new time faster correct
------------------------------------------------------------
16 0.000008 0.000052 0.155080 True
32 0.000005 0.000052 0.102151 True
64 0.000008 0.000059 0.132075 True
128 0.000013 0.000070 0.190476 True
256 0.000035 0.000107 0.325521 True
512 0.000126 0.000215 0.583658 True
1024 0.000431 0.000532 0.810399 True
2048 0.001855 0.001552 1.195104 True
4096 0.007154 0.005050 1.416708 True
8192 0.028505 0.015449 1.845033 True
16384 0.111193 0.046938 2.368925 True
32768 0.443435 0.142551 3.110706 True
65536 1.778292 0.432412 4.112497 True
131072 7.110184 1.305771 5.445200 True
262144 28.596926 3.919399 7.296253 True
524288 116.069764 11.804032 9.833061 True
>>> time_str(int, 20)
size old time new time faster correct
------------------------------------------------------------
16 0.000005 0.000013 0.413043 True
32 0.000006 0.000009 0.588235 True
64 0.000008 0.000012 0.674419 True
128 0.000020 0.000023 0.865854 True
256 0.000059 0.000133 0.442105 True
512 0.000204 0.000333 0.613255 True
1024 0.000895 0.001194 0.749708 True
2048 0.003505 0.002252 1.556824 True
4096 0.013645 0.006600 2.067429 True
8192 0.052386 0.018334 2.857358 True
16384 0.209164 0.052233 4.004412 True
32768 0.834201 0.153238 5.443827 True
65536 3.339629 0.450897 7.406639 True
131072 13.372223 1.339044 9.986392 True
262144 53.547894 3.998352 13.392491 True
524288 214.847486 11.966933 17.953429 True
from mpmath.lib import giant_steps, lshift, rshift
from math import log
START_PREC = 15
def size(x):
if isinstance(x, (int, long)):
return int(log(x,2))
# GMPY support
return x.numdigits(2)
def newdiv(p, q):
szp = size(p)
szq = size(q)
szr = szp - szq
if min(szp, szq, szr) < 2*START_PREC:
return p//q
r = (1 << (2*START_PREC)) // (q >> (szq - START_PREC))
last_prec = START_PREC
for prec in giant_steps(START_PREC, szr):
a = lshift(r, prec-last_prec+1)
b = rshift(r**2 * rshift(q, szq-prec), 2*last_prec)
r = a - b
last_prec = prec
return ((p >> szq) * r) >> szr
from time import clock
def timing(INT):
fmt = "%10s %12f %12f %12f %8s"
print "%10s %12s %12s %12s %8s" % ("size", "old time", "new time",
"faster", "error")
print "-"*78
for i in range(4,30):
n = 2**i
Q = INT(10)**n
P = Q**2
t1 = clock()
R1 = P // Q
t2 = clock()
R2 = newdiv(P,Q)
t3 = clock()
size, old_time, new_time = n, t2-t1, t3-t2
faster, error = old_time/new_time, R2-R1
print fmt % (size, old_time, new_time, faster, error)
timing(int)
size old time new time faster error
--------------------------------------------------------------
16 0.000005 0.000101 0.050000 -1
32 0.000005 0.000044 0.107595 -1
64 0.000006 0.000052 0.123656 0
128 0.000013 0.000064 0.197368 0
256 0.000033 0.000088 0.377778 -1
512 0.000115 0.000173 0.663430 0
1024 0.000413 0.000399 1.035689 1
2048 0.001629 0.001099 1.481576 0
4096 0.006453 0.004292 1.503352 -1
8192 0.025596 0.009966 2.568285 0
16384 0.101964 0.030327 3.362182 -1
32768 0.408266 0.091811 4.446792 -1
65536 1.633296 0.278531 5.863967 -1
131072 6.535185 0.834847 7.828001 0
262144 26.108710 2.517134 10.372397 0
524288 104.445635 7.576984 13.784593 -1
1048576 418.701976 22.760790 18.395758 0
from gmpy import mpz
timing(mpz)
size old time new time faster error
--------------------------------------------------------------
16 0.000011 0.000068 0.168033 -3
32 0.000008 0.000045 0.185185 -2
64 0.000006 0.000047 0.137725 -1
128 0.000005 0.000053 0.089005 -2
256 0.000007 0.000070 0.099602 0
512 0.000015 0.000083 0.184564 -1
1024 0.000044 0.000156 0.282143 0
2048 0.000134 0.000279 0.481000 -1
4096 0.000404 0.000657 0.614960 -2
8192 0.001184 0.001719 0.688882 -1
16384 0.003481 0.004585 0.759322 -2
32768 0.009980 0.012043 0.828671 -1
65536 0.027762 0.028783 0.964516 -1
131072 0.072987 0.067773 1.076926 -1
262144 0.186714 0.151604 1.231588 -1
524288 0.462057 0.342160 1.350411 -1
1048576 1.119103 0.788582 1.419134 -2
2097152 2.726458 1.838570 1.482923 -1
4194304 6.607204 4.069614 1.623546 -1
8388608 15.627027 8.980883 1.740032 -1
16777216 36.581787 19.167144 1.908567 -4
33554432 83.568330 40.131393 2.082368 -1
67108864 190.596889 81.412867 2.341115 -1


>>> from sympy import hypersimp, var, factorial
>>> var('n')
n
>>> pprint(hypersimp(factorial(n)**2 / factorial(2*n), n))
1 + n
-------
2 + 4*n
from sympy import hypersimp, lambdify
from sympy.mpmath.lib import MP_BASE, from_man_exp
from sympy.mpmath import mpf, mp
def hypsum(expr, n, start=0):
"""
Sum a rapidly convergent infinite hypergeometric series with
given general term, e.g. e = hypsum(1/factorial(n), n). The
quotient between successive terms must be a quotient of integer
polynomials.
"""
expr = expr.subs(n, n+start)
num, den = hypersimp(expr, n).as_numer_denom()
func1 = lambdify(n, num)
func2 = lambdify(n, den)
prec = mp.prec + 20
one = MP_BASE(1) << prec
term = expr.subs(n, 0)
term = (MP_BASE(term.p) << prec) // term.q
s = term
k = 1
while abs(term) > 5:
term *= MP_BASE(func1(k-1))
term //= MP_BASE(func2(k-1))
s += term
k += 1
return mpf(from_man_exp(s, -prec))
from sympy import factorial, var, Rational, binomial
from sympy.mpmath import sqrt
var('n')
fac = factorial
Q = Rational
mp.dps = 1000 # sum to 1000 digit accuracy
print hypsum(1/fac(n), n)
print 1/hypsum((1-2*n)/fac(2*n), n)
print hypsum((2*n+1)/fac(2*n), n)
print hypsum((4*n+3)/2**(2*n+1)/fac(2*n+1), n)**2
print 9801/sqrt(8)/hypsum(fac(4*n)*(1103+26390*n)/fac(n)**4/396**(4*n), n)
print 1/hypsum(binomial(2*n,n)**3 * (42*n+5)/2**(12*n+4), n)
print 16*hypsum((-1)**n/(2*n+1)/5**(2*n+1), n) - \
4*hypsum((-1)**n/(2*n+1)/239**(2*n+1), n)
print hypsum(fac(2*n+1)/fac(n)**2/2**(3*n+1), n)
print 1./64*hypsum((-1)**(n-1)*2**(8*n)*(40*n**2-24*n+3)*fac(2*n)**3*\
fac(n)**2/n**3/(2*n-1)/fac(4*n)**2, n, start=1)
print hypsum(Q(5,2)*(-1)**(n-1)*fac(n)**2 / n**3 / fac(2*n), n, start=1)
print hypsum(Q(1,4)*(-1)**(n-1)*(56*n**2-32*n+5) / \
(2*n-1)**2 * fac(n-1)**3 / fac(3*n), n, start=1)
print hypsum((-1)**n * (205*n**2 + 250*n + 77)/64 * \
fac(n)**10 / fac(2*n+1)**5, n)
P = 126392*n**5 + 412708*n**4 + 531578*n**3 + 336367*n**2 + 104000*n + 12463
print hypsum((-1)**n * P / 24 * (fac(2*n+1)*fac(2*n)*fac(n))**3 / \
fac(3*n+2) / fac(4*n+3)**3, n)
>>> from sympy import *
>>> fac = factorial
>>> var('n')
n
>>> P = fac(6*n)*(13591409+545140134*n)
>>> Q = fac(3*n)*fac(n)**3*(-640320)**(3*n)
>>> R = hypersimp(P/Q,n)
>>> abs(1/limit(R, n, oo))
151931373056000
>>> log(_,10).evalf()
14.1816474627255
>>> S = Sum(2**n/factorial(n), (n, 0, oo))
>>> S.evalf(1000)
>>> from mpmath import mp, pi
>>> mp.dps = 10**6
>>> print pi
>>> N('log(2)', 50)
'0.69314718055994530941723212145817656807550013436026'
>>> N('16*atan(1/5) - 4*atan(1/239)', 50)
'3.1415926535897932384626433832795028841971693993751'
>>> N('log(2**(1/10**20))',15)
'6.93147180559945e-21'
>>> from sympy import *
>>> var('x')
x
>>> gauss = Integral(exp(-x**2), (x, -oo, oo))
>>> N(gauss, 15)
'1.77245385090552'
>>> N(gauss - sqrt(pi) + E*Rational(1,10**20), 15)
'2.71828182845904e-20'
>>> N('(1/3+2*I)*(2+1/3*I)', 10)
'.0e-12 + 4.111111111*I'
>>> N('(1/3+2*I)*(2+1/3*I) - 37/9*I + pi/10**50', 10)
'3.141592654e-50 + .0e-62*I'
>>> N('(1/3+2*I)*(2+1/3*I) - (37/9 - 1/10**15)*I', 10)
'.0e-30 + 1.0e-15*I'
>>> N('(1/3+2*I)*(2+1/3*I) - 37/9*I, 10)
C:\Source\mp\trunk\demo>pidigits.py
Compute digits of pi with mpmath
Which base? (2-36, 10 for decimal)
> 10
How many digits? (enter a big number, say, 10000)
> 1000000
Output to file? (enter a filename, or just press enter
to print directly to the screen)
> pi.txt
Step 1 of 2: calculating binary value...
iteration 1 (accuracy ~= 0 base-10 digits)
iteration 2 (accuracy ~= 2 base-10 digits)
iteration 3 (accuracy ~= 4 base-10 digits)
iteration 4 (accuracy ~= 10 base-10 digits)
iteration 5 (accuracy ~= 21 base-10 digits)
iteration 6 (accuracy ~= 43 base-10 digits)
iteration 7 (accuracy ~= 86 base-10 digits)
iteration 8 (accuracy ~= 173 base-10 digits)
iteration 9 (accuracy ~= 348 base-10 digits)
iteration 10 (accuracy ~= 697 base-10 digits)
iteration 11 (accuracy ~= 1396 base-10 digits)
iteration 12 (accuracy ~= 2793 base-10 digits)
iteration 13 (accuracy ~= 5587 base-10 digits)
iteration 14 (accuracy ~= 11176 base-10 digits)
iteration 15 (accuracy ~= 22353 base-10 digits)
iteration 16 (accuracy ~= 44707 base-10 digits)
iteration 17 (accuracy ~= 89414 base-10 digits)
iteration 18 (accuracy ~= 178830 base-10 digits)
iteration 19 (accuracy ~= 357662 base-10 digits)
iteration 20 (accuracy ~= 715325 base-10 digits)
iteration 21 (accuracy ~= 1000017 base-10 digits)
final division
Step 2 of 2: converting to specified base...
Writing output...
Finished in 28.540354 seconds (26.498292 calc, 2.042062 convert)
The range of problems we currently attack can be described as follows: Imagine a light beam incident on some solid body, e.g., a semiconductor crystal of some 50 micrometers length. When the light propagates into the sample it gets damped, and its strength will sooner or later become incredibly small, i.e., it can no longer be held in a double precision float variable.
However, a lot of interesting things can be calculated with the help of these electromagnetic field strength, such as predictions for the output of semiconductor lasers or signs for the much-sought-after Bose-Einstein condensation of excitons (electron-hole pairs in a semiconductor). I sure shouldn't go much more into detail here, as I suppose you're not a physicist.
Just one example: As a consistency check, the equation
1 - |r|^2 - |t|^2 = \int dx dx' A(x') chi(x,x') A(x)
should be fullfilled for any light frequency. r, t, A(x) are complex electromagnetic field strengths and just cannot be calculated with machine precision alone, not to mention further calculations based on them. (Chi is the susceptibility and describes the electromagnetic properties of the matter).
However, due to the magic of math (and mpmath ;-) ), the interplay of these incredibly small numbers yields two perfectly equal numbers between 0 and 1, as it should.
I'm really happy having chosen Python for my work. Mpmath fits in well, its so easy to use. I especially like the operator overloading, so that I may add some complex multiprecision numbers with a simple "+". And mpmath's mathematical and numerical function library is so extensive that it can take you really a long way.