允许C++;使用Rcpp属性将常量作为默认函数参数

允许C++;使用Rcpp属性将常量作为默认函数参数,r,rcpp,R,Rcpp,我在带有rcpp的R包中创建了一个cumsum函数,它将累计求和一个向量,直到它达到用户定义的上限或下限。但是,如果希望总和在上面有界,用户仍然必须指定一个楼层 例如: a = c(1, 1, 1, 1, 1, 1, 1) 如果我想求和a并且上界为3,我可以cumsum\u有界(a,lower=1,upper=3)。我宁愿不必指定下限 我的代码: #include <Rcpp.h> #include <float.h> #include <cmath> us

我在带有rcpp的R包中创建了一个cumsum函数,它将累计求和一个向量,直到它达到用户定义的上限或下限。但是,如果希望总和在上面有界,用户仍然必须指定一个楼层

例如:

a = c(1, 1, 1, 1, 1, 1, 1)
如果我想求和
a
并且上界为3,我可以
cumsum\u有界(a,lower=1,upper=3)
。我宁愿不必指定下限

我的代码:

#include <Rcpp.h>
#include <float.h>
#include <cmath>
using namespace Rcpp;

// [[Rcpp::export]]
NumericVector cumsum_bounded(NumericVector x, int upper, int lower) {
  NumericVector res(x.size());
  double acc = 0;
  for (int i=0; i < x.size(); ++i) {
    acc += x[i];
    if (acc < lower)  acc = lower;
    else if (acc > upper)  acc = upper;
    res[i] = acc;
  }
  return res;
}
#包括
#包括
#包括
使用名称空间Rcpp;
//[[Rcpp::导出]]
数值向量总和有界(数值向量x,整数上限,整数下限){
数值向量res(x.size());
双acc=0;
对于(int i=0;i上部)acc=上部;
res[i]=acc;
}
返回res;
}
我想要的是:

#include <Rcpp.h>
#include <float.h>
#include <cmath>
#include <climits> //for LLONG_MIN and LLONG_MAX
using namespace Rcpp;

// [[Rcpp::export]]
NumericVector cumsum_bounded(NumericVector x, long long int upper = LLONG_MAX, long long int lower = LLONG_MIN) {
  NumericVector res(x.size());
  double acc = 0;
  for (int i=0; i < x.size(); ++i) {
    acc += x[i];
    if (acc < lower)  acc = lower;
    else if (acc > upper)  acc = upper;
    res[i] = acc;
  }
  return res;
}
#包括
#包括
#包括
#包括//用于最小和最大
使用名称空间Rcpp;
//[[Rcpp::导出]]
数值向量总和有界(数值向量x,长整型上限=长整型最大值,长整型下限=长整型最小值){
数值向量res(x.size());
双acc=0;
对于(int i=0;i上部)acc=上部;
res[i]=acc;
}
返回res;
}

简而言之,是的,这是可能的,但它需要一些技巧,包括创建一个中间函数或在主函数中嵌入排序逻辑


在long中,Rcpp属性仅支持一组限制功能值。这些值列在

  • 由引号分隔的字符串文字(例如“foo”)
  • 整数和十进制数值(例如10或4.5)
  • 预定义常数,包括:
    • 布尔人:对与错
    • 空值:R_NilValue、NA_STRING、NA_INTEGER、NA_REAL和NA_LOGICAL
  • 可以使用 ::create static成员函数的空形式。
    • CharacterVector、IntegerVector和NumericVector
  • 使用rows,cols构造函数Rcpp::Matrix n(rows,cols)实例化的矩阵类型
    • CharacterMatrix、IntegerMatrix和NumericMatrix)
如果要为
LLONG_MAX
LLONG_MIN
指定数值,这将满足直接在函数上使用Rcpp属性的标准。但是,这些值是特定于实现的。因此,硬编码它们并不理想。因此,我们必须寻求外部解决方案:使用
Rcpp::Nullable
类来启用默认的
NULL
值。我们必须用
Rcpp::Nullable
包装参数类型的原因是
NULL
是一种非常特殊的类型,如果不小心,可能会导致心痛

与实数行中的其他值不同,
NULL
值在此情况下不会用于绑定值。因此,它是用于函数调用的最佳候选者。然后,您必须做出两个选择:使用
Rcpp::Nullable
作为主函数的参数,或者创建一个“逻辑”辅助函数,该函数具有正确的参数,可以在应用程序中的其他地方使用,而无需担心。我选择了后面的选项

#include <Rcpp.h>
#include <float.h>
#include <cmath>
#include <climits> //for LLONG_MIN and LLONG_MAX
using namespace Rcpp;

NumericVector cumsum_bounded_logic(NumericVector x,
                                   long long int upper = LLONG_MAX,
                                   long long int lower = LLONG_MIN) {

    NumericVector res(x.size());
    double acc = 0;
    for (int i=0; i < x.size(); ++i) {
        acc += x[i];
        if (acc < lower)  acc = lower;
        else if (acc > upper)  acc = upper;
        res[i] = acc;
    }

    return res;
}

// [[Rcpp::export]]
NumericVector cumsum_bounded(NumericVector x,
                             Rcpp::Nullable<long long int> upper = R_NilValue, 
                             Rcpp::Nullable<long long int> lower = R_NilValue) {

    if(upper.isNotNull() && lower.isNotNull()){
        return cumsum_bounded_logic(x, Rcpp::as< long long int >(upper), Rcpp::as< long long int >(lower));
    } else if(upper.isNull() && lower.isNotNull()){
        return cumsum_bounded_logic(x, LLONG_MAX, Rcpp::as< long long int >(lower));
    } else if(upper.isNotNull() && lower.isNull()) {
        return cumsum_bounded_logic(x, Rcpp::as< long long int >(upper), LLONG_MIN);
    } else {
        return cumsum_bounded_logic(x, LLONG_MAX, LLONG_MIN);
    }

    // Required to quiet compiler
    return x;
}

在构建包时,我得到以下错误:<代码>警告消息:1:无法解析函数CuMuxIn BoffDeDigialLogic 2的参数上限的C++默认值“LangIONMAX”:无法解析C++ Cuff+默认值“LangLyMin”,以用于函数CuMuxIn BoffDeDeLogic < /C>复制和粘贴我上面的函数。不要将
/[[Rcpp::export]
添加到
cumsum\u bounded\u logic
函数中。谢谢,我有一个挥之不去的
/[[Rcpp::export]
cumsum_bounded(a, 5)
## [1] 1 2 3 4 5 5 5
cumsum_bounded(a, 5, 2)
## [1] 2 3 4 5 5 5 5