when using Rcpp, I want to use function abs, I just write Rcpp::abs(-1), but always an error:
no matching function for call to abs
Actually when I write Rcpp:ab, there are some hint that there exists Rcpp::abs(). I have tried some other function Rcpp::NumericVector, it works. I know I can use std::abs(-1), I just wonder why Rcpp::abs(-1) do not work, my system is windows, and I install Rtools.
Rcpp::abs() requires an Rcpp object, e.g. *Vector and *Matrix.
Unfortunately, -1 is of a primitive type, e.g. not an Rcpp object.
So, the following would work:
#include <Rcpp.h>
// [[Rcpp::export]]
void show_rcpp_abs() {
Rcpp::NumericVector A = NumericVector::create(-1);
Rcpp::Rcout << "A" << Rcpp::abs(A) << std::endl;
double B = std::abs(-1.0);
Rcpp::Rcout << "B" << B << std::endl;
}
Related
New to CPP and RCPP
I am putting together an R package with RCPP.
Here are my steps:
Transfer to directory with package.
Run compileAttributes(pkgdir = ".",verbose=TRUE)
Then run build and install from devtools.
I want one of my CPP functions to print a message whenever it is invoked.
So i added :
Rcpp::Rcout << "Hello World!" << std::endl;
I then went through steps 1 to 3 above. But no cigar. Not even a cigarillo.
Ideally, I want it to print out an integer value i, somthing like
Sample code.
Rcpp::Rcout << i << std::endl;
SO far, it compiles and the function runs - but no printout of the dear variable. HELP! An example of my function is below. I suspect there is some standard way to either pass the values to R or to simply print from CPP.
# include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::plugins(cpp11)]]
using namespace Rcpp ;
arma::mat sillyme (arma::mat FE) {
arma::mat FEE = FE ;
Rcpp::Rcout << "Hello World!" << std::endl;
Rcpp::Rcout << FE.n_rows << std::endl;
return(FEE) ;
}
On my system (Ubuntu 20.04, R 4.0.0), this works just as expected (after adding a // [[Rcpp::export]] attribute to make sure the function is callable from R):
sillyme(diag(2))
# Hello World!
# 2
# [,1] [,2]
# [1,] 1 0
# [2,] 0 1
Example
I have an Rcpp function where I would like to call boost::posix_time::time_from_string().
I've taken the example code from the boost documentation and translated it to a c++ function using Rcpp
library(Rcpp)
cppFunction(
includes = '
#include <boost/date_time/posix_time/posix_time.hpp>
',
code = '
void time_test() {
std::string t = "2002-01-20 23:59:59.000";
boost::posix_time::ptime pt(boost::posix_time::time_from_string(t));
Rcpp::Rcout << "time from string: " << pt << std::endl;
}
',
depends = "BH"
)
However, this doesn't compile.
I've seen a few comments saying you need to link to -lboost_date_time, such as this line in Dirk's RcppBDT library
// The next function uses the non-stream-based parsing in Boost Date_Time
// and requires _linking_ with -lboost_date_time which makes the (otherwise
// header-only) build more complicate
// // [ [ Rcpp::export ] ]
// Rcpp::DatetimeVector charToPOSIXctNS(Rcpp::CharacterVector sv) {
// ... code omitted ...
// }
Question
How do you provide the appropriate links to lboost_date_time, other than including the posix_time.hpp header, so that one can use time_from_string()?
Extra Info
It's possible to use other functions from the boost/date_time library, as demonstrated by this function, so what makes time_from_string() different?
cppFunction(
includes = '
#include <boost/date_time/posix_time/posix_time.hpp>
',
code = '
void time_test() {
Rcpp::Datetime dt("2002-01-20 23:59:59.000");
boost::posix_time::hours h( dt.getHours() );
boost::posix_time::minutes m( dt.getMinutes() );
boost::posix_time::seconds s( dt.getSeconds() );
Rcpp::Rcout << h << std::endl;
Rcpp::Rcout << m << std::endl;
Rcpp::Rcout << s << std::endl;
}
',
depends = "BH"
)
time_test()
# 12:00:00
# 00:59:00
# 00:00:59
As you already found out, you need to link with boost at the system level. The BH package is not sufficient. So first you have to install the required boost library. On Debian (dervied) Linux systems this can be done via
sudo apt-get install libboost-date-time-dev
Then you need to tell R to add -I/path/to/boost/headers and -L/path/to/boost/libraries -lboost_date_time to the compiler flags. You can do this by setting appropriate environment variables:
library(Rcpp)
Sys.setenv(PKG_LIBS="-L/usr/lib -lboost_date_time", PKG_CPPFLAGS="-I/usr/include")
cppFunction(
includes = '
#include <boost/date_time/posix_time/posix_time.hpp>
',
code = '
void time_test() {
std::string t = "2002-01-20 23:59:59.000";
boost::posix_time::ptime pt(boost::posix_time::time_from_string(t));
Rcpp::Rcout << "time from string: " << pt << std::endl;
}
'
)
Notes:
One could also define a Rcpp plugin for this.
In my case -I... and -L... are unnecessary, since the library is installed in a standard location. One does need these flags in other cases, though.
I'm writing a package with some functions calling RcppArmadillo::sample from RcppArmadillo.
However I met the following error when compiling.
In file included from Citrus.cpp:2:
./R/x86_64-unknown-linux-gnu-library/3.0/RcppArmadillo/include/RcppArmadilloExtensions/sample.h: In function ‘T Rcpp::RcppArmadillo::sample(const T&, int, bool, Rcpp::NumericVector) [with T = arma::subview_col]’:
Citrus.cpp:241: instantiated from here
./R/x86_64-unknown-linux-gnu-library/3.0/RcppArmadillo/include/RcppArmadilloExtensions/sample.h:45: error: ‘const struct arma::subview_col’ has no member named ‘size’
./R/x86_64-unknown-linux-gnu-library/3.0/RcppArmadillo/include/RcppArmadilloExtensions/sample.h:48: error: no matching function for call to ‘arma::subview_col::subview_col(const int&)’
./R/x86_64-unknown-linux-gnu-library/3.0/RcppArmadillo/include/armadillo_bits/subview_bones.hpp:236: note: candidates are: arma::subview_col::subview_col() [with eT = double]
./R/x86_64-unknown-linux-gnu-library/3.0/RcppArmadillo/include/armadillo_bits/subview_meat.hpp:2608: note: arma::subview_col::subview_col(const arma::Mat&, arma::uword, arma::uword, arma::uword) [with eT = double]
./R/x86_64-unknown-linux-gnu-library/3.0/RcppArmadillo/include/armadillo_bits/subview_meat.hpp:2597: note: arma::subview_col::subview_col(const arma::Mat&, arma::uword) [with eT = double]
./R/x86_64-unknown-linux-gnu library/3.0/RcppArmadillo/include/armadillo_bits/forward_bones.hpp:29: note: arma::subview_col::subview_col(const arma::subview_col&)
make: *** [Citrus.o] Error 1
The RcppArmadillo I'm using is 0.7.700.0.0.
The same error appeared on both linux and OSX. When compiling using Rstudio, the error message as follows:
no member named 'size' in 'arma::subview_col<double>'.
no matching constructor for initialization of 'arma::subview_col<double>'
I used RcppArmadillo::sample in my previous work a lot. It suddenly doesn't work. I appreciate any help.
This feature works on pre-subset data in either arma::vec or NumericVector Always has and always will. Do not use this with an intermediary vector obtained from a subset operation (e.g. .col(), .cols(), or .submat()).
The issue you are running into is you've decided to subset the data within the call to sample. (You've omitted code to diagnose this part, so I'm speculating here.) Since sample() needs to work with both Rcpp and Armadillo data types there never was a call to Armadillo specific size member functions. Instead, the library opted to call the .size() member function of an STL container, which armadillo supported, since that was shared between both objects. However, armadillo limits where the member function was implemented to the "active" data structures and not temporaries. As a result, the .size() member function was not implemented for subview_col. So, we end up with the error of:
error: ‘const struct arma::subview_col’ has no member named ‘size’
To get around this limitation and save memory, use an advanced vec ctor that will reuse memory and, thus, avoiding the need for an intermediary arma::subview_col to be created.
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
#include <RcppArmadilloExtensions/sample.h>
// [[Rcpp::export]]
void adv_rnd(int nrow, int ncol, bool replace = true){
// Create a matrix of given dimensions
arma::mat X(nrow, ncol);
X.randn();
// Show state before randomization
Rcpp::Rcout << "Before Randomization:" << std::endl << X << std::endl;
// Randomize each column
for(int i = 0; i < ncol; ++i){
arma::vec Y(X.colptr(i), nrow, false, true);
X.col(i) = Rcpp::RcppArmadillo::sample(Y, nrow, replace);
}
// Show state after randomization
Rcpp::Rcout << "After Randomization:" << std::endl << X << std::endl;
}
Sample output:
> adv_rnd(3,3)
Before Randomization:
-0.7197 1.2590 -0.5898
0.0253 0.1493 -0.0685
-0.6074 1.3843 0.0400
After Randomization:
-0.7197 1.2590 0.0400
-0.6074 1.2590 -0.5898
-0.6074 0.1493 -0.0685
I implemented a Python-style dictionary for R, but did not find a good way to raise an error when a given key does not have a value in the dictionary. Calling stop is easy enough, but I would like to tell the user which key has not been found by printing the R object. Right now I have:
Rcpp::Rcout << "Key not found: ";
Rcpp::print(key); # <-- how can I get this on stderr?
Rcpp::stop("Key error!");
This prints the message to stdout, but I'd rather have it on stderr. Probably I'm just missing a function that Rcpp provides?
Here's a MWE:
library(Rcpp)
sourceCpp(code='
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
void test(SEXP key) {
Rcpp::print(key);
Rcpp::Rcerr << "This does not work: " << key << std::endl;
}
/*** R
test("x")
test(c(1,2,3))
*/
')
This works just fine:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
std::string test(std::string key) {
Rcpp::Rcerr << "Key not found: "<< key << std::endl;
Rcpp::stop("Key error!");
return key;
}
/*** R
test("x")
*/
Output:
Key not found: x
Error in eval(expr, envir, enclos) : Key error!
Edit:
OK, so you pass a SEXP that can be a single value or vector. I would suggest to cast that to a character vector:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
void test(SEXP key) {
CharacterVector key1 = as<CharacterVector>(key);
Rcpp::Rcerr << "This does not work: " << key1 << std::endl;
}
/*** R
test(c("x", "y"))
test(1:3)
*/
Output:
> Rcpp::sourceCpp('E:/temp/ttt.cpp')
> test(c("x", "y"))
This does not work: "x" "y"
> test(1:3)
This does not work: "1" "2" "3"
At the moment, it seems that this hack is the only way to go. It's not very efficient, as we go back from C++ to R to get the value as a nice string.
library(Rcpp)
sourceCpp(code='
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
void test(SEXP key, Function generate_error) {
std::string s = as<std::string>(generate_error(key));
stop(s);
}
/*** R
generate_error <- function(key) {
paste("Key not found:", capture.output(print(key)))
}
try( test("x", generate_error) )
try( test(c(1,2,3), generate_error) )
*/
')
Rcpp calls Rf_PrintValue internally. I've glanced at R source and it seems like this function is in turn implemented using printfs.
So, the problem is how to redirect external printf calls to stderr. Depending on your platform you have multiple options like dup/freopen/CreatePipe etc. Arguably, redirecting stdout back and forth is a hack.
New to Rcpp I am testing how to retrieve and use a nested list from R with a known structure without copying parts of the list again. The small code example (with embedded R code) seems to work (cout is used for debugging).
The list rL retrieved from R may be very big so I do not want to reallocate memory (copy parts of rL). Do the current code copy parts of rL?
Best Lars
#include <Rcpp.h>
#include <iostream>
using namespace Rcpp;
using namespace std;
// [[Rcpp::export]]
SEXP testing(const List rL) {
List L(rL);
SEXP sL2(L["L2"]);
List L2(sL2);
SEXP sStateGrpL2(L2["stateGroups"]);
List stateGrpL2(sStateGrpL2);
SEXP sStateAllocL2(L2["stateAlloc"]);
CharacterVector stateAllocL2(sStateAllocL2);
SEXP sActionGrpL2(L2["actionGroups"]);
List actionGrpL2(sActionGrpL2);
SEXP sActionAllocL2(L2["actionAlloc"]);
List actionAllocL2(sActionAllocL2);
vector<string> stateLabels;
vector<string> actionLabels;
CharacterVector actionNames;
for(int n2 = 0; n2< as<int>(L2["stages"]); n2++) {
stateLabels = as< vector<string> >(stateGrpL2[as<string>(stateAllocL2[n2])]);
int s2Size = stateLabels.size();
SEXP sAllocA(actionAllocL2[n2]);
List allocA(sAllocA);
actionNames = as<CharacterVector>(allocA[0]);
cout << "stage:" << n2 << " sN:" << as<string>(stateAllocL2[n2]) << "\n";
for (int s2=0; s2<s2Size; ++s2) {
cout << " s:" << stateLabels[s2] << " aN:" << actionNames[s2] << "\n";
actionLabels = as< vector<string> >(actionGrpL2[ as<string>(actionNames[s2]) ]);
int a2Size = actionLabels.size();
for (int a2=0; a2<a2Size; ++a2) {
cout << " a:" << actionLabels[a2] << "\n";
}
}
}
return wrap(0);
}
/*** R
L <- list( L2=list(stages=2,
stateGroups=list(s1Grp=c("a","b","c"),s2Grp=c("d","e")),
stateAlloc = c(rep("s1Grp",1),rep("s2Grp",1)),
actionGroups = list(a1Grp=c("terminate","keep"), a2Grp=c("finish")),
actionAlloc = list(list( rep("a1Grp",3) ),
list( c("a1Grp","a2Grp") )
)
)
)
testing(L)
*/
You write:
The list rL may be very big so I do not want to use new memory (copy
parts of rL). Is this the way to do it?
Pretty much (as far as I can tell from a glance at your code).
All exchange with R uses SEXP types where the P stands for pointer -- these are shallow proxy objects which will not be copied. It uses / reuses the R object memory.
So if you profile / memory-profile this it should behave similarly for N=10 and N=1e5. But the proof is in the pudding...
A few things :
The loop test n2< as<int>(L2["stages"]) is both hard to read and
inefficient as it is calculated at each iteration. You should
definitely do it just once.
All of your as< vector<string> > create deep copies and does not
take advantage of the R's string cache. Can't you use a
CharacterVector instead ?