gpt4 book ai didi

c++ - 如何(轻松)将 C++ 函数包装到易于安装的 R 'package'

转载 作者:太空宇宙 更新时间:2023-11-04 15:47:37 28 4
gpt4 key购买 nike

假设我有一个 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)

例如我只是按照 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++ 函数可以正常编译/运行。有没有办法将其转换为 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 交互的“Writing R Extensions”手册?

在没有 Rcpp 的情况下,您当然可以自由地执行此操作,但我们编写 Rcpp 供我们使用,因为我们发现它使这些交换变得更加容易。 CRAN 上使用 Rcpp 的 94 个包似乎同意...

您正在使用 Eigen,并且您希望将其打包供第三方(“裁判”)使用。现在,如果你要使用 RcppEigen 你会确保 Eigen 存在于 RcppEigen 中。通过你所做的,你不是...

另外,.C() 是一个比 .Call() 限制更多的接口(interface)。

关于c++ - 如何(轻松)将 C++ 函数包装到易于安装的 R 'package',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14034868/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com