假設我有一個C++代碼(參見下面的簡單示例)。 我想讓日記裁判輕鬆安裝/運行 它。如何(輕鬆地)將C++函數包裝成易於安裝的R'包'
所以我想最簡單的方法是扭曲的,給一個簡單的 [R包般的tar.gz文件,使裁判可以通過簡單地調用install.packages到本地.tar.gz文件安裝 。
這樣做的原因是,我不知道 裁判是用什麼機器,但我敢肯定裁判會 知道如何安裝的R程序包,以便它是 我扭曲我的代碼更容易作爲一個R'包' - 或者無論如何, 的東西足夠類似於它可以通過簡單調用install.package()安裝的 。
回答較早的question似乎表明這 確實是可能的。我跟着建議在其中和 創建/ src目錄與我的cpp代碼(所示的下面 )和含有一個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)
例如我只是遵循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]])
}
和空/安裝/包括和一個含有最小(但有效的).Rd文件/ man目錄。 我已經添加含有NAMESPACE文件:
import(Rcpp)
import(RcppEigen)
useDynLib(MySmallExample)
這裏是這樣的問題:
- C++函數否則編譯/運行良好。有沒有辦法將它翹曲成R包,以便於第三方安裝/運行。
這裏是用於這個例子的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();
}
}
不,我沒有看過那個文件。我希望有人能指點我一個更短的版本(我不打算很快提交給任何人 - 只是將R的基礎設施作爲載體)。謝謝,你的第三段是強調RcppEigen - 我已經編輯了相應的問題。我同意.Call()和.C()的優點,但是在這一點上,我的代碼已經寫在了R中。我只是尋找一種無憂無慮的方式,使得它可以很容易地運行/安裝由不需要計算機熟練的人(超過小費'安裝.package'在R) – user189035
問題解決。謝謝!我會寫我做錯了什麼... – user189035