Feeding The Snake
Thoughts on Python, Science, Culture, and Life
        

Getting Started and Having Fun with GMPY

Rick Muller

Overview

GMPY is the General Multiprecision Python project, which is a set of Pythonwrappers to the Gnu Multiple Precision (GMP)arithmetic library.

This document gives a casual introduction to GMPY, since it's one of my favorite Python modules, and is intended for people who want to investigate some of the features that the module makes available. If you are a serious mathematician you will probably provide the discussion herein lacking, and should probably refer to the GMP documentation.

What is multiprecision arithmetic?

To be completed.

What types and functions does GMPY provide?

There are three basic types that GMPY provides:

  • mpz, for integers,
  • mpf, for floats,
  • mpq, for rational numbers.

The examples described here will use these types with a few other functions, including

  • pi, which computes pi as an mpf object,
  • fac, which returns the factorial as an mpz object.

Examples of GMPY use

Computing pi

There are numerous methods of computing the number pi; Googling "compute pi" will bring up a large number of sites. But there are many very simple methods forcomputing pi that can do so with surprising accuracy.

GMPY has a builtin method for computing pi. The documentation shows that

pi(n): returns pi with n bits of precision in an mpf object
so we can, for example, call
>>> pi(100)

mpf('3.141592653589793238462643383279502884197e0',100)
and obtain a fairly good approximation to pi. Using a higher precision, of course, gives more digits. The GMPY pi function is the best way to get a large number of digits for pi.

However, there are also a number of simple methods for computing pi, and, if you're interested in understanding how these constants are computed, GMPY can give you a nice set of tools for exploring thesetechniques.

The simplest algorithm for computing pi is

from gmpy import *
def pi_simple(npts=100):
    hits = mpz(0)
    for i in range(npts):
        x,y = rand('floa'),rand('floa')
        if x*x+y*y < 1: hits += 1
    return mpf(mpq(4*hits,npts))

The problem with this algorithm is that, unless you use a ridiculous number of points, you would be just as well off using normal Python floats, ints, and random numbers.

Another much, much better method of computing pi relies on Ramanujan's sequence

from gmpy import *
def pi_rama(npts=100,prec=1000):
    pre = mpf(8,prec).sqrt() / mpf(9801,prec)
    sum = mpq(0)
    c1103 = mpz(1103)
    c26390 = mpz(26390)
    c396 = mpz(396)
    for i in range(npts):
        num = fac(4*i)*(c1103+c26390*i)
        denom = pow(fac(i),4)*pow(c396,4*i)
        sum += mpq(num,denom)
    return mpf(mpq(mpz(1),pre*sum),prec)

Given enough steps and a high enough precision, this function will match the GMPY version of pi digit for digit.

Computing e

We can compute e using the Taylor series
from gmpy import *

def gmpy_e(npts=100, prec=1000):
    e = mpq(1)
    for i in range(1,npts): e += mpq(1,fac(i))
    return mpf(e,prec)
which will again give a large number of digits of e.



© Copyright 2005 Rick Muller. Click here to send an email to the editor of this weblog.
Last update: 3/30/05; 9:12:13 AM.