[Rcpp-devel] Example of rcpp usage with Rmpfr, mpfr, gmp.

Thell Fowler tbfowler4 at gmail.com
Wed Apr 25 18:32:05 CEST 2012

On Sun, Apr 22, 2012 at 12:13 PM, Dirk Eddelbuettel <edd at debian.org> wrote:

> On 22 April 2012 at 11:41, Thell Fowler wrote:
> | On Sun, Apr 22, 2012 at 10:49 AM, Dirk Eddelbuettel <edd at debian.org>
> wrote:
> |     On 22 April 2012 at 10:17, Thell Fowler wrote:
> |     | Any examples or direction on how (if I can) to get to a Rcpp Rmpfr
> bridge
> |     with
> |     | speed would go a long way...
> |
> |     Sounds fine. Not sure how to return (or pass down) the mpfr arrays.
> But you
> |     may be able to
> |     look at the existing CRAN packages wrapping mpfr for ideas.
> |
> | I'll try reading through  the Rmpfr source to see how it does its' magic.
> | Also, the Bessel package depends on Rmpfr so that might yield some ideas.
> It shouldn't be too hard, apart from the fact that instead of Rcpp niceties
> you have to deal with R API which is plain C and macros...
> After some trial and error I was able to pass down mpfr values.  You're
right though, it wasn't 'nice'.

--->8 ---

> |
> |     You just need to add the required -I and -L flags to src/Makevars
> and you
> |     should be fine. [ Higher-end solutions use configure, or pkg-config,
> or
> |     ... to find those values. Harcoded may work on standard Linux
> systems. ]
> |
> | That part _should_ be pretty straight forward.
> Yes.
> Well, it wasn't really all that straight forward after all as I need to
use -std=c++0x.
Here's the code and comments used to setup access...
<I hope gmail doesn't mess this up too much, I haven't setup alpine for
this list yet...>

suppressMessages( require( Rcpp ) )
suppressMessages( require( inline ) )

## Base Access to mpfr
# To have access to mpfr the following was done...
#   Extracted Rtools Local215keep3.zip to `c:\RtoolsLocal\R-2.15.0`
#   Created an environment var `RTOOLS_LOCAL` to that path.
#   Set LOCAL_SOFT = $(RTOOLS_LOCAL) in $(R_HOME}/etc$(R_ARCH)/Makeconf
#   < note: CXXFLAGS =  -O3 -Wall $(DEBUGFLAG) -std=c++0x -mtune=core2 >
mpfr.settings <- Rcpp:::Rcpp.plugin.maker( include.before= "#include
                                           libs= "-lgmp -lmpfr" )
registerPlugin( "RcppMpfr", mpfr.settings )

# Test mpfr .dll access
mpfr.Rcpp.source <- '
  Rprintf(" MPFR library: %-12s\\n MPFR header:  %s (based on %d.%d.%d)\\n",
          mpfr_get_version(), MPFR_VERSION_STRING, MPFR_VERSION_MAJOR,
  return Rcpp::wrap( std::string("OK") );
mpfr.Rcpp.test <- cxxfunction( signature(),
                               body= mpfr.Rcpp.source,
                               plugin= "RcppMpfr",
                               verbose= FALSE )
cat( mpfr.Rcpp.test(), '\n')

## Access to Rmpfr
# To utilize the Rmpfr .dll functions for processing the Rmpfr SEXP
# a junction was made linking the src path of the mpfr to a new `include`
# path in the Rmpfr package path.
# Inclusion of the Mpfr_utils caused some issues though;
#   1) REVprintf is not defined by R_ext/Print.h when __cpluscplus id
#      unless R_USE_C99_IN_CXX is defined.
#   2) allocVector is not decalred unless R_NO_REMAP is not defined.
#   ...
#   Yet, with 1 defined and 2 not defined and passing -std=c++0x to GCC
there is
#   a macro argument length error in codecvt.h included by Rostream.h's
#   of iomanip and __GXX_EXPERIMENTAL_CXX0X.
# Not passing -std=c++0x allowed successful compilation, but I'll need it.

suppressMessages( require( Rmpfr ) )

Rmpfr.Rcpp.include.before <-'

  #define R_USE_C99_IN_CXX
  #undef R_NO_REMAP
  #include <Rmpfr_utils.h>
  #include <Syms.h>


Rmpfr.Rcpp.include.after <-'

  #include <R_ext/Rdynload.h>


Rmpfr.settings <- Rcpp:::Rcpp.plugin.maker( include.before=
                                            libs="-lgmp -lmpfr" )
registerPlugin( "RcppRmpfr", Rmpfr.settings )

Rmpfr.Rcpp.include <- '

  // Typedefs...
  // Doing this for each signature in Rmpfr that is used should not be too
  // but it would be nice not to have to.

  typedef SEXP (*FUNC)(void);
  FUNC p_R_mpfr_get_version = (FUNC) R_GetCCallable("Rmpfr",


Rmpfr.Rcpp.source <- '

  Rprintf(" MPFR library: %-12s\\n MPFR header:  %s (based on %d.%d.%d)\\n",
          mpfr_get_version(), MPFR_VERSION_STRING, MPFR_VERSION_MAJOR,

  return p_R_mpfr_get_version();

Rmpfr.Rcpp.test <- cxxfunction( signature(),
                                includes= Rmpfr.Rcpp.include,
                                body= Rmpfr.Rcpp.source,
                                plugin= "RcppRmpfr",
                                verbose= FALSE )

cat( Rmpfr.Rcpp.test(), '\n')

|     [ And if you want to look into doing more of an integration (a la
> |     RcppArmadillo,
> |     RcppGSL, RcppEigen, ...), then the Rcpp-extending vignette shows you
> how to
> |     modify as<>() and wrap() to get automatic converters going.  But you
> |     surely
> |     don't need to do this for a first attempt to compute your stuff. I
> just
> |     mention it as you say 'R mpfr bridge' -- this would be the Rcpp way
> of
> |     doing
> |     it. ]
> |
> | The Rcpp-extending vignette is what I originally thought would be the
> answer.
> | Good thing I asked first! ;)
> It's somewhat scarier reading material but it nudges ever so gently into
> Template Programming...  You do *not* need to go there just to call mpfr.
Well, in the end it looks like this is essentially what I'll need to do...
After looking around at the options I think what I need to do is use the
mpfrc++ library.
Only two headers and works on top of gmp and mpfr, but I do wonder one
thing about using it as an extension...

It includes its own dlmalloc, is this a death blow for using it as either
an extension/package, RcppMpfr++ package?

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20120425/7a2a6878/attachment.html>

More information about the Rcpp-devel mailing list