I want to disable bound checks when accessing to matrix elements in RcppArmadillo.
The documentations of Armadillo says
Armadillo can be configured via editing the file
include/armadillo_bits/config.hpp. Specific functionality can be
enabled or disabled by uncommenting or commenting out a particular
#define, listed below.
But in the context of an R package, how can I activate this directive?
I have tried to create a config.h file with
#ifndef CONFIG_LOADED
#define CONFIG_LOADED
#define ARMA_NO_DEBUG
#endif
and then including it in every .cpp file of my /src folder, but I'm not sure whether it works properly or whether there is some other way other than adding a #include "config.h"in each .cpp file.
Currently I have one .cpp (the one that contains the main algorithm) that start with:
#include "configs.h"
#include <RcppArmadillo.h>
using namespace Rcpp;
using namespace arma;
// [[Rcpp::export]]
SEXP sample_gibbs_cpp(const arma::vec& v_n, const arma::mat& W,
arma::vec h_n, double alpha = 1, double beta = 1, int iter=100,
double burnin = 0.5){
... code ...
}
And then others that are just
#include <RcppArmadillo.h>
using namespace Rcpp;
using namespace arma;
... code ...
My DESCRIPTION file:
Package: mypackage
Title: What the Package Does (one line, title case)
Version: 0.0.0.9000
Authors#R: person("First", "Last", email = "first.last#example.com", role = c("aut", "cre"))
Description: What the package does (one paragraph).
Depends:
R (>= 3.2.3)
License: What license is it under?
Encoding: UTF-8
LazyData: true
RoxygenNote: 5.0.1
Imports:
ggplot2,
dplyr,
tidyr,
rstan
LinkingTo: Rcpp, RcppArmadillo, RcppEigen
SystemRequirements: C++11
And I compile my package with:
devtools::load_all()
Order matters here. This #define statement must be included before the inclusion of #include<RcppArmadillo.h>
An example:
custom_config.h
#ifndef CONFIG_LOADED
#define CONFIG_LOADED
#define ARMA_NO_DEBUG
#endif
example_compiled_file.cpp
#include "custom_config.h"
#include <RcppArmadillo.h>
// [[Rcpp::export]]
void test_pkg(const arma::vec& x) {
// Should not trigger error bound checking with debug flag on.
double my_val_protected = x(0);
// Never triggers error bound checking
double my_val = x.at(0);
}
Note: As this is a package, the use of // [[Rcpp::depends(RcppArmadillo)]] is not required. Instead, you must specify RcppArmadillo and Rcpp in the LinkingTo: field of the DESCRIPTION file as well as including Rcpp in the Imports: field. You will have to minimally import from Rcpp a function (preferably: evalCpp).
e.g. DESCRIPTION must have:
Imports: Rcpp (>= 0.12.15)
LinkingTo: Rcpp, RcppArmadillo
Related
When compiling my .cpp file with Rcpp in R, this error message comes :
undefined reference to `boost::system::generic_category()'
But when I remove the // [[Rcpp::plugins(cpp11)]] line, there isn't any error anymore. Why?
Here is my minimal reproducible example.
// include Rcpp, it takes care of most other headers you need
#include <Rcpp.h>
#include <boost/array.hpp>
// include Boost's odeint
#include <boost/numeric/odeint.hpp>
#include <boost/numeric/odeint/integrate/integrate_adaptive.hpp>
#include <boost/filesystem/fstream.hpp>
#include <functional>
// tell R you need Boost
// [[Rcpp::depends(BH)]]
// [[Rcpp::plugins(cpp11)]]
using namespace Rcpp;
using namespace std;
using namespace boost::numeric::odeint;
typedef boost::array< double ,130 > state_type;
// [[Rcpp::export]]
void my_fun22(Rcpp::NumericVector &x, const double t,const Rcpp::NumericVector theta){
Function f("mod_cpp");
x=f(_["t"]=t,_["x"]=x,_["p1"]=theta);
}
Yet another elementary issue: Boost System (generally) requires linking which is a whole different ball game than just pointing to Boost headers via the BH package. And the very standard error message undefined reference comes from the linker / failed attempts to locate a symbol.
We discuss the use of linking to Boost libraries in some posts on the Rcpp Gallery, but the short of it is that there is no portable way to provide linking to Boost libraries across the OSs used by R.
I'm writing my functions in C++ to use them in R. Since I don't want to include all the functions inside the same file, I want to call them. I'll give you a simple example of the three files I'm using:
function.h:
#ifndef FUNCTION_H
#define FUNCTION_H
#include <RcppArmadillo.h>
arma::vec quadraticsum(arma::vec x);
#endif
function.cpp:
#include <RcppArmadillo.h>
#include <function.h>
// [[Rcpp::depends(RcppArmadillo)]]
using namespace Rcpp;
using namespace arma;
using namespace std;
// [[Rcpp::export]]
arma::vec quadraticsum(arma::vec x){
arma::vec results = sum(pow(x,2));
return results;
}
main.cpp:
#include <RcppArmadillo.h>
#include <function.h>
// [[Rcpp::depends(RcppArmadillo)]]
using namespace Rcpp;
using namespace arma;
using namespace std;
// [[Rcpp::export]]
arma::vec sum2(arma::vec x){
arma::vec results = quadraticsum(x)+2;
return results;
}
I'm working with Rstudio and when I write the code in the main.cpp file it recognizes the function quadraticsum, and so everything seems to be fine. However, when I compile using the command sourceCpp("~/main.cpp"), I got this error:
Error in dyn.load("/private/var/folders/46/1tz_54_n3glfmgftvqsspwrr0000gn/T/Rtmpdnk9hf/sourceCpp-x86_64-apple-darwin13.4.0-0.12.12/sourcecpp_237a88636e6/sourceCpp_2.so") :
unable to load shared object '/private/var/folders/46/1tz_54_n3glfmgftvqsspwrr0000gn/T/Rtmpdnk9hf/sourceCpp-x86_64-apple-darwin13.4.0-0.12.12/sourcecpp_237a88636e6/sourceCpp_2.so':
dlopen(/private/var/folders/46/1tz_54_n3glfmgftvqsspwrr0000gn/T/Rtmpdnk9hf/sourceCpp-x86_64-apple-darwin13.4.0-0.12.12/sourcecpp_237a88636e6/sourceCpp_2.so, 6): Symbol not found: __Z12quadraticsumN4arma3ColIdEE
Referenced from: /private/var/folders/46/1tz_54_n3glfmgftvqsspwrr0000gn/T/Rtmpdnk9hf/sourceCpp-x86_64-apple-darwin13.4.0-0.12.12/sourcecpp_237a88636e6/sourceCpp_2.so
Expected in: flat namespace
in /private/var/folders/46/1tz_54_n3glfmgftvqsspwrr0000gn/T/Rtmpdnk9hf/sourceCpp-x86_64-apple-darwin13.4.0-0.12.12/sourcecpp_237a88636e6/sourceCpp_2.so
Have you seen this problem before? I'm using macOS 10.12.5. Thank you all.
sourceCpp only allows a single source file.
If you want to use multiple source files, you will need to build a full package.
The error appears because the second source file has not been compiled or linked into the shared library. As a result, no function implementation exists.
You could also make the implementations static or inline and then place them in a header, of you want to avoid a full package. if
I discovered that writing #include "function.h" instead of #include <function.h> it compiles correctly. I just changed it. Thank you all.
I am writing a Rcpp code as below:
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::depends(BH)]]
// [[Rcpp::plugins(cpp11)]]
#include <RcppArmadillo.h>
#include <boost/random.hpp>
#include <boost/random/uniform_real_distribution.hpp>
#include <math.h>
using namespace Rcpp;
using namespace std;
// [[Rcpp::export]]
double ks(const double k, const double alpha, const double mag, const double M0){
double ksres;
ksres= k* std::exp ( alpha*(mag-M0) );
return(ksres);
}
.
But it shows that "Call to 'exp' is ambiguous". Why do I get this message and how will I solve it?
While I get in sessionInfo():
R version 3.2.4 (2016-03-10)
Platform: x86_64-apple-darwin13.4.0 (64-bit)
Running under: OS X 10.12.6 (unknown)
locale:
[1] en_GB.UTF-8/en_GB.UTF-8/en_GB.UTF-8/C/en_GB.UTF-8/en_GB.UTF-8
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] Rcpp_0.12.4
loaded via a namespace (and not attached):
[1] colorspace_1.2-6 scales_0.4.0 plyr_1.8.3 tools_3.2.4 inline_0.3.14 gtable_0.2.0 rstan_2.9.0-3
[8] gridExtra_2.2.1 ggplot2_2.1.0 grid_3.2.4 munsell_0.4.3 stats4_3.2.4
I suggest this to be closed or deleted by OP. The question simply exhibits some allowed-but-not-recommended C++ usage:
extra headers included: the math headers are already brought in by Rcpp (which is brought in by RcppArmadillo)
you never ever need both cmath and math.h, and as stated here you do not need either
we generally recommend against flattening all namespaces unconditionally
With this, your code looks like this (still containing a call for C++11 which is not used, but does no harm):
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::depends(BH)]]
// [[Rcpp::plugins(cpp11)]]
#include <RcppArmadillo.h>
#include <boost/random.hpp>
#include <boost/random/uniform_real_distribution.hpp>
// [[Rcpp::export]]
double ks(const double k, const double alpha, const double mag, const double M0){
double ksres;
ksres= k* std::exp ( alpha*(mag-M0) );
return(ksres);
}
/*** R
ks(1.0, 2.0, 3.0, 4.0)
*/
This compiles without any warning whatsoever on my box (with stringent compiler warnings turned on, output not shown here) and runs as expected too:
R> Rcpp::sourceCpp("/tmp/soQ.cpp")
R> ks(1.0, 2.0, 3.0, 4.0)
[1] 0.135335
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,
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.
I'm building an R-package for hydrological modelling using the C++ boost library.
The package requires:
boost::math::gamma_distribution
boost::math::cdf
boost::math::isnan
Would the BH R-package work in my case?
It sure should. Boost math is a header only library only; so we can test the boost tgamma function using Dirks Rcpp Gallery post as a model
Something along the lines of:
// Use brandnew CRAN package BH for Boost headers
// [[Rcpp::depends(BH)]]
#include <Rcpp.h>
#include <boost/foreach.hpp>
#include <boost/math/special_functions/gamma.hpp>
#define foreach BOOST_FOREACH
using namespace boost::math;
//[[Rcpp::export]]
Rcpp::NumericVector boost_gamma( Rcpp::NumericVector x ) {
foreach( double& elem, x ) {
elem = boost::math::tgamma(elem);
};
return x;
}
and then a quick check:
> identical( boost_gamma(0:10 + 1), factorial(0:10) )
[1] TRUE
Not that the test means too much, except to say that the headers are easily included and usable.
Take a look at the BigMemory Description file's Depends and LinkingTo and notice the BH there.
Lastly, you can keep up to date on the changes to what the BH package is setup for by looking at it's News page.
Have fun!