Search code examples
rcpp

Use Rcpp::NumericVector::create(R_NegInf) as function argument in Rcpp


I would like to set -Inf as the default value for a function argument in Rcpp. I tried the following which throws an error at execution:

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
Rcpp::NumericVector test_cpp1(
    Rcpp::NumericVector x = Rcpp::NumericVector::create(R_NegInf))
{
    return x;
}

[R] test_cpp1()                     
Error in test_cpp1() : object 'R_NegInf' not found

A possible workaround is creating an overflow:

// [[Rcpp::export]]
Rcpp::NumericVector test_cpp2(
    Rcpp::NumericVector x = Rcpp::NumericVector::create(-1E+999))
{
    return x;
}

[R] test_cpp2()                                
[1] -Inf

This works but causes warnings on the compilation. Is there a workaround without this hack? Thank you very much in advance.

Edit:

Another example for clarification. This works perfectly fine:

// [[Rcpp::export]]
NumericVector test_cpp3(
    NumericVector x = NumericVector::create(1, 2, 3))
{
    return x;
}

But this does not:

// [[Rcpp::export]]
NumericVector test_cpp4(
    NumericVector x = NumericVector::create(R_NegInf, 2, 3))
{
    return x;
}

It throws the following error on execution:

[R] test_cpp4()                                                                                                                                       
Error in test_cpp4() : object 'R_NegInf' not found

I would expect it to return -Inf. I need this Vector x inside an Rcpp function for some compuations. It should contain -Inf on default. But the user should be able to pass any numeric vector he/she wants.


Solution

  • I think you picked the wrong signature. Based on your follow-up comment, maybe this is what you are after: one int argument for size, a second double argument for default value to be assigned?

    > cppFunction("NumericVector myvec(int n, double v) { \
                      return NumericVector(n, v); }")
    > myvec(3, 1.23)
    [1] 1.23 1.23 1.23
    > 
    

    which works for all values that are a double:

    > makevec(3, -Inf)
    [1] -Inf -Inf -Inf
    > 
    

    If the value is a constant, there are a few ways to do that too. Here is one:

    > cppFunction("NumericVector makevec2(int n) { \
          double val = -std::numeric_limits<double>::infinity(); \
          return NumericVector(n, val); }")
    > makevec2(3)
    [1] -Inf -Inf -Inf
    > 
    

    Edit: Your edit makes your question clearer, and you are still hitting a wall over R not being C++: types matter !! While NumericVector::create(1, 2, 3) works with these values of type integer you simply cannot simply stick a double in there and hope for the best. (Though this may have to do with the nature of the #define used here.)

    Edit 2: Maybe the error had to do with C-level #define. We can stick a single double, including -Inf, into create() as well:

    > cppFunction("NumericVector makevec3() { \  
          double val = -std::numeric_limits<double>::infinity();\
          return NumericVector::create(val); }")
    > makevec3()
    [1] -Inf
    >