我想知道是否可以制作一个infix函数,例如A %o% B
与Rcpp。
我知道可以使用inline
包来做到这一点,但是在使用sourceCpp()
时仍然无法找到一种方法。
当使用%o%
和outer()
确定参数是矢量时,我对RcppEigen
/ inline
进行了以下中缀实现:
`%op%` <- cxxfunction(signature(v1="NumericVector",
v2="NumericVector"),
plugin = "RcppEigen",
body = c("
NumericVector xx(v1);
NumericVector yy(v2);
const Eigen::Map<Eigen::VectorXd> x(as<Eigen::Map<Eigen::VectorXd> >(xx));
const Eigen::Map<Eigen::VectorXd> y(as<Eigen::Map<Eigen::VectorXd> >(yy));
Eigen::MatrixXd op = x * y.transpose();
return Rcpp::wrap(op);
"))
可以很容易地实现它,以使用sourceCpp()
进行导入,但是不能作为infix函数。
我当前的尝试如下:
#include <Rcpp.h>
using namespace Rcpp;
#include <RcppEigen.h>
// [[Rcpp::depends(RcppEigen)]]
// [[Rcpp::export]]
NumericMatrix outerProd(NumericVector v1, NumericVector v2) {
NumericVector xx(v1);
NumericVector yy(v2);
const Eigen::Map<Eigen::VectorXd> x(as<Eigen::Map<Eigen::VectorXd> >(xx));
const Eigen::Map<Eigen::VectorXd> y(as<Eigen::Map<Eigen::VectorXd> >(yy));
Eigen::MatrixXd op = x * y.transpose();
return Rcpp::wrap(op);
}
所以总结我的问题。是否可以通过sourceCpp
使中缀函数可用?
答案 0 :(得分:4)
是否可以通过
sourceCpp
使中缀函数可用?
是。
一如既往,您应该阅读Rcpp
vignettes!
特别是在这里,如果您查看the Rcpp attributes vignette的1.6节,就会发现可以使用Rcpp::export
的name参数来修改函数的名称。
例如,我们可以这样做:
#include <Rcpp.h>
// [[Rcpp::export(name = `%+%`)]]
Rcpp::NumericVector add(Rcpp::NumericVector x, Rcpp::NumericVector y) {
return x + y;
}
/*** R
1:3 %+% 4:6
*/
那么我们会得到:
Rcpp::sourceCpp("~/infix-test.cpp")
> 1:3 %+% 4:6
[1] 5 7 9
因此,您仍然必须在代码中命名有效的C ++名称的C ++函数,但是您可以通过Rcpp::export
的名称参数将其导出到R,而无需在R端做任何进一步的事情。
答案 1 :(得分:3)
约翰·钱伯斯(John Chambers)在(强烈推荐的)“扩展R”书的第四页上陈述了三个原则:
因此,对于第二点,您当然可以使用sourceCpp()
创建您的已编译函数,并将其挂在您喜欢的任何奇数中缀运算符上。
library(Rcpp)
cppFunction("std::string cc(std::string a, std::string b) { return a+b; }")
`%+%` <- function(a,b) cc(a,b)
cc("Hello", "World")
"hello" %+% "world"
R> library(Rcpp)
R> cppFunction("std::string cc(std::string a, std::string b) { return a+b; }")
R> `%+%` <- function(a,b) cc(a,b)
R>
R> cc("Hello", "World")
[1] "HelloWorld"
R>
R> "hello" %+% "world"
[1] "helloworld"
R>
Rcpp实际上只是机械中的一枚齿轮。
它还可以与您的初始功能一起使用,但略有简化。对于
`%op%` <- cppFunction("Eigen::MatrixXd op(Eigen::VectorXd x, Eigen::VectorXd y) { Eigen::MatrixXd op = x * y.transpose(); return op; }", depends="RcppEigen")
as.numeric(1:3) %op% as.numeric(3:1)
我们得到
R> `%op%` <- cppFunction("Eigen::MatrixXd op(Eigen::VectorXd x, Eigen::VectorXd y) { Eigen::MatrixXd op = x * y.transpose(); return op; }", depends="RcppEigen")
R> as.numeric(1:3) %op% as.numeric(3:1)
[,1] [,2] [,3]
[1,] 3 2 1
[2,] 6 4 2
[3,] 9 6 3
R>
(对来自编译器的一些线路噪声进行模运算)。