有什么方法可以使用 sourceCpp() 创建中缀函数
Is there any way in which to make an Infix function using sourceCpp()
我想知道是否可以制作一个中缀函数,例如A %o% B
与 Rcpp。
我知道使用 inline
包可以做到这一点,但是在使用 sourceCpp()
.
时我还没有找到这样做的方法
当参数肯定是使用RcppEigen
和inline
的向量时,我已经实现了%o%
/outer()
的以下中缀实现:
`%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()
导入,但不能作为中缀函数。
我目前的尝试如下:
#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
提供中缀函数?
John Chambers 在(强烈推荐)"Extending R" 一本书的第四页阐述了三项原则:
- R 中存在的一切都是对象。
- R 中发生的一切都是函数调用。
- 与其他软件的接口是 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>
(模数来自编译器的一些线路噪声)。
Is it possible to make an infix function available through sourceCpp
?
是.
一如既往,应该阅读 Rcpp
vignettes!
特别是在这里,如果您查看 the Rcpp attributes vignette 的第 1.6 节,您会发现您可以使用 Rcpp::export
的名称参数修改函数的名称。
例如,我们可以这样做:
#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 端做任何进一步的操作。
我想知道是否可以制作一个中缀函数,例如A %o% B
与 Rcpp。
我知道使用 inline
包可以做到这一点,但是在使用 sourceCpp()
.
当参数肯定是使用RcppEigen
和inline
的向量时,我已经实现了%o%
/outer()
的以下中缀实现:
`%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()
导入,但不能作为中缀函数。
我目前的尝试如下:
#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
提供中缀函数?
John Chambers 在(强烈推荐)"Extending R" 一本书的第四页阐述了三项原则:
- R 中存在的一切都是对象。
- R 中发生的一切都是函数调用。
- 与其他软件的接口是 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>
(模数来自编译器的一些线路噪声)。
Is it possible to make an infix function available through
sourceCpp
?
是.
一如既往,应该阅读 Rcpp
vignettes!
特别是在这里,如果您查看 the Rcpp attributes vignette 的第 1.6 节,您会发现您可以使用 Rcpp::export
的名称参数修改函数的名称。
例如,我们可以这样做:
#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 端做任何进一步的操作。