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 17590 days, 6 hours, 44 minutes ago.