假设我有一个c ++代码(参见下面的一个简单示例)。 我希望日记裁判能够轻松安装/运行 它
所以我认为最简单的方法是将其变形为简化版 R包类似的tar.gz文件,所以裁判可以安装它 只需将install.packages调用到本地.tar.gz文件即可。
原因是我不知道什么机器了 裁判正在使用,但我很确定裁判会这样做 知道如何安装R软件包,因此更容易 我将我的代码变成R'包' - 无论如何, 与它完全相似的东西 通过简单调用install.package()安装。
对早期question的回答似乎暗示了这一点 确实可能。我按照其中的建议和 使用我的cpp代码创建了一个/ src目录(显示的那个) 下面)和一个包含:
的Makevars.win文件## This assume that we can call Rscript to ask Rcpp about its locations
## Use the R_HOME indirection to support installations of multiple R version
#PKG_LIBS = $(shell $(R_HOME)/bin/Rscript.exe -e "Rcpp:::LdFlags()")
PKG_CPPFLAGS = -I../inst/include -I.
PKG_CXXFLAGS = -DEIGEN_DONT_PARALLELIZE $(SHLIB_OPENMP_CXXFLAGS)
PKG_LIBS = $(shell $(R_HOME)/bin/Rscript.exe -e "Rcpp:::LdFlags()") $(SHLIB_OPENMP_CXXFLAGS)
和包含以下内容的Makevars文件:
## Use the R_HOME indirection to support installations of multiple R version
#PKG_LIBS = `$(R_HOME)/bin/Rscript -e "Rcpp:::LdFlags()"`
# This was created by RcppEigen.package.skeleton, but the R script that is
# called creates error message:
# PKG_CPPFLAGS = `$(R_HOME)/bin/Rscript -e "RcppEigen:::RcppEigenCxxFlags()"`
PKG_CPPFLAGS = -I../inst/include
PKG_CXXFLAGS = -DEIGEN_DONT_PARALLELIZE $(SHLIB_OPENMP_CXXFLAGS)
PKG_LIBS = `$(R_HOME)/bin/Rscript -e "Rcpp:::LdFlags()"` $(SHLIB_OPENMP_CXXFLAGS)
e.g。我只是按照SO帖子中的答案来四处寻找 这是在其他包中完成的(我还将RcppEigen添加到依赖项列表中,因为 这保证了Eigen安装在目标机器上)。我还创建了一个包含文件MSE.R的/ R目录,其中包含:
fx01<-function(x){
x<-as.matrix(x)
Dp<-rep(0,ncol(x))
fit<-.C("mse",as.integer(nrow(x)),as.integer(ncol(x)),as.single(x),as.single(Dp))
as.numeric(fit[[4]])
}
和一个空的/ inst / include和一个包含最小(但有效).Rd文件的/ man目录。 我添加了一个包含以下内容的NAMESPACE文件:
import(Rcpp)
import(RcppEigen)
useDynLib(MySmallExample)
以下是问题:
这是用于此示例的c ++代码。
#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <functional>
#include <fstream>
#include <iostream>
#include <math.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <sstream>
#include <vector>
#include <Eigen/Dense>
#include <Eigen/LU>
#include <Eigen/SVD>
using namespace std;
using namespace Eigen;
using Eigen::MatrixXf;
using Eigen::VectorXf;
float median(VectorXf& x) {
int n=x.rows();
int half=(n+1)/2;
half--;
float med;
nth_element(x.data(),x.data()+half,x.data()+x.size());
if((n%2)==1){
med=x(half);
} else {
float tmp0=x(half);
float tmp1=x.segment(half+1,half-1).minCoeff();
med=0.5*(tmp0+tmp1);
}
return med;
}
VectorXf fx01(MatrixXf& x){
int p=x.cols();
int n=x.rows();
VectorXf Recept(n);
VectorXf Result(p);
for(int i=0;i<p;i++){
Recept=x.col(i);
Result(i)=median(Recept);
}
return Result;
}
extern "C"{
void mse(int* n,int* p,float* x,float* medsout){
MatrixXf x_cen=Map<MatrixXf>(x,*n,*p);
VectorXf MedsOut=fx01(x_cen);
Map<VectorXf>(medsout,*p)=MedsOut.array();
}
}
答案 0 :(得分:4)
您是否阅读了有关如何与R接口的`Writing R Extensions'手册?
你当然在没有Rcpp的情况下可以自由地做到这一点,但是我们写了Rcpp供我们使用,因为我们发现它使这些交换变得更容易。使用Rcpp的CRAN上的94个软件包似乎同意......
您正在使用Eigen,并且您希望将其打包为第三方(“裁判”)。现在,如果您使用RcppEigen ,您可以确保Eigen存在,因为它在RcppEigen 中。做你做的,你不是......
另外,.C()
是一个限制性更强的界面.Call()
。
答案 1 :(得分:2)
拥有正确的DESCRIPTION文件非常重要。 我用过这个:
Package: MySmallExample
Type: Package
Title: MysmallExample
Version: 0.0.0
Date: 2012-12-24
Depends: Rcpp (>= 0.9.10)
Imports: RcppEigen (>= 0.2.0)
Suggests: mvtnorm
LinkingTo: Rcpp, RcppEigen
Description: A small minimal Package.
License: GPL (>= 2)
LazyLoad: yes
Authors@R: person("joe", "programer", email =
"joe.programer@joe_inc.com", role = c("aut", "cre"))
Collate: 'MSE.R'
Packaged: 2012-12-24 12:34:56 UTC; andi
Author: joe programer [aut, cre]
Maintainer: joe programer <joe.programer@joe_inc.com>
Repository: CRAN
Date/Publication: 2012-12-24 12:34:56
最重要的似乎是'Collate:'字段:它应该正确列出 / R目录中的所有.R文件。取决于&amp; Imports字段也应该与NAMESPACE文件一致。
文件NAMESPACE包含一行
也非常重要export("fx01","fx02")
其中“fx01”,“fx02”是其中所有R函数的名称 /R/*.R文件(在这种情况下,只是fx01)。
然后,我将整件事包裹在.tar.gz中。然后跑了
install.packages("MySmallExample.tar.gz",repos=NULL,type="source")
> install.packages("/MySmallExample.tar.gz",repos=NULL,type="source")
Installing package(s) into ‘/R/x86_64-pc-linux-gnu-library/2.15’
(as ‘lib’ is unspecified)
* installing *source* package ‘MySmallExample’ ...
** libs
g++ -I/usr/share/R/include -DNDEBUG -I../inst/include -I"/R/x86_64-pc-linux-gnu-library/2.15/Rcpp/include" -I"/R/x86_64-pc-linux-gnu-library/2.15/RcppEigen/include" -DEIGEN_DONT_PARALLELIZE -fopenmp -fpic -O3 -pipe -g -c MSE.cpp -o MSE.o
g++ -shared -o MySmallExample.so MSE.o -L/R/x86_64-pc-linux-gnu-library/2.15/Rcpp/lib -lRcpp -Wl,-rpath,/R/x86_64-pc-linux-gnu-library/2.15/Rcpp/lib -fopenmp -L/usr/lib/R/lib -lR
installing to /R/x86_64-pc-linux-gnu-library/2.15/MySmallExample/libs
** R
** inst
** preparing package for lazy loading
** help
*** installing help indices
** building package indices
** testing if installed package can be loaded
* DONE (MySmallExample)