使用Rcpp函数构建一个函数

3
在R中存在一个函数可以创建另一个函数,例如:
create_ax2 <-  function(a) {

  ax2 <- function(x) {
    y <- a * x^2
    return(y)
  }

  return(ax2)
}

这导致的结果是:
> fun <- create_ax2(3)
> fun(1)
[1] 3
> fun(2)
[1] 12
> fun(2.5)
[1] 18.75

我有一个在R中创建函数的过程非常复杂,需要传入多个参数,设置返回函数中使用的某些常量,进行一些中间计算等等...但结果是一个非常慢的函数。因此,我尝试将代码翻译成C++,并与Rcpp一起使用。然而,我无法想出一种在C++函数内部构建函数并将其返回以在R中使用的方法。

以下是我目前的情况:

Rcpp::Function createax2Rcpp(int a) {

  double ax2(double x) {
    return(a * pow(x, 2));
  };

  return (ax2);
}

这让我报错“此处不允许定义函数”,我不知道如何创建该函数。
编辑:问题RcppArmadillo pass user-defined function接近答案,但据我所知,它只提供了一种将C++函数传递给R的方法。它没有提供在将C++函数传递给R之前初始化某些值的方法。

这不是Rcpp的问题,C++不允许局部函数声明。因此,您需要将该函数定义在局部范围之外或将其包装在类中。 - m0nhawk
1
@m0nhawk 当然会。 - Severin Pappadeux
@SeverinPappadeux 当然我可以使用 std::function 和 lambda,但是你不能像上面的代码那样定义它们。 - m0nhawk
我编辑了一下,并解释了它与https://dev59.com/CWYq5IYBdhLWcg3wfw1x不同的原因。你能否举个例子,说明如何使用lambda表达式构建这样的函数? - Akkariz
1
好的,所以你想要一个Rcpp函数来创建另一个Rcpp函数?为什么?(如果涉及到编译语言,为什么这可能具有挑战性,请仔细思考。) - Roland
显示剩余6条评论
1个回答

2

好的,据我所知,您希望一个返回闭包的函数,也就是“在闭包中定义的函数记住了它被创建时所处的环境”。

在C++11及以上版本中,可以按照以下方式定义这样的函数:

std::function<double(double)> createax2Rcpp(int a) {
    auto ax2 = [a](double x) {  return(double(a) * pow(x, 2)); };
    return ax2;
}

当代码创建一个带有重载的operator()的匿名类和对象时,它将捕获闭包并移出创建函数。返回值将被捕获到具有类型抹除等功能的std :: function实例中。
但是!在R中,C/C++函数需要是某种特定类型,这种类型较窄(与“宽”相反,您可以将“窄”对象捕获到“宽”的对象中,但反之则不行)。
因此,我不知道如何从std::function创建一个适当的R函数,看起来似乎不可能。
也许像下面这样模仿闭包会有所帮助。
static int __a;

double ax2(double x) {
    return(__a * pow(x, 2));
}

Rcpp::Function createax2Rcpp(int a) {
    __a = a;

    return (ax2);
}

谢谢。目标确实是创建一个“记住”它所在环境的函数,以便我不需要在周围传递额外的变量(在这种情况下是 a)。由于似乎是不可能的,因此我将其标记为已接受,并直接定义该函数为 double ax2(double x, int a) - Akkariz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接