Rcpp with quad precision computation

后端 未结 2 1134
温柔的废话
温柔的废话 2021-01-17 05:00

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

2条回答
  •  别那么骄傲
    2021-01-17 05:08

    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 
    #include 
    #include 
    
    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();
    }
    
    // [[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();
    }
    

    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
    

提交回复
热议问题