gma*_*man 4 c++ syntactic-sugar rcpp
到目前为止,我一直在尝试在 Rcpp 中实现应用功能,代码如下所示
//[[Rcpp::export]]
NumericVector apply(NumericMatrix x,int dim,Function f){
NumericVector output;
if(dim==1){
for(int i=0;i<x.nrow();i++){
output[i]=f(x(i,_));
}
}
else if(dim==2){
for(int i=0;i<x.ncol();i++){
output[i]=f(x(_,i));
}
}
return(output);
}
Run Code Online (Sandbox Code Playgroud)
但我在第 6 行和第 11 行收到错误“无法将 SEXP 转换为赋值中的双精度值”。有没有办法将任意函数返回的值转换为双精度值?应用函数也有一个糖函数。
没有糖函数apply。做你想做的最简单的方法是调用as<double>,即:
output[i]=as<double>(f(x(i,_)));
Run Code Online (Sandbox Code Playgroud)
您还可以将其嵌入到需要as您的类型中,例如:
template <typename T>
class F {
public:
F( SEXP f_) : f(f_){}
inline T operator()(NumericVector x){
return as<T>(f(x)) ;
}
private:
Function f ;
} ;
Run Code Online (Sandbox Code Playgroud)
这样你就可以:
// [[Rcpp::export]]
NumericVector apply_cpp(NumericMatrix x,int dim,F<double> f){
if(dim==1){
NumericVector output(x.nrow());
for(int i=0;i<x.nrow();i++){
output[i]=f(x(i,_));
}
return output ;
}
else {
NumericVector output(x.ncol());
for(int i=0;i<x.ncol();i++){
output[i]=f(x(_,i));
}
return output ;
}
}
Run Code Online (Sandbox Code Playgroud)
F上面的模板假设函数接受 aNumericVector并返回一些可以转换为 a 的东西double。您还可以嵌入有关输入和输出的类型信息。像这样(用 C++11 表示):
template <typename T, typename... Args>
class F {
public:
F( SEXP f_) : f(f_){}
inline T operator()(Args... args){
return as<T>(f(args...)) ;
}
private:
Function f ;
} ;
Run Code Online (Sandbox Code Playgroud)
然后签名会变成:
// [[Rcpp::export]]
NumericVector apply_cpp(NumericMatrix x,int dim,F<double,NumericVector> f){
Run Code Online (Sandbox Code Playgroud)