earclimate
earclimate

Reputation: 375

Rcpp: How can I get the size of a Rcpp::Nullable NumericVector

I want to translate a R function into Rcpp, a simple test code is as follow, but I do not know how to deal with the arguments which is set NULL by default.

test<- function(t=NULL,tmax=NULL,tmin=NULL){
  if(is.null(t)){
    yout=(tmax-tmin)*(tmin+tmax)
  }else{
    yout=2*t
  }
  return(yout)
}

test(tmax=1:3,tmin=0:2)




  // [[Rcpp::export]]
    NumericVector cpptest(Rcpp::Nullable<Rcpp::NumericVector> t=R_NilValue,
                          Rcpp::Nullable<Rcpp::NumericVector> tmax=R_NilValue,
                          Rcpp::Nullable<Rcpp::NumericVector> tmin=R_NilValue){
      int N=0;
      if(t.isNotNull()) {
        N=t.size(); /* which show a error*/
      }else{
        N=tmax.size(); /* which show a error*/
      }
      NumericVector yout=NumericVector(N);

      if(t.isNotNull()) {
        for(i=0;i<N,i++){
          yout[i]=2*t[i]
        }
      }else{
        for(i=0;i<N,i++){
          yout[i]=(tmax[i]-tmin[i])*(tmin[i]+tmax[i])
        }
      }
      return(yout)
    }

Upvotes: 2

Views: 1125

Answers (1)

nrussell
nrussell

Reputation: 18612

Instead of calling, e.g. .size() directly on the object as you are doing here -- N = t.size(); -- you need to cast it to the underlying type. For example,

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
int nullable_size(Nullable<NumericVector> x_ = R_NilValue)
{
    if (x_.isNotNull()) {
        NumericVector x(x_.get());
        return x.size();
    }
    warning("argument x_ is NULL");
    return -1;
}

/*** R

nullable_size(rnorm(5))
# [1] 5

nullable_size(NULL)
# [1] -1
# Warning message:
# In .Primitive(".Call")(<pointer: 0x000000006aa417a0>, x_) :
#   argument x_ is NULL

*/

As pointed out by Dirk, the use of .get() is not strictly necessary here -- using NumericVector x(x_); will invoke Nullable<>::operator SEXP() and work equally well.


Also, please format your code better in the future.

Upvotes: 5

Related Questions