piRamanujan.frink

View or download piRamanujan.frink in plain text format

// System to calculate digits of pi.
// ftp://rtfm.mit.edu/pub/usenet/sci.math/sci.math_FAQ%3A_Digits_or_Pi
//
// This uses Ramanujan's equation for pi, which converges very rapidly.
// It adds approximately 8 decimal places for each iteration through the loop.

// Most of the class is for caching so repeated calls are efficient.
// Users should use the Pi.getPi[] method which performs caching.

use root.frink

class Pi
{
   // This is a cache of digits of pi keyed by digits.
   class var cachedPiDict = new dict

   // This is a cache of digits of sqrt[K3] keyed by digits.
   class var cachedK3Dict = new dict

   // The number of digits in the biggest cached value.
   class var biggestCachedDigitsPi = -1

   // The number of digits in the biggest cached value.
   class var biggestCachedDigitsK3 = -1

   // The biggest calculated cached value of pi.
   class var biggestCachePi = undef
   
   // The biggest calculated cached root of k3
   class var biggestCacheK3 = undef
   
   // get pi to the specified number of digits, with caching
   class getPi[digits] :=
   {
      digits = ceil[digits]
      cachedVal = cachedPiDict@digits
      if cachedVal != undef
         return cachedVal
      else                      // Must generate it
         if digits <= biggestCachedDigitsPi
         {
            prevPrec = getPrecision[]
            try
            {
               setPrecision[digits]
               val = 1. * biggestCachePi  // Generate from cached value
               cachedPiDict@digits = val
               return val
            }
            finally
               setPrecision[prevPrec]
         } else
         {
            // Generate whole thing
            val = calculatePi[digits]
            cachedPiDict@digits = val
            biggestCachePi = val
            biggestCachedDigitsPi = digits
            return val
         }
   }

   // Calculate pi to the specified number of digits.
   // You shouldn't call this method directly, but rather call getPi[digits]
   // which does caching.
   class calculatePi[digits] :=
   {
      k1 = 545140134
      k2 = 13591409
      k3 = 640320
      k4 = 100100025
      k5 = 327843840
      k6 = 53360

      dn = 8 k4 k5

      s=0
      mypi = 0

      prevPrec = getPrecision[]

      try
      {
         setPrecision[digits+3]

         err = 10^(-digits-1)
         //println["Err is $err"]
         n = 0

         do
         {
            term = (-1)^n ((6n)! (k2 + n k1)) / ((n!)^3 (3n)! dn^n)
            s = s + term
            //   if (n mod 100 == 0)
            //      print["$n..."]
            n = n + 1
         } while (abs[term] > err)

         //println["Used $n terms"]

         //println["Taking root"]

         sqrk = getRootK3[digits+3]

         mypi = k6 / s sqrk

         setPrecision[digits]
         return mypi * 1.
      }
      finally
         setPrecision[prevPrec]
   }


   // get the root of k3 to the specified number of digits, with caching.
   class getRootK3[digits] :=
   {
      digits = ceil[digits]
      cachedVal = cachedK3Dict@digits
      if cachedVal != undef
         return cachedVal
      else                      // Must generate it
         if digits <= biggestCachedDigitsK3
         {
            prevPrec = getPrecision[]
            try
            {
               setPrecision[digits]
               val = 1. * biggestCacheK3  // Generate from cached value
               cachedK3Dict@digits = val
               return val
            }
            finally
               setPrecision[prevPrec]
         } else
         {
            // Generate whole thing
            val = sqrt[640320, digits]
            cachedK3Dict@digits = val
            biggestCacheK3 = val
            biggestCachedDigitsK3 = digits
            return val
         }
   }
}

//start = now[]
//println[Pi.getPi[10000]]
//end = now[]
//println["Total time: " + (end-start)]
//println[Pi.getPi[40]]
//println[Pi.getPi[5000]]

//   pifull = 3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316527120190914564856692346034861045432664821339360726024914127372458700660631558817488152092096282925409171536436789259036001133053054882046652138414695194151160943305727036575959195309218611738193261179310511854807446237996274956735188575272489122793818301194912983367336244065664308602139494639522473719070217986094370277053921717629317675238467481846766940513200056812714526356082778577134275778960917363717872146844090122495343014654958537105079227968925892354201995611212902196086403441815981362977477130996051870721134999999837297804995105973173281609631859502445945534690830264252230825334468503526193118817101000313783875288658753320838142061717766914730359825349042875546873115956286388235378759375195778185778053217122680661300192787661119590921642019893809525720106548586327886593615338182796823030195203530185296899577362259941389124972177528347913151557485724245415069595082953311686172785588907509838175463746493931925506040092770167113900984882401285836160356370766010471018194295559619894676783744944825537977472684710404753464620804668425906949129331367702898915210475216205696602405803815019351125338243003558764024749647326391419927260426992279678235478163600934172164121992458631503028618297455570674983850549458858692699569092721079750930295532116534498720275596023648066549911988183479775356636980742654252786255181841757467289097777279380008164706001614524919217321721477235014144197356854816136115735255213347574184946843852332390739414333454776241686251898356948556209921922218427255025425688767179049460165346680498862723279178608578438382796797668145410095388378636095068006422512520511739298489608412848862694560424196528502221066118630674427862203919494504712371378696095636437191728746776465757396241389086583264599581339047802759009946576407895126946839835259570982582262052248940772671947826848260147699090264013639443745530506820349625245174939965143142980919065925093722169646151570985838741059788595977297549893016175392846813826868386894277415599185592524595395943104997252468084598727364469584865383673622262609912460805124388439045124413654976278079771569143599770012961608944169486855584840635342207222582848864815845602850601684273945226746767889525213852254995466672782398645659611635488623057745649803559363456817432411251507606947945109659609402522887971089314566913686722874894056010150330861792868092087476091782493858900971490967598526136554978189312978482168299894872265880485756401427047755513237964145152374623436454285844479526586782105114135473573952311342716610213596953623144295248493718711014576540359027993440374200731057853906219838744780847848968332144571386875194350643021845319104848100537061468067491927


View or download piRamanujan.frink in plain text format


This is a program written in the programming language Frink.
For more information, view the Frink Documentation or see More Sample Frink Programs.

Alan Eliasen was born 17891 days, 12 hours, 13 minutes ago.