我的任务是用C++重写R函数来加速while循环.所有R代码都在Rcpp和Armadillo的帮助下重写,除了.Fortran().我尝试首先使用Rinside,它的工作速度非常慢,正如Dirk所指出的那样.(数据通过R - > C++ - > R - > Fortran是昂贵的)
由于我不想用C++重写Fortran代码,反之亦然,通过将C++直接链接到Fortran来加速程序看起来很自然:R - > C++ - > Fortran.
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
using namespace Rcpp;
extern "C"{
List f_(int *n,NumericMatrix a, NumericVector c, double* eps);
}
Run Code Online (Sandbox Code Playgroud)
问题是我可以将C++与Fortran集成并将R与C++集成,但我不能让这三个东西一起工作!
我尝试在Linux中编译C++,但它无法找到RcppArmadillo.h并且namespace Rcpp:
error: RcppArmadillo.h: No such file or directory
error: 'Rcpp' is not a namespace-name
Run Code Online (Sandbox Code Playgroud)
当我sourceCpp("test.cpp")直接打电话给R时,控制台会显示:
test.o:test.cpp:(.text+0x20b2): undefined reference to `f_'
collect2: ld returned 1 exit status
Error in sourceCpp("test.cpp") : Error occurred building shared library. …Run Code Online (Sandbox Code Playgroud) 在R中使用内联包中的cxx函数时,如何更改cpp编译器的优化标志?
默认情况下,在我的机器上,它编译-g -O2.但我想用-O3优化来提高速度.我使用Rcpp插件,如果这有任何区别.
我试过创建自己的插件,我试图设置cxx函数的不同参数,但没有任何效果.
我想一个选项是使用R CMD SHLIB而不是使用编译它cxxfunction.但是Rcpp建议使用它,inline因为他们的大多数测试用例都在使用它.
感谢您的帮助,如果您需要任何澄清,请与我们联系
在R中,如果我们有一个数据矩阵,比如一个100乘10矩阵X,一个带有可能值(0,1,2,3)的100个元素矢量t,我们可以很容易地找到一个简单的X矩阵y句法:
y = X[t == 1, ]
Run Code Online (Sandbox Code Playgroud)
但是,问题是,我怎么能用Rcpp的NumericMatrix做到这一点?
(或者,更一般地说,我怎么能在C++的任何容器中做到这一点?)
感谢Dirk的暗示,似乎是这样
NumericMatrix X(dataX);
IntegerVector T(dataT);
mat Xmat(X.begin(), X.nrow(), X.ncol(), false);
vec tIdx(T.begin(), T.size(), false);
mat y = X.rows(find(tIdx == 1));
Run Code Online (Sandbox Code Playgroud)
可以做我想做的事,但这似乎太冗长了.
我试图在我的win7 64位系统上嵌入RInside我的应用程序,但是当我初始化一个RInside时:
Rin = new RInside(argc, argv);
Run Code Online (Sandbox Code Playgroud)
出现以下消息:
loadNamespace(name)出错:没有名为'Rcpp'的包
此错误仅发生在Windows上.
我们知道Rf_error()在Rcpp中应该避免调用,因为它涉及堆栈上的C++析构函数的longjmp.这就是为什么我们宁愿在Rcpp代码中抛出C++异常(喜欢throw Rcpp::exception("...")或通过stop("...")函数).
但是,R警告也可能导致调用Rf_error()(此行为取决于warn选项).所以,打电话Rf_warning()也是有风险的.
Rcpp::sourceCpp(code = '
#include <Rcpp.h>
using namespace Rcpp;
class Test {
public:
Test() { Rcout << "start\\n"; }
~Test() { Rcout << "end\\n"; }
};
// [[Rcpp::export]]
void test() {
Test t;
Rf_warning("test");
}
')
options(warn=10)
test()
## start
## Error in test() : (converted from warning) test
Run Code Online (Sandbox Code Playgroud)
我们看到析构函数没有被调用(没有"结束"消息).
如何用C++生成R警告 - 对析构函数友好的方式?
我已经设法Rcpp.package.skeleton在R提示符下通过以下命令在Windows中安装 -
Rcpp.package.skeleton("mypackage")
system("R CMD build mypackage")
system("R CMD INSTALL mypackage")
library(mypackage)
Run Code Online (Sandbox Code Playgroud)
这创造了mypackage.dll.但是当我执行以下命令时 -
rcpp_hello_world <- function(){ .Call( "rcpp_hello_world", PACKAGE = "mypackage")}
rcpp_hello_world()
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
Error in .Call("rcpp_hello_world", PACKAGE = "mypackage") :
"rcpp_hello_world" not available for .Call() for package "mypackage"
Run Code Online (Sandbox Code Playgroud)
我跑了sessionInfo(),我得到以下内容:
attached base packages:
[1] tools stats graphics grDevices utils datasets methods base
other attached packages:
[1] mypackage_1.0 inline_0.3.13 Rcpp_0.11.1
Run Code Online (Sandbox Code Playgroud)
说我的新mypackage在那里.
我有什么进一步的检查可以看看发生了什么?有任何想法吗?
我正在尝试生成一个可以计算一系列加权产品的函数
其中W是对角矩阵.有许多W矩阵但只有一个X矩阵.
为了有效,我可以将W表示为包含对角线部分的数组(w).然后在R中这将是
crossprod(X, w*X)
要不就
crossprod(X * sqrt(w))
我可以循环W系列,但这似乎效率低下.整个产品可以作为只有w改变才能回收第i列和第j列的产品X_i*X_j.我想要制作的功能看起来像这样
Rcpp::List Crossprod_sparse(Eigen::MappedSparseMatrix<double> X, Eigen::Map<Eigen::MatrixXd> W) {
int K = W.cols();
int p = X.cols();
Rcpp::List crossprods(W.cols());
for (int k = 0; k < K; k++) {
Eigen::SparseMatrix<double> matprod(p, p);
for (int i = 0; i < p; i++) {
Eigen::SparseVector<double> prod = X.col(i).cwiseProduct(W.col(k));
for (int j = i; j < p; j++) {
double out = prod.dot(X.col(j));
matprod.coeffRef(i,j) = out;
matprod.coeffRef(j,i) = out;
}
}
matprod.makeCompressed();
crossprods[k] = matprod; …Run Code Online (Sandbox Code Playgroud) 在R中使用C++库的最佳方法是什么,希望保留C++数据结构.我不是一个C++用户,所以我不清楚可用方法的相对优点.R-ext手册似乎建议用C语言包装每个C++函数.但是,至少有四到五种其他的C++结合方法.
两种方式是具有类似谱系的包,Rcpp(由多产的overflower Dirk Eddelbuettel维护)和RcppTemplate包(都在CRAN上),两者之间有什么区别?
另一个可用的rcppbind包,声称采用不同的方法绑定C++和R(我不知道如何知道).
CRAN上提供的内联包声称允许内联C/C++我不确定这与内置功能有什么不同,除了允许代码内联w/R.
而且,最后RSwig似乎是在野外,但目前尚不清楚它是如何支持的,因为作者的页面多年来一直没有更新.
我的问题是,这些不同方法的相对优点是什么.哪些是最便携和最强大的,哪些是最容易实现的.如果您打算在CRAN上分发一个包,您会使用哪种方法?
仅仅为了完成我的C++/Rcpp编程,我开始实现(样本)标准偏差函数:
#include <Rcpp.h>
#include <vector>
#include <cmath>
#include <numeric>
// [[Rcpp::export]]
double cppSD(Rcpp::NumericVector rinVec)
{
std::vector<double> inVec(rinVec.begin(),rinVec.end());
int n = inVec.size();
double sum = std::accumulate(inVec.begin(), inVec.end(), 0.0);
double mean = sum / inVec.size();
for(std::vector<double>::iterator iter = inVec.begin();
iter != inVec.end(); ++iter){
double temp;
temp= (*iter - mean)*(*iter - mean);
*iter = temp;
}
double sd = std::accumulate(inVec.begin(), inVec.end(), 0.0);
return std::sqrt( sd / (n-1) );
}
Run Code Online (Sandbox Code Playgroud)
我还决定测试stddevArmadillo库中的函数,考虑到它可以在向量上调用:
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
using namespace Rcpp;
// [[Rcpp::export]]
double armaSD(arma::colvec …Run Code Online (Sandbox Code Playgroud) 我创建了一个for循环,我想使用Rcpp库来加速它.我对C++不太熟悉.你能帮助我更快地完成我的功能吗?谢谢您的帮助!
我已将算法,代码以及输入和输出与sessionInfo一起包括在内.
这是我的算法:
如果当前价格高于先前价格,则在名为TR的列中标记(+1)
如果当前价格低于先前价格,则在名为TR的列中标记(-1)
如果当前价格与先前价格相同,则在名为TR的列中标记与先前价格相同的价格
这是我的代码:
price <- c(71.91, 71.82, 71.81, 71.81, 71.81, 71.82, 71.81, 71.81, 71.81,
71.82, 71.81, 71.81, 71.8, 71.81, 71.8, 71.81, 71.8, 71.8, 71.8,
71.8, 71.81, 71.81, 71.81, 71.81, 71.81, 71.81, 71.81, 71.81,
71.81, 71.82, 71.81, 71.81, 71.81, 71.81, 71.81, 71.81, 71.8,
71.8, 71.81, 71.81, 71.81, 71.81, 71.82, 71.82, 71.81, 71.81,
71.81, 71.81, 71.81, 71.81, 71.81, 71.82, 71.82, 71.82, 71.82,
71.82, 71.82, 71.82, 71.81, 71.82, 71.82, 71.82, 71.82, 71.82,
71.82, 71.82, 71.82, 71.82, 71.81, …Run Code Online (Sandbox Code Playgroud)