Learning in Stereo: Math + Python

David C. Ullrich ullrich at math.okstate.edu
Tue Apr 4 14:21:19 EDT 2000


Kirby Urner wrote:

> [...]
> And here's another fast converger [to pi] using every other
> Fibonacci number:
>
> def pifib(n):
>    # return approximation for pi using
>    # arctan(1) = 4 * SIGMA [ arctan(1.0/Fib(2i+1))]
>    sum = 0
>    for i in range(1,n+1):
>       sum = sum + math.atan(1.0/fibo(2*i+1))
>    return 4*sum

    I didn't know that arctan(1) was equal to that sum, fascinating.
But I don't quite see the point to using that as a way to "calculate"
arctan(1) - seems like the call to math.atan is cheating, if we're
gonna do that why not just call math.atan(1)?

    Now if we were calculating the arctangents by hand that might
be different - there's an easy and fairly efficient way to find
arctan(x) for |x| < 1 that doesn't work for |x| > 1 (and just
barely works for |x| = 1), ie the power series; so there's
a possible point to finding arctan(1) using arctan(1/fib) in that
case.
    You might note that pi/6 = arctan(1/sqrt(3)). The power series
for arctan(1/sqrt(3)) converges pretty fast, and you can make
the calculations go pretty quick as well, if you note that
(sqrt(3))**(2*k+1) = sqrt(3)*(3**k); you factor out one
sqrt(3) and in the inner loop you have almost nothing but
integer computations. (I got 7,000 digits of pi this morning
in about two minutes this way. Using ordinary floats it's

def floatpi(n):
  """Gets pi from the power series for arctan(1/sqrt(3)) -
factors out some stuff and combined pairs of terms... """
  eps = 10.0**(-n)
  pow = 1L
  term = 1.0 #just to make the first test succeed
  p=0.0
  j=0
  while abs(term) > eps:
    term=float(j+1)/((4*j+1)*(4*j+3)*pow)
    p=p+term
    pow=9*pow
    j=j+1
  return (16/math.sqrt(3))*p

The error's just a little larger than the first omitted term,
so floatpi(n) should give pi to n places. And it only takes
about n terms to get there. Probably worrying about the
"optimizations" doesn't make much sense here - makes
more sense when dealing with high-precision (slow) reals.)

    Or you could use someone's formula

pi = 16*atan(1/5) - 4*atan(1/239)

to get faster convergence (although explaining why the
formula is valid might not be quite as straightforward as
pi = 6*atan(1/sqrt(3)) - dunno if we mean to include
explanations of that sort of thing or not).

DU





More information about the Python-list mailing list