Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将R函数作为参数传递给RCpp函数_C++_R_Function_Rcpp - Fatal编程技术网

C++ 将R函数作为参数传递给RCpp函数

C++ 将R函数作为参数传递给RCpp函数,c++,r,function,rcpp,C++,R,Function,Rcpp,我在试着做一些类似的事情 R my_r_函数您应该能够使用我在上面提供的链接中的示例来运行代码;但你也应该注意德克的警告 调用函数既简单又诱人。它也像那里一样慢 是否涉及日常开支。并从C++内部重复调用它 代码,可能隐藏在几个循环中,完全是愚蠢的 这可以通过稍微修改上述代码并对两个版本进行基准测试来演示: #include <Rcpp.h> // [[Rcpp::export]] Rcpp::NumericVector RunFunction(Rcpp::NumericVector

我在试着做一些类似的事情

R


my_r_函数您应该能够使用我在上面提供的链接中的示例来运行代码;但你也应该注意德克的警告

调用函数既简单又诱人。它也像那里一样慢 是否涉及日常开支。并从C++内部重复调用它 代码,可能隐藏在几个循环中,完全是愚蠢的

这可以通过稍微修改上述代码并对两个版本进行基准测试来演示:

#include <Rcpp.h>

// [[Rcpp::export]]
Rcpp::NumericVector RunFunction(Rcpp::NumericVector a, Rcpp::Function func)
{
  Rcpp::NumericVector b = func(a);
  return b;
}

// [[Rcpp::export]]
Rcpp::NumericVector RunFunction2(Rcpp::NumericVector a, Rcpp::Function func)
{
  Rcpp::NumericVector b(a.size());
  for(int i = 0; i < a.size(); i++){
    b[i] = Rcpp::as<double>(func(a[i]));
  }
  return b;
}

/*** R
my_r_function <- function(input_a) {return(input_a**3)}
x <- 1:10
##
RunFunction(x,my_r_function)

RunFunction2(x,my_r_function)
##
library(microbenchmark)
microbenchmark(
  RunFunction(rep(1:10,10),my_r_function),
  RunFunction2(rep(1:10,10),my_r_function))

Unit: microseconds
                                       expr     min       lq       mean   median       uq      max neval
  RunFunction(rep(1:10, 10), my_r_function)  21.390  22.9985   25.74988  24.0840   26.464   43.722   100
 RunFunction2(rep(1:10, 10), my_r_function) 843.864 903.0025 1048.13175 951.2405 1057.899 2387.550   100

*/
你大概是弄错了

无法将“SEXP”转换为“Rcpp::traits::storage_type::type{aka” 赋值中的双}

我通过将
func(a[I])
的返回值包装在上面的
Rcpp::as()
中解决了这个问题。但是,这显然不值得费心,因为不管怎样,最终的结果是函数的速度要慢得多。

您可以使用“transform()”并避免使用循环!请尝试以下代码:

List RunFunction(List input, Function f) {

    List output(input.size());

    std::transform(input.begin(), input.end(), output.begin(), f);
    output.names() = input.names();
}

额外的链接到Rcpp画廊文章点。非常好的答案。我将此用于性能敏感代码,因此我采纳了您的建议,从Rcpp代码中删除了调用,并选择了矢量化解决方案。谢谢所有的便利提示。你正确的是,<代码> STD::转换是循环的<代码>的一个可行的替代方案,通常比典型C++代码中的循环和迭代器更可取。但是,这种方法仍然会导致相同的性能开销,这是由于在C++中对<代码> f>代码>重复调用。如果您运行一些基准测试,将
for
循环方法与
std::transform
方法进行比较,您将看到它们的计时或多或少是相等的。还请注意,OP的函数将向量作为输入,而不是列表;虽然
transform
在列表中工作得很好。
#include <Rcpp.h>

// [[Rcpp::export]]
Rcpp::NumericVector RunFunction(Rcpp::NumericVector a, Rcpp::Function func)
{
  Rcpp::NumericVector b = func(a);
  return b;
}

// [[Rcpp::export]]
Rcpp::NumericVector RunFunction2(Rcpp::NumericVector a, Rcpp::Function func)
{
  Rcpp::NumericVector b(a.size());
  for(int i = 0; i < a.size(); i++){
    b[i] = Rcpp::as<double>(func(a[i]));
  }
  return b;
}

/*** R
my_r_function <- function(input_a) {return(input_a**3)}
x <- 1:10
##
RunFunction(x,my_r_function)

RunFunction2(x,my_r_function)
##
library(microbenchmark)
microbenchmark(
  RunFunction(rep(1:10,10),my_r_function),
  RunFunction2(rep(1:10,10),my_r_function))

Unit: microseconds
                                       expr     min       lq       mean   median       uq      max neval
  RunFunction(rep(1:10, 10), my_r_function)  21.390  22.9985   25.74988  24.0840   26.464   43.722   100
 RunFunction2(rep(1:10, 10), my_r_function) 843.864 903.0025 1048.13175 951.2405 1057.899 2387.550   100

*/
b[i] = func(a[i]);
List RunFunction(List input, Function f) {

    List output(input.size());

    std::transform(input.begin(), input.end(), output.begin(), f);
    output.names() = input.names();
}