Martin Maechler
2018-Oct-26 09:29 UTC
[Rd] Rmpfr: build vector sequentially -- c(.) not working
I've been asked in private, but am answering in public so others can comment / or find this answer in the future after a web search. This is about the package 'Rmpfr' (R interface to MPFR, the GNU C library for arbitrary precise numbers).> How can you build a vector of mpfr numbers sequentially? > Typically I would do something like the following (and try to > replace the for loop with some sort of apply construct) > > vec <- NULL > for(...) { > ... > vec <- c(vec, vec.new) > }Dear Jerry, In general the above is *bad* R code in the sense that it is unnecessarily inefficient. In a typical for() loop you know the length of the result in advance, and vec <- numeric(n) for(i in seq_along(vec)) { vec[i] <- ..... } is *MUCH* faster than your construct when n is not small. Still, I understand that you would expect mpfr numbers to work as well as many other R objects here -- and they don't :> However, this does not work with mpfr's. For instance > c(NULL, 1:3) > is equivalent to > 1:3 > > But > c(NULL, mpfr(1:3,100)) > is not even the same class as > mpfr(1:3,100)Indeed. One can consider this to be unfortunate, but it's nothing I can change as author of 'Rmpfr'. Rather, this is a shortcoming of R's current implementation of c() which I think may be very hard to be changed in R without either losing to much speed or changing semantic in a too radical way. [but I'm happy if I'm proven wrong here !! ==> that's why posting to R-devel] - - - - Anyway, now to solve your problem, if you really want to do something like your original code, you can do it like this : mNUL <- mpfr(logical()) # instead of 'NULL' Then, e.g., vec <- mNUL for(i in 1:10) { vec <- c(vec, mpfr(i^2, 88)) } works fine. In the next version of Rmpfr, both as(NULL, "mpfr") mpfr(NULL) will also give the 'mNUL' above. I hope you enjoy using Rmpfr! Best regards, Martin Martin Maechler ETH Zurich
Jerry Lewis
2018-Oct-26 21:48 UTC
[Rd] Rmpfr: build vector sequentially -- c(.) not working
Thank you for your detailed response. I subsequently noticed that sapply(vec,fn) also fails if the function fn returns an mpfr object. Will the next version of Rmpfr also fix this usage? I do enjoy using Rmpfr, and appreciate all that you have done in bringing this capability to the R community. Thanks, Jerry -----Original Message----- From: Martin Maechler <maechler at stat.math.ethz.ch> Sent: Friday, October 26, 2018 5:29 AM To: R Development List <R-devel at r-project.org> Cc: Martin Maechler (maechler at stat.math.ethz.ch) <maechler at stat.math.ethz.ch> Subject: Re: Rmpfr: build vector sequentially -- c(.) not working I've been asked in private, but am answering in public so others can comment / or find this answer in the future after a web search. This is about the package 'Rmpfr' (R interface to MPFR, the GNU C library for arbitrary precise numbers).> How can you build a vector of mpfr numbers sequentially? > Typically I would do something like the following (and try to replace > the for loop with some sort of apply construct) > > vec <- NULL > for(...) { > ... > vec <- c(vec, vec.new) > }Dear Jerry, In general the above is *bad* R code in the sense that it is unnecessarily inefficient. In a typical for() loop you know the length of the result in advance, and vec <- numeric(n) for(i in seq_along(vec)) { vec[i] <- ..... } is *MUCH* faster than your construct when n is not small. Still, I understand that you would expect mpfr numbers to work as well as many other R objects here -- and they don't :> However, this does not work with mpfr's. For instance > c(NULL, 1:3) > is equivalent to > 1:3 > > But > c(NULL, mpfr(1:3,100)) > is not even the same class as > mpfr(1:3,100)Indeed. One can consider this to be unfortunate, but it's nothing I can change as author of 'Rmpfr'. Rather, this is a shortcoming of R's current implementation of c() which I think may be very hard to be changed in R without either losing to much speed or changing semantic in a too radical way. [but I'm happy if I'm proven wrong here !! ==> that's why posting to R-devel] - - - - Anyway, now to solve your problem, if you really want to do something like your original code, you can do it like this : mNUL <- mpfr(logical()) # instead of 'NULL' Then, e.g., vec <- mNUL for(i in 1:10) { vec <- c(vec, mpfr(i^2, 88)) } works fine. In the next version of Rmpfr, both as(NULL, "mpfr") mpfr(NULL) will also give the 'mNUL' above. I hope you enjoy using Rmpfr! Best regards, Martin Martin Maechler ETH Zurich