What is the best way to numerically compute things like the following within Rcpp?
exp(-1500)/(exp(-1500)+exp(-1501))
In many cases, the computa
A quick way to get up and running is to install the BH
package and use the Boost Multiprecision library, which provides several extended precision floating point types. For example, this code demos the float128 and mpf_float_100 types:
// [[Rcpp::depends(BH)]]
#include <Rcpp.h>
#include <boost/multiprecision/float128.hpp>
#include <boost/multiprecision/mpfr.hpp>
namespace mp = boost::multiprecision;
// [[Rcpp::export]]
std::string qexp(double da = -1500.0, double db = -1501.0)
{
mp::float128 a(da), b(db);
mp::float128 res = mp::exp(a) / (mp::exp(a) + mp::exp(b));
return res.convert_to<std::string>();
}
// [[Rcpp::export]]
std::string mpfr_exp(double da = -1500.0, double db = -1501.0)
{
mp::mpf_float_100 a(da), b(db);
mp::mpf_float_100 res = mp::exp(a) / (mp::exp(a) + mp::exp(b));
return res.convert_to<std::string>();
}
The latter requires adding flags for linking to the libmpfr
and libgmp
before compiling; the former does not, as it is a wrapper around GCC's built in __float128
:
Sys.setenv("PKG_LIBS" = "-lmpfr -lgmp")
Rcpp::sourceCpp('/tmp/quadexp.cpp')
qexp()
# [1] "0.731058578630004879251159241821836351"
mpfr_exp()
# [1] "0.731058578630004879251159241821836274365144640165056519276365907919040453070204639387474532075981245292174466493140773"
Comparing to Rmpfr
,
library(Rmpfr)
a <- mpfr(-1500, 100)
b <- mpfr(-1501, 100)
exp(a) / (exp(a) + exp(b))
# 1 'mpfr' number of precision 100 bits
# [1] 7.3105857863000487925115924182206e-1
I fear you may be mostly confused.
Rcpp is a bridge between R and C++. It is neither a new language, nor a new system.
And in C++ you use something like GNU gmplib aka The GNU Multiple Precision Arithmetic Library which, of course, has already been wrapped for R as package gmp
But if you want to write C++ functions, called from R, interfacing the GMP library -- you certainly. It falls back to 'how do I write a C++ function callable from R which accesses an external library' -- and that question has been covered numerous times here too.