I have a function in C that gets run from R via .Call and the boolean parameter always gets evaluated as true. Here's a minimal reproducible example:
library(inline)
dummy <- cfunction(signature(x = "bool"),
body = '
int val = x?0:1;
SEXP fake = allocVector(LGLSXP, 5);
SEXP ans = allocVector(LGLSXP, val);
if (val== 1) {
return fake;
}
return ans;
')
dummy(FALSE)
dummy(TRUE)
Both of these function calls return logical(0)
That doesn't sound right, but I also do not think your code goes about this in the right way. In the still-small, still-fairly new package tidyCpp I am collecting a few convenience definitions. One of its examples is basically exactly your problem:
#include <tidyCpp>
// We use Rcpp here because it has cppFunction() and sourceCpp().
// We do not use any Rcpp headers.
// [[Rcpp::depends(tidyCpp)]]
// [[Rcpp::export]]
bool isItLogical(SEXP x) {
return R::isLogical(x);
}
/*** R
isItLogical(TRUE)
isItLogical(FALSE)
isItLogical(42)
*/
When I sourceCpp() this (using Rcpp just for the convenience of building, no real Rcpp code here) I see
> Rcpp::sourceCpp("~/git/tidycpp/inst/snippets/defineExamples.cpp")
>
isItLogical(TRUE)
[1] TRUE
>
isItLogical(FALSE)
[1] TRUE
>
isItLogical(42)
[1] FALSE
>
If we change it from isLogical (answering: is the incoming variable a boolean or not) to asLogical to return the boolean value instead it becomes
> Rcpp::sourceCpp("~/git/stackoverflow/66575428/answer.cpp")
>
asLogical(TRUE)
[1] TRUE
>
asLogical(FALSE)
[1] FALSE
>
asLogical(42) # not zero so ...
[1] TRUE
>
New function below.
#include <tidyCpp>
// We use Rcpp here because it has cppFunction() and sourceCpp().
// We do not use any Rcpp headers.
// [[Rcpp::depends(tidyCpp)]]
// [[Rcpp::export]]
bool asLogical(SEXP x) {
return R::asLogical(x);
}
/*** R
asLogical(TRUE)
asLogical(FALSE)
asLogical(42) # not zero so ...
*/
Obviously, you do not have to use tidyCpp and can just look at its sources to pick the respective C functions of the R API, but I find the naming conventions there a little inconsistent hence this small packages as a little shim around it...
Use asLogical to convert function arguments (which are type SEXP, never bool) to bool:
SEXP dummy(SEXP x) {
int val = asLogical(x);
if (val) {
return allocVector(LGLSXP, 5);
}
return ScalarLogical(0);
}
(though I tend to agree with Dirk that Rcpp is almost always the way to go, unless is a peculiar aversion to it, especially as a first step from R to using compiled code with R).
Related
Suppose I have the following function:
List foo(List x)
{
x.attr("class") = "myOwnClass";
return(x);
}
I whant to override R summary method for foo function output. However the following R-style approach does not work:
List summary.myOwnClass(List x)
{
return(x)
}
During compilation I have a error which says that "expected initializer before '.' token".
Please help me to understand how to implement summary function override within Rcpp framework for my customly defined class.
Will be very greatfull for help!
I feel like this is likely a duplicate, but my initial search didn't pull one up. I add a quick answer for now, but if I later find one I'll delete this answer and propose a duplicate.
The way to solve this issue is to use the export tag to specify the function's R side name as summary.myOwnClass while using something else for the C++ side name; you can't have dots in the middle of a C++ function name (think about, e.g., how member functions are called -- it would be unworkable). So, we do the following
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
List foo(List x)
{
x.attr("class") = "myOwnClass";
return(x);
}
// [[Rcpp::export(summary.myOwnClass)]]
List summary(List x)
{
return(x);
}
/*** R
l <- foo(1:3)
summary(l)
*/
Then we get the output we expect
> l <- foo(1:3)
> summary(l)
[[1]]
[1] 1
[[2]]
[1] 2
[[3]]
[1] 3
attr(,"class")
[1] "myOwnClass"
In R the possibility exists to have a function that creates another function, e.g.
create_ax2 <- function(a) {
ax2 <- function(x) {
y <- a * x^2
return(y)
}
return(ax2)
}
The result of which is
> fun <- create_ax2(3)
> fun(1)
[1] 3
> fun(2)
[1] 12
> fun(2.5)
[1] 18.75
I have such a complicated create function in R which take a couple of arguments, sets some of the constants used in the returned function, does some intermediary computations etc... But the result is a function that is way too slow. Hence I tried to translate the code to C++ to use it with Rcpp. However, I can't figure out a way to construct a function inside a C++ function and return it to be used in R.
This is what I have so far:
Rcpp::Function createax2Rcpp(int a) {
double ax2(double x) {
return(a * pow(x, 2));
};
return (ax2);
}
This gives me the error 'function definition is not allowed here', I am stuck about how to create the function.
EDIT: The question RcppArmadillo pass user-defined function comes close, but as far as I can tell, it only provides a way to pass a C++ function to R. It does not provide a way to initialise some values in the C++ function before it is passed to R.
Ok, as far as I understand, you want a function returning function with a closure, a.k.a. " the function defined in the closure 'remembers' the environment in which it was created."
In C++11 and up it is quite possible to define such function, along the lines
std::function<double(double)> createax2Rcpp(int a) {
auto ax2 = [a](double x) { return(double(a) * pow(x, 2)); };
return ax2;
}
What happens, the anonymous class and object with overloaded operator() will be created, it will capture the closure and moved out of the creator function. Return will be captured into instance of std::function with type erasure etc.
But! C/C++ function in R requires to be of a certain type, which is narrower (as an opposite to wider, you could capture narrow objects into wide one, but not vice versa).
Thus, I don't know how to make from std::function a proper R function, looks like it is impossible.
Perhaps, emulation of the closure like below might help
static int __a;
double ax2(double x) {
return(__a * pow(x, 2));
}
Rcpp::Function createax2Rcpp(int a) {
__a = a;
return (ax2);
}
I am trying to write a C++/Rcpp function that has an optional argument whos default needs to be a vector of length 1 with a value of 0. The following does not compile properly:
cppFunction("std::vector<int> test(std::vector<int> out = {0}) {
return out;
}")
I get the following error:
Error in cppFunction("std::vector test(std::vector out =
{1}) {\n return out;\n}") : No function definition found In
addition: Warning messages: 1: No function found for Rcpp::export
attribute at fileee5f629605d7.cpp:5 2: In sourceCpp(code = code, env
= env, rebuild = rebuild, showOutput = showOutput, : No Rcpp::export attributes or RCPP_MODULE declarations found in source
What is the right way to do this?
This answer was posted on the Rcpp issue tracker. This is the desired result that I wanted just not with std::vector.
cppFunction("IntegerVector test(IntegerVector out = IntegerVector::create(0)) {
return out;
}")
You could wrap the underlying C++ function in an R function that uses a default value:
#include <Rcpp.h>
#include <vector>
// [[Rcpp::plugins(cpp11)]]
// [[Rcpp::export]]
std::vector<int> cpp_test(const std::vector<int>& x)
{
return x;
}
/*** R
test <- function(X = c(0L))
{
cpp_test(X)
}
test()
test(c(1:5))
*/
which gives you
> Rcpp::sourceCpp('~/RcppFiles/cpp_test.cpp')
> test()
[1] 0
> test(c(1:5))
[1] 1 2 3 4 5
Currently the Rcpp package didn't support the exporting the default values. There are several packages to improve this (including Rcpp11), thought, I have a solution on Rcpp with RCPP_MODULES:
library("Rcpp")
cppFunction(plugins=c("cpp11"),'NumericVector test(std::vector<int> out) {
return wrap(out);
}
RCPP_MODULE(mod) {
function("test",&test,List::create( _["out"] = std::vector<int>({0})), "Simple description");
}', verbose=TRUE,rebuild=TRUE)
I change the return type, thought, it work even if you return std::vector<int>.
So, how this works: it just creates a documentation entry with the default value, third argument for RCPP_MODULES.
With just {0} my R crashes, so, it's necessary for me to put std::vector explicitly.
I've just finished writing a new version of the ABCoptim package using Rcpp. With around 30x speed ups, I'm very happy with the new version's performance (vs old version), but I'm still having some concerns on if I have space to improve performance without modifying too much the code.
Within the main function of ABCoptim (written in C++) I'm passing around a Rcpp::List object containing "bees positions" (NumericMatrix) and some NumericVectors with important information for the algorithm itself. My question is, when I'm passing a Rcpp::List object around other functions, e.g.
#include <Rcpp.h>
using namespace Rcpp;
List ABCinit([some input]){[some code here]};
void ABCfun2(List x){[some code here]};
void ABCfun3(List x){[some code here]};
List ABCmain([some input])
{
List x = ABCinit([some input]);
while ([some statement])
{
ABCfun2(x);
ABCfun3(x);
}
...
return List::create(x["results"]);
}
What does Rcpp does within the while loop? Does the x object is passed by reference or by deep copy to the functions ABCfun2 and ABCfun3? I've seen the usage of 'const List&x', which tells me that I can pass Rcpp objects using pointers, but the thing is that I need this list to be variable (and no constant), is there anyway to improve this? I'm afraid that iterative copy of this x List can be slowing down my code.
PS: I'm still new to C++, furthermore I'm using Rcpp to learn C++.
There is no deep copy in Rcpp unless you ask for it with clone. When you pass by value, you are making a new List object but it uses the same underlying R object.
So the different is small between pass by value and pass by reference.
However, when you pass by value, you have to pay the price for protecting the underlying object one more time. It might incur extra cost as for this Rcpp relies on the recursive not very efficient R_PreserveObject.
My guideline would be to pass by reference whenever possible so that you don't pay extra protecting price. If you know that ABCfun2 won't change the object, I'd advise passing by reference to const : ABCfun2( const List& ). If you are going to make changes to the List, then I'd recommend using ABCfun2( List& ).
Consider this code:
#include <Rcpp.h>
using namespace Rcpp ;
#define DBG(MSG,X) Rprintf("%20s SEXP=<%p>. List=%p\n", MSG, (SEXP)X, &X ) ;
void fun_copy( List x, const char* idx ){
x[idx] = "foo" ;
DBG( "in fun_copy: ", x) ;
}
void fun_ref( List& x, const char* idx ){
x[idx] = "bar" ;
DBG( "in fun_ref: ", x) ;
}
// [[Rcpp::export]]
void test_copy(){
// create a list of 3 components
List data = List::create( _["a"] = 1, _["b"] = 2 ) ;
DBG( "initial: ", data) ;
fun_copy( data, "a") ;
DBG( "\nafter fun_copy (1): ", data) ;
// alter the 1st component of ths list, passed by value
fun_copy( data, "d") ;
DBG( "\nafter fun_copy (2): ", data) ;
}
// [[Rcpp::export]]
void test_ref(){
// create a list of 3 components
List data = List::create( _["a"] = 1, _["b"] = 2 ) ;
DBG( "initial: ", data) ;
fun_ref( data, "a") ;
DBG( "\nafter fun_ref (1): ", data) ;
// alter the 1st component of ths list, passed by value
fun_ref( data, "d") ;
DBG( "\nafter fun_ref (2): ", data) ;
}
All I'm doing is pass a list to a function, update it and print some information about the pointer to the underlying R object and the pointer to the List object ( this ) .
Here are the results of what happens when I call test_copy and test_ref:
> test_copy()
initial: SEXP=<0x7ff97c26c278>. List=0x7fff5b909fd0
in fun_copy: SEXP=<0x7ff97c26c278>. List=0x7fff5b909f30
after fun_copy (1): SEXP=<0x7ff97c26c278>. List=0x7fff5b909fd0
$a
[1] "foo"
$b
[1] 2
in fun_copy: SEXP=<0x7ff97b2b3ed8>. List=0x7fff5b909f20
after fun_copy (2): SEXP=<0x7ff97c26c278>. List=0x7fff5b909fd0
$a
[1] "foo"
$b
[1] 2
We start with an existing list associated with an R object.
initial: SEXP=<0x7fda4926d278>. List=0x7fff5bb5efd0
We pass it by value to fun_copy so we get a new List but using the same underlying R object:
in fun_copy: SEXP=<0x7fda4926d278>. List=0x7fff5bb5ef30
We exit of fun_copy. same underlying R object again, and back to our original List :
after fun_copy (1): SEXP=<0x7fda4926d278>. List=0x7fff5bb5efd0
Now we call again fun_copy but this time updating a component that was not on the list: x["d"]="foo".
in fun_copy: SEXP=<0x7fda48989120>. List=0x7fff5bb5ef20
List had no choice but to create itself a new underlying R object, but this object is only underlying to the local List. Therefore when we get out of get_copy, we are back to our original List with its original underlying SEXP.
after fun_copy (2): SEXP=<0x7fda4926d278>. List=0x7fff5bb5efd0
The key thing here is that the first time "a" was already on the list, so we updated the data directly. Because the local object to fun_copy and the outer object from test_copy share the same underlying R object, modifications inside fun_copy was propagated.
The second time, fun_copy grows its local List object, associating it with a brand new SEXP which does not propagate to the outer function.
Now consider what happens when you pass by reference :
> test_ref()
initial: SEXP=<0x7ff97c0e0f80>. List=0x7fff5b909fd0
in fun_ref: SEXP=<0x7ff97c0e0f80>. List=0x7fff5b909fd0
after fun_ref(1): SEXP=<0x7ff97c0e0f80>. List=0x7fff5b909fd0
$a
[1] "bar"
$b
[1] 2
in fun_ref: SEXP=<0x7ff97b5254c8>. List=0x7fff5b909fd0
after fun_ref(2): SEXP=<0x7ff97b5254c8>. List=0x7fff5b909fd0
$a
[1] "bar"
$b
[1] 2
$d
[1] "bar"
There is only one List object 0x7fff5b909fd0. When we have to get a new SEXP in the second call, it correctly gets propagated to the outer level.
To me, the behavior you get when passing by references is much easier to reason with.
Briefly:
void ABCfun(List x) passes by value but then again List is an Rcpp object wrapping a SEXP which is a pointer -- so the cost here is less than what a C++ programmer would suspect and it is in fact lightweight. (But as Romain rightly points out, there is cost in an extra protection layer.)
void ABCfun(const List x) promises not to change x, but again because it is a pointer...
void ABCfun(const List & x) looks most normal to a C++ programmer and is supported in Rcpp since last year.
Ipso facto, in the Rcpp context all three are about the same. But you should think along the lines of best C++ practice and prefer 3. as one day you may use a std::list<....> instead in which case the const reference clearly is preferable (Scott Meyers has an entire post about this in Effective C++ (or maybe in the companion More Effective C++).
But the most important lesson is that you should not just believe what people tell you on the internet, but rather measure and profile whenever possible.
I'm new to Rcpp so figured i'd answer #Dirk's request for a measurement of the cost of the two passing styles (copy and reference) ...
There is surprisingly little difference -- between the two approaches.
I get the below:
microbenchmark(test_copy(), test_ref(), times = 1e6)
Unit: microseconds
expr min lq mean median uq max neval cld
test_copy() 5.102 5.566 7.518406 6.030 6.494 106615.653 1e+06 a
test_ref() 4.639 5.566 7.262655 6.029 6.494 5794.319 1e+06 a
I used a cut-down version of #Roman's code: removing the DBG calls.
#include <Rcpp.h>
using namespace Rcpp;
void fun_copy( List x, const char* idx){
x[idx] = "foo";
}
void fun_ref( List& x, const char* idx){
x[idx] = "bar";
}
// [[Rcpp::export]]
List test_copy(){
// create a list of 3 components
List data = List::create( _["a"] = 1, _["b"] = 2);
// alter the 1st component of the list, passed by value
fun_copy( data, "a");
// add a 3rd component to the list
fun_copy( data, "d");
return(data);
}
// [[Rcpp::export]]
List test_ref(){
// create a list of 3 components
List data = List::create( _["a"] = 1, _["b"] = 2);
// alter the 1st component of the list, passed by reference
fun_ref( data, "a");
// add a 3rd component to the list
fun_ref( data, "d");
return(data);
}
/*** R
# benchmark copy v. ref functions
require(microbenchmark)
microbenchmark(test_copy(), test_ref(), times = 1e6)
*/
I have a c++ class myClass which has a method foo(int x=0) and it has a parameter x with default value = 0. The c++ class could be exported to R by
RCPP_MODULE(my_module) {
class_< myClass >( "myClass" )
.constructor()
.method( "foo", &myClass::foo )
;
}
However, in R, I am not able to call myClass$foo without specifying the value of x.
I have to specify the value of x regardless the default value.
So my question is how to export Rcpp class method with default arguments. I tried to search it over the internet. The closest thing that I found was
using namespace Rcpp;
double norm( double x, double y ) { return sqrt( x*x + y*y );
}
RCPP_MODULE(mod_formals2) {
function("norm", &norm,
}
But it doesn't work in my case.
I had the same problem recently. After looking at the source file of rcpp handling the classes (~/R/x86_64-pc-linux-gnu-library/3.2/Rcpp/include/Rcpp/module/class.h in my setup) I don't think that it is currently possible.
The best workaround I came up with was to create a wrapper in R to handle the default arguments.
Here is a full example demonstrating how to do it. I defined a simple function that accepts 3 arguments and outputs their sum. The second and third arguments are optional and set by default to 10 and 100.
mwe.cpp
#include <Rcpp.h>
class MWE {
public:
int sum_them(int mandatory_arg,
int optional_arg1,
int optional_arg2)
{
return (mandatory_arg+optional_arg1+optional_arg2);
}
};
RCPP_MODULE(mod_mwe) {
Rcpp::class_<MWE>( "MWE" )
.constructor()
.method("sum_them", &MWE::sum_them)
;
}
mwe.R
require('Rcpp')
# source the C++ code
sourceCpp('mwe.cpp')
# create an instance of the class:
my_mwe = new(MWE)
# assign a wrapper with default arguments to the instance:
assign('sum_them_wrapper',
function(mandatory_arg,
optional_arg1=10,
optional_arg2=100) {
return(my_mwe$sum_them(mandatory_arg, optional_arg1, optional_arg2))
},
envir = my_mwe
)
This outputs the expected result:
> my_mwe$sum_them_wrapper(3, optional_arg2=500)
[1] 513