JunhuiLi
JunhuiLi

Reputation: 107

how to compile function in C code using RcppEigen

I am very new to Rcpp, or more specifically RcppEigen, and struggling with how to use RcppEigen to compile C++ function. Here is the C++ code in which some problems maybe exist.

#include <RcppEigen.h>
#include <string>

using namespace Eigen;
using namespace Rcpp;

double MatOp(const Map<MatrixXd> X, Map<MatrixXd> Y)
{ 

  int n=X.rows();
  int p=X.cols();
  //int nY=Y.cols();
  MatrixXd I(n,n);
  I.setIdentity(n,n);
  double SSE=(Y.transpose()*(I-X*(X.transpose()*X).inverse()*X.transpose())*Y).determinant();
  return (n*log(SSE/n)+log(n)*p);
}

And here is R code,

> getwd()
[1] "C:/Users/LJH/Documents"
> RcppEigen.package.skeleton("PfCRT")

> RCppEigen_IcPf_R <- function(X,Y) {
+   .Call('TestInRcppEigen',X,Y,PACKAGE = 'PfCRT')
+ }
> 
> prompt(RCppEigen_IcPf_R)

.Rcheck file is,

* installing *source* package 'PfCRT' ...
** libs

*** arch - i386
cygwin warning:
  MS-DOS style path detected: C:/R/R-31~1.1/etc/i386/Makeconf
  Preferred POSIX equivalent is: /cygdrive/c/R/R-31~1.1/etc/i386/Makeconf
  CYGWIN environment variable option "nodosfilewarning" turns off this warning.
  Consult the user's guide for more details about POSIX paths:
    http://cygwin.com/cygwin-ug-net/using.html#using-pathnames
g++ -m32 -I"C:/R/R-31~1.1/include" -DNDEBUG    -I"C:/Users/LJH/Documents/R/win-library/3.1/Rcpp/include" -I"C:/Users/LJH/Documents/R/win-library/3.1/RcppEigen/include" -I"d:/RCompile/CRANpkg/extralibs64/local/include"     -O2 -Wall  -mtune=core2 -c TestInRcppEigen.cpp -o TestInRcppEigen.o
g++ -m32 -shared -s -static-libgcc -o PfCRT.dll tmp.def TestInRcppEigen.o -Ld:/RCompile/CRANpkg/extralibs64/local/lib/i386 -Ld:/RCompile/CRANpkg/extralibs64/local/lib -LC:/R/R-31~1.1/bin/i386 -lR
cygwin warning:
  MS-DOS style path detected: C:/R/R-31~1.1/etc/i386/Makeconf
  Preferred POSIX equivalent is: /cygdrive/c/R/R-31~1.1/etc/i386/Makeconf
  CYGWIN environment variable option "nodosfilewarning" turns off this warning.
  Consult the user's guide for more details about POSIX paths:
    http://cygwin.com/cygwin-ug-net/using.html#using-pathnames
installing to C:/Users/LJH/Documents/PfCRT.Rcheck/PfCRT/libs/i386

*** arch - x64
cygwin warning:
  MS-DOS style path detected: C:/R/R-31~1.1/etc/x64/Makeconf
  Preferred POSIX equivalent is: /cygdrive/c/R/R-31~1.1/etc/x64/Makeconf
  CYGWIN environment variable option "nodosfilewarning" turns off this warning.
  Consult the user's guide for more details about POSIX paths:
    http://cygwin.com/cygwin-ug-net/using.html#using-pathnames
g++ -m64 -I"C:/R/R-31~1.1/include" -DNDEBUG    -I"C:/Users/LJH/Documents/R/win-library/3.1/Rcpp/include" -I"C:/Users/LJH/Documents/R/win-library/3.1/RcppEigen/include" -I"d:/RCompile/CRANpkg/extralibs64/local/include"     -O2 -Wall  -mtune=core2 -c TestInRcppEigen.cpp -o TestInRcppEigen.o
g++ -m64 -shared -s -static-libgcc -o PfCRT.dll tmp.def TestInRcppEigen.o -Ld:/RCompile/CRANpkg/extralibs64/local/lib/x64 -Ld:/RCompile/CRANpkg/extralibs64/local/lib -LC:/R/R-31~1.1/bin/x64 -lR
cygwin warning:
  MS-DOS style path detected: C:/R/R-31~1.1/etc/x64/Makeconf
  Preferred POSIX equivalent is: /cygdrive/c/R/R-31~1.1/etc/x64/Makeconf
  CYGWIN environment variable option "nodosfilewarning" turns off this warning.
  Consult the user's guide for more details about POSIX paths:
    http://cygwin.com/cygwin-ug-net/using.html#using-pathnames
installing to C:/Users/LJH/Documents/PfCRT.Rcheck/PfCRT/libs/x64
** R
** preparing package for lazy loading
** help
*** installing help indices
** building package indices
** testing if installed package can be loaded
*** arch - i386
*** arch - x64
* DONE (PfCRT)

Then I do this,

> library(PfCRT)
> X1 <- matrix(c(1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,0,2,0,1,0,2,0,1,0,2,0,1,0,2,0,1,
+                0,2,0,1,0,0,3,1,0,0,3,1,0,0,3,1,0,0,3,1,0,0,3,1,0,0,3,1,0,0,3,1,0,0,3,1,0,
+                0,3,1,0,0,3.01),20,4,byrow=TRUE)
> Y <- matrix(c(50,51,52,54,53,60,59,65,67,70,70,73,74,78,82,80,87,84,88,92),20,1)
> 
> RCppEigen_IcPf_R(X1,Y)
Error in .Call("TestInRcppEigen", X, Y, PACKAGE = "PfCRT") : 
  "TestInRcppEigen" not available for .Call() for package "PfCRT"

Error occurs, so I guess something wrong in double MatOp(const Map<MatrixXd> X, Map<MatrixXd> Y) function in C++. Any help will be very appreciated.

Upvotes: 0

Views: 337

Answers (1)

Dirk is no longer here
Dirk is no longer here

Reputation: 368231

Your C++ function is called "MatOp":

double MatOp(const Map<MatrixXd> X, Map<MatrixXd> Y)

but instead you call "TestInRcppEigen":

.Call('TestInRcppEigen',X,Y,PACKAGE = 'PfCRT')

which gets the error

Error in .Call("TestInRcppEigen", X, Y, PACKAGE = "PfCRT") : 
  "TestInRcppEigen" not available for .Call() for package "PfCRT"

which is correct: you did not provide a TestInRcppEigen.

Either provide TestInRcppEigen (by renaming 'MatOp' to it) or call MatOp.

None of this has anything to do with RcppEigen per se, you're simply getting lost in the weeds of how to call C++ from R. Look at the Rcpp Attributes vignette -- it can really help and simplify.

Upvotes: 1

Related Questions