emadalamoudi emadalamoudi - 24 days ago 7
R Question

Fatal error when tring to call C++ function from R

I have a C++ function called "file1.cpp" that looks like:

#include <cmath>
#include <stdio.h>
#include <RcppArmadillo.h>
#include <boost/math/special_functions/gamma.hpp>
#include <mpi.h>
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
using namespace std;
using namespace arma;
using namespace boost::math;
const double PIVAL = std::acos(0.0)*2;
class function1
{
...
}
extern "C"
void functin2
{
...
}


I want to call it from an R function. In order to do that I needed to compile it first to get the "file1.so", which I can use it later in the R command:

dyn.load("file1.so.so")


So it ubuntu 16.10 terminal I wrote:

$ R CMD SHLIB file1.cpp -O2 -larmadillo -llapack -lblas


when I press enter I will get the follwing error message:

g++ -I/usr/share/R/include -DNDEBUG -fpic -g -O2 -fdebug-prefix-map=/build/r-base-rAT5Oi/r-base-3.3.1=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -g -c file1.cpp -o file1.o
file1.cpp:12:81: fatal error: RcppArmadillo.h: No such file or directory
#include <RcppArmadillo.h>


I couldn't find solution for that error. So, I tried to call the C++ function from inside Rstudio. I wrote the follwing commands:

library(Rcpp)
library(RcppArmadillo)
sourceCpp("file1.cpp")
function2()


When executing it I will get this error:

file1.cpp:11:81: fatal error: RcppArmadillo.h: No such file or directory


Anybody have an idea about how to solve it? Thanks in advance.

Best Regards,

Answer

Please read some of the many existing examples on RcppArmadillo here, at the Rcpp Gallery or, heaven forbid, in the package documentation.

You could of course just call RcppArmadillo.package.skeleton() and have a working package created for you to start from and place your local changes in.

See this:

R> setwd("/tmp")
R> RcppArmadillo::RcppArmadillo.package.skeleton("demoPkg")

Calling kitten to create basic package.
Creating directories ...
Creating DESCRIPTION ...
Creating NAMESPACE ...
Creating Read-and-delete-me ...
Saving functions and data ...
Making help files ...
Done.
Further steps are described in './demoPkg/Read-and-delete-me'.

Adding pkgKitten overrides.
Deleted 'Read-and-delete-me'.
Done.

Consider reading the documentation for all the packaging details.
A good start is the 'Writing R Extensions' manual.

And run 'R CMD check'. Run it frequently. And think of those kittens.


Adding RcppArmadillo settings
 >> added Imports: Rcpp
 >> added LinkingTo: Rcpp, RcppArmadillo
 >> added useDynLib and importFrom directives to NAMESPACE
 >> added Makevars file with Rcpp settings
 >> added Makevars.win file with RcppArmadillo settings
 >> added example src file using armadillo classes
 >> added example Rd file for using armadillo classes
 >> invoked Rcpp::compileAttributes to create wrappers
R> 

which creates, _inter alia, this file:

// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*-

// we only include RcppArmadillo.h which pulls Rcpp.h in for us
#include "RcppArmadillo.h"

// via the depends attribute we tell Rcpp to create hooks for
// RcppArmadillo so that the build process will know what to do
//
// [[Rcpp::depends(RcppArmadillo)]]

// simple example of creating two matrices and
// returning the result of an operatioon on them
//
// via the exports attribute we tell Rcpp to make this function
// available from R
//
// [[Rcpp::export]]
arma::mat rcpparma_hello_world() {
    arma::mat m1 = arma::eye<arma::mat>(3, 3);
    arma::mat m2 = arma::eye<arma::mat>(3, 3);

    return m1 + 3 * (m1 + m2);
}


// another simple example: outer product of a vector, 
// returning a matrix
//
// [[Rcpp::export]]
arma::mat rcpparma_outerproduct(const arma::colvec & x) {
    arma::mat m = x * x.t();
    return m;
}

// and the inner product returns a scalar
//
// [[Rcpp::export]]
double rcpparma_innerproduct(const arma::colvec & x) {
    double v = arma::as_scalar(x.t() * x);
    return v;
}


// and we can use Rcpp::List to return both at the same time
//
// [[Rcpp::export]]
Rcpp::List rcpparma_bothproducts(const arma::colvec & x) {
    arma::mat op = x * x.t();
    double    ip = arma::as_scalar(x.t() * x);
    return Rcpp::List::create(Rcpp::Named("outer")=op,
                              Rcpp::Named("inner")=ip);
}

and that should be enough to get you going.

Comments