Re: Rmpfr: build vector sequentially -- c(.) not working

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Re: Rmpfr: build vector sequentially -- c(.) not working

Martin Maechler
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

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: Rmpfr: build vector sequentially -- c(.) not working

Jerry Lewis
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 <[hidden email]>
Sent: Friday, October 26, 2018 5:29 AM
To: R Development List <[hidden email]>
Cc: Martin Maechler ([hidden email]) <[hidden email]>
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

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel