Why do we both "include" and "depends" on RcppArmadillo? - r

To use RcppArmadillo, we're often instructed to have the following lines at the top:
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
Why do we need both? Isn't the #include directive sufficient for us to have access to all functions defined inside the scope of RcppArmadillo?

There are two different things at play:
The compiler needs the header RcppArmadillo.h in order to know about types from (Rcpp)Armadillo, Rcpp (as this one pulls in Rcpp.h as well) and therefore R. I presume you know you need this. But ...
How would R know to add the -I... flag required for this? It wouldn't!
At a package level the LinkingTo: helps for the header case. But in deeper sense sometimes we need headers and linking (ie RcppGSL) and in that case, the hook we have here via Rcpp::depends into Rcpp Attributes ensures we can do this.
So the // [[Rcpp::depends(RcppArmadillo)]] helps for sourceCpp() use. It is not needed in a package. "Plugins" like this are discussed a little in the Rcpp Attributes vignette.

Related

Combine R, C++ and Fortran

I am trying to reimplement an R function using C++ and RCpp to speed up the computation. And in the C++ implementation, I need to use a Fortran function mvtdst found in link.
#include <Rcpp.h>
#include "mvtnorm.h"
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector pmvnorm_rcpp(NumericVector upper, NumericMatrix corr)
{
double error;
double mvnP = pmvnorm_P(2, upper, corr, &error) ;
return mvnP ;
}
/*** R
pmvnorm_rcpp(c(1.5,1.5),c(0.0))
*/
Here, pmvnorm_P is defined in the mvtnorm.cpp file.
All the files found in link are kept in the working directory along with the RcppWrapper.cpp file.
When I compile my RcppWrapper.cpp file using sourceCpp() function in RCpp package, it gives the following error.
mvtnorm.o:mvtnorm.cpp:(.text+0x7c): undefined reference to `mvtdst_'
collect2.exe: error: ld returned 1 exit status
Error in Rcpp::sourceCpp("RcppWrapper.cpp") :
Error occurred building shared library.
Does anyone know how to resolve this error?
When you have code in two sources files
mvtnorm.cpp calling your backend function pmvnorm_P()
another file providing it
then you also must provide link instructions. Simply put, sourceCpp() is only intentended and working for one-file solutions (unless you give link instructions).
Simplest fix: just create a package assembling all your files in src/.
Fortran and C++ mangle the names of functions differently. It looks like mvtdst is the name of your Fotran function. (Right?) You need to "mangle" that by hand when called from C++. So instead of calling mvtdst, call mvtdst_ with the trailing underscore.
Unfortunately, compilers are not consistent in the mangling, so this will not be portable. (To make it portable, you'll need some sort of preprocessing that matched the mangling to the compiler.)

Documenting Rcpp module exposed methods with roxygen2

I have an Rcpp module in my package which, as well as exposing the class, exposes a number of methods. Is it possible to document the methods (on the C++ side) using roxygen2? My module looks like this:
RCPP_MODULE(BayesFst) {
using namespace Rcpp;
class_<BayesFst>( "BayesFst")
.default_constructor("Standard constructor")
.method("printData", &BayesFst::printData)
.method("printCounts", &BayesFst::printCounts)
.method("printInitialPvals", &BayesFst::printInitialPvals)
.method("printFstSummary", &BayesFst::printFstSummary)
.method("run", &BayesFst::run)
.method("setData", &BayesFst::setData)
.method("setPriorParameters", &BayesFst::setPriorParameters)
.method("setRunParameters", &BayesFst::setRunParameters)
.method("ldiriTest", &BayesFst::ldiriTest)
.property("interaction", &BayesFst::getInteraction, &BayesFst::setInteraction)
;
}
I would like to document all of these methods ideally. A simple idea is to hide the class behind wrapper functions and then call the methods from within R wrapper functions, but this feels kind of inelegant to me.
I have tried adding the roxygen comment lines to the functions, but because they don't get exported in the same way the documentation doesn't seem to get picked up.
You will not be able to rely on Rcpp to carry the roxygen documentation over the way compileAttributes() would ... as you are not invoking compileAttributes().
Feel free to construct (and test and then contribute :) a new helper function; otherwise I would just use roxygen in an R file and proceed from there.
Edit: I also filed an issue so that we don't forget about it.

Equivalent of c++ include in R

I have 3 scripts logs.R, func.R, main.R and I want to log from main and also from func scripts. I know that I can use source, for having the functions in both scripts, but sourcing logs in func and in main, is the same of sourcing it 2 times (I source func in main). Is there any equivalent of #pragma once or #ifndef #define #endif from C++ ?
You can mimic that with a custom variable and a condition.
logs.R
...
log.sourced <- TRUE
func.R
if(!exists("log.sourced")) source("logs.R")
...
main.R
if(!exists("log.sourced")) source("logs.R")
...
Or just test exists("func") where func is defined in logs.R
use the source("otherfile.R") to include the content of other files. (equivalent of include).
As R is directly interpreted and no preprocessed, there is not equivalent of #pragma once or include guards directive.
One way to replace the include guards would be to write in directly in R.
Since there’s no proper solution in base R and other solutions require on hacky mechanisms like include guards, I wrote my own package: ‘box’.
With modules you can for instance write the following code:
box::use(./logs)
And now you can use logs like a package/namespace you’re used to in other languages: logs$log('Some string I’d like to log.'). Or, alternatively, you could do
box::use(./logs[...])
This mimics R’s normal attaching mechanism, and is similar to using namespace foo in C++. See the ‘box’ vignette for a more in-depth introduction.

Rcpp: Call C function from a package within Rcpp

I would like to write a C++ function with Rcpp that uses a C function found in the package hypred, which is on CRAN here.
I read using C function from other package in Rcpp, but don't understand if this applies for me and if it would apply, what to do.
The desired function is in the the source file /src/hypredRoutines.c and is called meiosisFUNAllChr.
What I so far did based on this SO question here is:
I separated the function meiosisFUNAllChr from the rest of the code and placed it in a new file called meiosisFUNAllChr.c.
I created a header file called meiosisFUNAllChr.h containing:
#ifndef MEIOSISFUNALLCHR_H
#define MEIOSISFUNALLCHR_H
void meiosisFUNallChr (...);
#endif
Compiled it with
gcc -c -o meiosisFUNAllChr.o meiosisFUNAllChr.c
Created a dummy c++ function
#include <Rcpp.h>
using namespace Rcpp;
extern "C" {
#include "meiosisFUNallChr.h"
}
// [[Rcpp::export]]
int timesTwo(int x) {
return x * 2;
}
At this point, compiling with sourceCpp does not work. Can you show me how to get it working?
Many Thanks!
EDIT
Compiling with sourceCpp gives me:
meiosisFUNallChr.h: file or directory not found
hypred registers its two functions, at the R level you can get hold of the one you want like this:
xp <- getDLLRegisteredRoutines( getLoadedDLLs()[["hypred"]] )[[".C"]][["meiosisFUNallChr"]]$address
I believe you can then access the function pointer in C++ like this:
DL_FUNC meiosisFUNallChr = reinterpret_cast<DL_FUNC>( R_ExternalPtrAddr(xp) ) ;
But you'd be better off negotiating with the package authors that they implement this scheme if you can make a case that you really need to be calling the C function directly.
Briefly:
You want to use another source file (presumably available under a suitable license).
You want to call it from a new file of yours.
So you already have two files.
By now the alarm bells should go off that you really, really, want to create a package.
Which the Rcpp documentation details in many places. And there are 340+ packages on CRAN using Rcpp, many doing this very issue of calling a C file too. Pick one or two, study their structure; also pick one or two created by the fully documented Rcpp tools such as Rcpp.package.skeleton() and things should become a lot clearer.
Edit: Obviously, this approach only needs to be taken if the other package does not export its function. If you can get its author to export, use that as mention in Romain's answer. Pairs of packages that export/use are zoo/xts, xts/RcppXts, expm/RcppKalman (not on CRAN), RApiSerialize/RcppRedis, ...

Error when building R package using roxygen2

I have 2 files, Rfile.R and Cppfile.cpp.
Contents in Cppfile.cpp:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
int CPPF(int k){return ++k;}
Contents in Rfile.R:
RF<-function(k){return(CPPF(k))}
I want to build an R package based on the 2 files. I use the lastest versions of Rstudio and Roxygen2.
I tried 3 ways to build the package with or without Roxygen2, and had different results:
New Project->New Directory->R package->Type:Package w/Rcpp, add both Rfile.R and Cppfile.cpp as source files. Build & reload, everything works out fine. The functions work as they do.
New Project->New Directory->R package->Type:Package w/Rcpp, add both Rfile.R and Cppfile.cpp as source files. Select "Generate documentations with Roxygen", check all its options. Build & Reload, the functions don't work. Inputting "RF" gives the contents of RF, inputting "CPPF" pops "Object not found".
New Project->New Directory->R package->Type:Package w/Rcpp, add only Cppfile.cpp as source files. Select "Generate documentations with Roxygen", check all its options. Build & Reload, the function works.
Then copy Rfile.R directly into the project folder->R folder. Build & Reload, everything fine, functions work well.
Am I using the Roxygen wrong or Roxygen has bugs? I need it to document. I can stick to the 3rd way which cost me much energy to find, but wired.
Thanks!
One Way To Solve The Issue:
When selecting "Generate documentations with Roxygen", Don't check "NAMESPACE file" option.
You're mixing up two things (which are easy to mix up, unfortunately):
First, the // [[Rcpp::export]] attribute is used for auto-generating wrapper functions in two files, RcppExports.cpp and RcppExports.R. A wrapper R function, CPPF, will be auto-generated by Rcpp::compileAttributes() here, and placed into R/RcppExports.R.
Second, roxygen comments can be used to manage the NAMESPACE, e.g. with the #export tag. Note that this is different from // [[Rcpp::export]]!
The auto-generated function is not automatically exported. The Rcpp.package.skeleton() will generate a NAMESPACE file that automatically exports all functions of a given name; ie, the exportPattern("^[[:alpha:]]+") entry. This is good enough for small packages; but as your package gets more complicated you will want more fine-grained control over your namespace. Or you can just adopt a convention where all internal, non-exported functions begin with a .. Either way, this mechanism is what allows the auto-generated function to be exported to your package namespace.
If you want to use roxygen to manage the NAMESPACE, you need to add roxygen comments to your C++ functions if you want them to be exported in the namespace. So you could modify your function as the following:
#include <Rcpp.h>
using namespace Rcpp;
//' #export
// [[Rcpp::export]]
int CPPF(int k){return ++k;}
Note that you might have to run roxygen2::upgradeRoxygen() to ensure that roxygen2 takes over the NAMESPACE, for new versions of roxygen2.
So if 2. does not work, file it as a (reproducible) bug report with the roxygen2 team.
I see no Rcpp issue; it is possible that something went wrong with the Imports: / NAMESPACE declaration. I see no Rcpp issue here (as 1. works fine).
FWIW I also use roxygen2 on some packages, and I too build them from time to time in RStudio.

Resources