ProfJCNash
2015-Jul-05 01:42 UTC
[R] : Ramanujan and the accuracy of floating point computations - using Rmpfr in R
n163 <- mpfr(163, 500) is how I set up the number. JN On 15-07-04 05:10 PM, Ravi Varadhan wrote:>> What about numeric constants, like `163'? >> >> eval(Pre(exp(sqrt(163)*pi), 120)) does not work. >> >> Thanks, >> Ravi >> ________________________________________ >> From: David Winsemius <dwinsemius at comcast.net> >> Sent: Saturday, July 4, 2015 1:12 PM >> To: Duncan Murdoch >> Cc: r-help; John Nash; Ravi Varadhan >> Subject: Re: [R] : Ramanujan and the accuracy of floating point computations - using Rmpfr in R >> >>> On Jul 4, 2015, at 12:20 AM, Duncan Murdoch <murdoch.duncan at gmail.com> wrote: >>> >>> On 04/07/2015 8:21 AM, David Winsemius wrote: >>>>> On Jul 3, 2015, at 11:05 PM, Duncan Murdoch <murdoch.duncan at gmail.com> wrote: >>>>> >>>>> On 04/07/2015 3:45 AM, David Winsemius wrote: >>>>>>> On Jul 3, 2015, at 5:08 PM, David Winsemius <dwinsemius at comcast.net> wrote: >>>>>>> >>>>>>> >>>>>>> >>>>>>> It doesn?t appear to me that mpfr was ever designed to handle expressions as the first argument. >>>>>> This could be a start. Obviously one would wnat to include code to do other substitutions probably using the all.vars function to pull out the other ?constants? and ?numeric? values to make them of equivalent precision. I?m guessing you want to follow the parse-tree and then testing the numbers for integer-ness and then replacing by paste0( ?mpfr(?, val, ?L, ?, prec,?)? ) >>>>>> >>>>>> Pre <- function(expr, prec){ sexpr <- deparse(substitute(expr) ) >>>>> Why deparse? That's almost never a good idea. I can't try your code (I >>>>> don't have mpfr available), but it would be much better to modify the >>>>> expression than the text representation of it. For example, I think >>>>> your code would modify strings containing "pi", or variables with those >>>>> letters in them, etc. If you used substitute(expr) without the >>>>> deparse(), you could replace the symbol "pi" with the call to the Const >>>>> function, and be more robust. >>>>> >>>> Really? I did try. I was fairly sure that someone could do better but I don?t see an open path along the lines you suggest. I?m pretty sure I tried `substitute(expr, list(pi= pi))` when `expr` had been the formal argument and got disappointed because there is no `pi` in the expression `expr`. I _thought_ the problem was that `substitute` does not evaluate its first argument, but I do admit to be pretty much of a klutz with this sort of programming. I don?t think you need to have mpfr installed in order to demonstrate this. >>> The substitute() function really does two different things. >>> substitute(expr) (with no second argument) grabs the underlying >>> expression out of a promise. substitute(expr, list(pi = pi)) tries to >>> make the substitution in the expression "expr", so it doesn't see "pi?. >> Thank you. That was really helpful. I hope it ?sticks? to sufficiently durable set of neurons. >>> This should work: >>> >>> do.call(substitute, list(expr = substitute(expr), env=list(pi >>> Const(pi, 120)))) >>> >>> (but I can't evaluate the Const function to test it). >> The expression `pi` as the argument to Const only needed to be character()-ized and then evaluation on that result succeeded: >> >> library(mpfr) >> # Pre <- function(expr, prec){ do.call(substitute, >> list(expr = substitute(expr), >> env=list(pi = Const(pi, prec)))) } >> >>> Pre(exp(pi),120) >> Error in Const(pi, prec) : >> 'name' must be one of 'pi', 'gamma', 'catalan', 'log2' >> >> >> Pre <- function(expr, prec){ do.call(substitute, >> list(expr = substitute(expr), >> env=list(pi = Const('pi', prec)))) } >> >>> Pre(exp(pi),120) >> exp(list(<S4 object of class "mpfr1">)) >>> eval( Pre(exp(pi),120) ) >> 1 'mpfr' number of precision 120 bits >> [1] 23.140692632779269005729086367948547394 >> >> So the next step for delivering Ravi?s request would be to add the rest of the ?Const? options: >> >> Pre <- function(expr, prec){ do.call(substitute, >> list(expr = substitute(expr), >> env=list(pi = Const('pi', prec), >> catalan=Const('catalan', prec), >> log2=Const('log2', prec), >> gamma=Const('gamma', prec)))) } >> >> >>> eval(Pre(exp(gamma))) >> Error in stopifnot(is.numeric(prec)) : >> argument "prec" is missing, with no default >>> eval(Pre(exp(gamma), 120)) >> 1 'mpfr' number of precision 120 bits >> [1] 1.781072417990197985236504103107179549 >> >>> This works: >>> >>> do.call(substitute, list(expr = substitute(expr), env = list(pi >>> quote(Const(pi, 120))))) >>> >>> because it never evaluates the Const function, it just returns some code >>> that you could modify more if you liked. >>> >>> Duncan Murdoch >> David Winsemius, MD >> Alameda, CA, USA >>
Martin Maechler
2015-Jul-14 07:34 UTC
[R] : Ramanujan and the accuracy of floating point computations - using Rmpfr in R
>>>>> "P" == ProfJCNash <profjcnash at gmail.com> >>>>> on Sat, 4 Jul 2015 21:42:27 -0400 writes:P> n163 <- mpfr(163, 500) P> is how I set up the number. Yes, and you have needed to specify the desired precision. As author and maintainer of Rmpfr, let me give my summary of this overly long thread (with many wrong statements before finally RK give the "obvious" answer): 1) Rmpfr is about high (or low, for didactical reasons, see Rich Heiberger's talk at 'useR! 2015') precision __numerical__ computations. This is what the GNU MPFR library is about, and Rmpfr wants to be a smart and R-like {e.g., automatic coercions wherever they make sense} R interface to MPFR. 2) If you use Rmpfr, you as user should decide about the desired accuracy of your "inputs". I think it would be a very bad idea to redefine 'pi' (in Rmpfr) to be Const("pi", 120). R-like also means that in a computation a * b the properties of a and b determine the result, and hence if a <- pi then we know that pi is a double precision number with 53-bit mantissa. p> On 15-07-04 05:10 PM, Ravi Varadhan wrote: >>> What about numeric constants, like `163'? well, if you _combine_ them with an mpfr() number, they are used in their precision. An integer like 163 is exact of course; but pi (another numeric constant) is 53-bit as mentioned above, *and* sqrt(163) is ("R-like") a double precision number computed by R's internal double precision arithmetic. My summary: -------------------------------------------------------------------- 1. Rmpfr behaves entirely correctly and as documented (in all the examples given here). 2. The idea of substituting expressions containing pi with something like Const("pi", 120) is not a good one. (*) -------------------------------------------------------------------- *) One could think of adding a new class, say "symbolicNumber" or rather "numericExpression" which in arithmetic would try to behave correctly, namely find out what precision all the other components in "the arithmetic" have and make sure all parts of the 'numericExpression' are coerced to 'mpfr' with the correct precision, and only then start evaluating "the arithmetic". But that *does* look like implementation of Maple/Mathematica/... in R and that seems silly; rather R should interface to Free (as in "speech") aka "open source" symbolic math packages such as Pari, macysma, .. Martin Maechler ETH Zurich