From m@echler @ending from @t@t@m@th@ethz@ch  Fri Oct 26 11:29:16 2018
From: m@echler @ending from @t@t@m@th@ethz@ch (Martin Maechler)
Date: Fri, 26 Oct 2018 11:29:16 +0200
Subject: [Rd] Rmpfr: build vector sequentially -- c(.) not working
In-Reply-To: <CY4PR12MB1910056059D5038651A0DC4F81F00@CY4PR12MB1910.namprd12.prod.outlook.com>
References: <CY4PR12MB1910056059D5038651A0DC4F81F00@CY4PR12MB1910.namprd12.prod.outlook.com>
Message-ID: <23506.56940.485048.948917@stat.math.ethz.ch>

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



[Rd] Rmpfr: build vector sequentially -- c(.) not working
Martin Maechler