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>
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 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
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.
This question already has answers here:
Call a function from c++ via environment Rcpp
(2 answers)
Closed 5 years ago.
How can I call an R function that does not belong to any R package into a C++ code?. I can show you what I mean through a very semplicistic example. Suppose I have an R file where I write
myRfunction <- function(x){
return(x+2)
}
and I want to use it in a generic c++ code. So, I write something like
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
using namespace Rcpp;
using namespace arma;
using namespace std;
// [[Rcpp::export]]
arma::vec myCppfunction(arma::vec y){
arma::sec results = myRfunction(y); /* Or whatever I have to do to call it! */
return results;
}
Can someone tell me how to do it? What is the general procedure? Thank you all.
Example. In R:
> timesTwoR <- function(x) 2*x
The cpp file:
#include <Rcpp.h>
using namespace Rcpp;
Function timesTwoFromR = Environment::global_env()["timesTwoR"];
// [[Rcpp::export]]
NumericVector timesTwo(NumericVector x) {
return timesTwoFromR(x);
}
Then, in R:
> timesTwo(42)
[1] 84
Alternatively, you can pass the R function as an argument to the C++ function, something like this:
// [[Rcpp::export]]
NumericVector call_r_fun(NumericVector x, Function f) {
return f(x) ;
}
I am reading Accelerated C++ Chapter 4: Organizing Programs and Data. I came across the following piece of code, which is saved to a file called median.cpp:
// median.cpp file contents
#include <algorithm>
#include <stdexcept>
#include <vector>
using std::domain_error;
using std::sort;
using std::vector;
// Compute the median of a vector<double>
double median(vector<double> vec)
{
// Code for what the median function does goes here
}
and then, later on on page 67., the authors discuss an include guard like below, which is saved to a file called median.h.
#ifndef GUARD_median_h
#define GUARD_median_h
// median.h - final version
#include<vector>
double median(std::vector<double>);
//
#endif
Are we supposed to "include" the median.h into median.cpp before compiling, like below?
// median.cpp file contents
#include "median.h"
#include <algorithm>
#include <stdexcept>
#include <vector>
using std::domain_error;
using std::sort;
using std::vector;
// Compute the median of a vector<double>
double median(vector<double> vec)
{
// Code for what the median function does goes here
}
I am asking this because, in section 4.3 where the authors discuss this topic, they have failed to mention how someone is supposed to make use of median.cpp and median.h for compilation.