# BinarySplittingExp.frink

``` /** This class is an example of using the BinarySplitting.frink file to     calculate exp[x] to arbitrary precision.  It follows the algorithm     described in:    "Fast multiprecision evaluation of series of rational numbers" by Bruno     Hible and Thomas Papanikolaou:     https://ginac.de/CLN/binsplit.pdf        See the references in that paper for discussion of the parameters.  See     section 2.2.1 for the algorithm for exp[x].     Call BinarySplittingExp.exp[digits] to calculate the specified number of     digits.     TODO:  This is incomplete and needs a better algorithm to calculate the     number of iterations because the equation given in the paper is not useful.     Also see:     https://stackoverflow.com/questions/57510825/binary-splitting-in-pari-gp */ use BinarySplitting.frink      class BinarySplittingExp implements ParamProvider {    // The numerator    var u    // The denominator    var v    new[num, denom] :=    {       u = num       v = denom    }        /** Call this method with the number of digits of exp[x] you want to    calculate.  */    class exp[x, digits] :=    {       [u,v] = numeratorDenominator[toRational[x]]       splitter = new BinarySplittingExp[u,v]       origPrec = getPrecision[]       try       {          setPrecision          d1 = log[digits]          d2 = log[1/abs[x]]          d = d1 + d2          println["d1 is \$d1"]          println["d2 is \$d2"]          println["d  is \$d"]          reps = ceil[digits / d * 1.43]  // Found empirically for some numbers          setPrecision[digits+3]          println["reps is \$reps"]          return BinarySplitting.calc[splitter, 0, reps, digits]       }       finally          setPrecision[origPrec]    }    /** Implementation of the ParamProvider interface. */    a[n] := 1    b[n] := 1    p[n] :=    {       if n == 0          return 1       else          return u    }    q[n] :=    {       if n <= 0          return 1       else          return n v    } } use ArbitraryPrecision.frink test[x,digits] := {    s = now[]    c = arbitraryExp[x, digits]    e = now[]    println["calculated c  in " + format[e-s, "ms", 0]]    s = now[]    bs = BinarySplittingExp.exp[x, digits]    e = now[]    println["calculated bs in " + format[e-s, "ms", 0]]        setPrecision[digits]    println["diff is " + (c-bs)] }```