On Fri, 10 May 2019 16:17:42 +0000 "Wang, Zhu" <wan...@uthscsa.edu> wrote:
> Are there any examples or links for me to follow through more closely? Calling R functions from C++ is described at <http://dirk.eddelbuettel.com/code/rcpp/Rcpp-quickref.pdf> and elsewhere in Rcpp documentation. An example follows: --------------8<--------------glmfit.cpp--------------8<-------------- #include <algorithm> #include <Rcpp.h> using namespace Rcpp; extern "C" double intercept_glm(size_t n, const double * response) { // access functions from default environment Function glm_fit("glm.fit"), coef("coef"); // intercept-only model: response ~ 1 NumericVector x(n); x.fill(1); // I couldn't find a way to wrap a double* into a NumericVector // without copying anything, sorry; perhaps someone else // can offer a solution NumericVector y(n); std::copy_n(response, n, y.begin()); // call the R function, convert the result back return as<double>(coef(glm_fit(x, y))); } --------------8<--------------glmfit.cpp--------------8<-------------- Since this function is extern "C" and uses only primitive C types, it should be fairly easy to call from Fortran. (C is the lingua franca of programming languages). Fortran-C interoperability is well described in "Modern Fortran Explained" by Metcalf et al. Here is the Fortran side of the code: --------------8<--------------callglm.f90--------------8<-------------- subroutine callglm(ret) use, intrinsic :: iso_c_binding, only: c_size_t, c_double ! using iso_c_binding here ! - to get correct type of ret when R calls the function ! - to convert variables before calling C function implicit none ! using F77-style arguments to match expectations of .Fortran() real(c_double), intent(out) :: ret ! toy data to compare against R code later real :: y(10) = [10, 11, 20, 9, 10, 8, 11, 45, 2, 3] ! the interface block declares an extern "C" function interface ! double intercept_glm(size_t n, const double * response) function intercept_glm(n, response) bind(c) use, intrinsic :: iso_c_binding real(c_double) :: intercept_glm integer(c_size_t), value :: n real(c_double) :: response(*) end function end interface ! call the function as you would call any other function ret = intercept_glm(int(size(y), c_size_t), real(y, c_double)) end subroutine --------------8<--------------callglm.f90--------------8<-------------- For a quick test, make sure that you have Rcpp installed and run: # adjust R version and path if your library is elsewhere PKG_CPPFLAGS='-g -I ~/R/x86_64-pc-linux-gnu-library/3.3/Rcpp/include' \ R CMD SHLIB callglm.f90 glmfit.cpp R library(Rcpp) dyn.load('callglm.so') # change extension if needed .Fortran('callglm', ret=numeric(1)) # $ret # [1] 12.9 coef(glm.fit(rep(1, 10), c(10, 11, 20, 9, 10, 8, 11, 45, 2, 3))) # [1] 12.9 To use this in a package, place both files in the src/ subdirectory of your package and add LinkingTo: Rcpp in the DESCRIPTION. -- Best regards, Ivan ______________________________________________ R-package-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-package-devel