Rcpp Class wrap and as - rcpp

I created a Rcpp - Package with a Module that contains the following class :
Update
C++ Part:
class A
{
public:
void concat( A & x)
{
....
}
}
With the Rcpp Module - Part
RCPP_MODULE(Foo){
using namespace Rcpp;
class_<A>("A")
.method("concat", &A::concat)
;
}
And the R - Part
x <- new(A)
y <- new(A)
The Problem
x$concat(y)
No known conversion from argument 1 'SEXP' to 'A'.
The problem i think is that there is no specialized wrap and as function.
For me it is not clear, do i need the create this template function for the class A ?
Do i need to create a Rcpp:Xptr ?

You can use RCPP_EXPOSED_CLASS(A) to generate all this stuff for you. See https://github.com/RcppCore/Rcpp/blob/master/inst/include/Rcpp/macros/module.h for the details.
#include <Rcpp.h>
using namespace Rcpp ;
RCPP_EXPOSED_CLASS(A)
class A{
public:
A(){}
void concat( A & x){
Rprintf( "hello\n") ;
}
} ;
RCPP_MODULE(Foo){
using namespace Rcpp;
class_<A>("A")
.default_constructor()
.method("concat", &A::concat)
;
}
Which gives:
> sourceCpp( "/tmp/mod.cpp" )
>
> a <- new(A)
> b <- new(A)
> a$concat(b)
hello

Related

Conversion of Rcpp::NumericMatrix to Eigen::MatrixXd

I am facing a very similar issue to these questions:
convert Rcpp::NumericVector to Eigen::VectorXd
Converting between NumericVector/Matrix and VectorXd/MatrixXd in Rcpp(Eigen) to perform Cholesky solve
I am writing an R-package, that uses the RcppEigen library for Matrix arithmetic. My problem is that the project is not compiling because of an error in the conversion of the Rcpp::NumericMatrix input to an Eigen::MatrixXd.
The file looks like this:
#include <map>
#include <Rcpp.h>
...
using namespace Eigen;
...
// [[Rcpp::export]]
Rcpp::List my_function(Rcpp::NumericMatrix input_matrix)
{
...
Map<MatrixXd> GATE_matrixx(Rcpp::as<Map<MatrixXd> >(GATE_matrix));
...
}
This gives me the following error:
Myfile.cpp:40:65: required from here
C:/Users/User/AppData/Local/Programs/R/R-4.2.2/library/Rcpp/include/Rcpp/internal/Exporter.h:31:31:error:
matching function for call to 'Eigen::Map<Eigen::Matrix<double, -1,
-1> >::Map(SEXPREC*&) 31 | Exporter( SEXP x ) : t(x) | ^ In file included from
C:/Users/User/AppData/Local/Programs/R/R-4.2.2/library/RcppEigen/include/Eigen/Core:19
from
C:/Users/User/AppData/Local/Programs/R/R-4.2.2/library/RcppEigen/include/Eigen/SparseCore:11
from
C:/Users/User/AppData/Local/Programs/R/R-4.2.2/library/RcppEigen/include/Eigen/Sparse:26
from Myfile.cpp:8
I have also tried to change the line to:
MatrixXd input_matrix_eigen(Rcpp::as\<MatrixXd\>(input_matrix));
This gives me the equivalent error :
Myfile.cpp:40:54: required from here
C:/Users/User/AppData/Local/Programs/R/R
4.2.2/library/RcppEigen/include/Eigen/src/Core/Matrix.h:332:31:error: matching function for call to 'Eigen::Matrix<double, -1,
-1>::_init1<SEXPREC*>(SEXPREC* const&)
Do you have any ideas?
If more information is required to evaluate the issue, just let me know.
If you use the command
RcppEigen::RcppEigen.package.skeleton("demoPackage")
an example package demoPackage is created for you which you can install the usual way. It contains example functions to create amd return a matrix:
// [[Rcpp::export]]
Eigen::MatrixXd rcppeigen_hello_world() {
Eigen::MatrixXd m1 = Eigen::MatrixXd::Identity(3, 3);
// Eigen::MatrixXd m2 = Eigen::MatrixXd::Random(3, 3);
// Do not use Random() here to not promote use of a non-R RNG
Eigen::MatrixXd m2 = Eigen::MatrixXd::Zero(3, 3);
for (auto i=0; i<m2.rows(); i++)
for (auto j=0; j<m2.cols(); j++)
m2(i,j) = R::rnorm(0, 1);
return m1 + 3 * (m1 + m2);
}
If you set the same seed as I do you should get the same matrix
> set.seed(42)
> demoPackage::rcppeigen_hello_world()
[,1] [,2] [,3]
[1,] 8.11288 -1.694095 1.089385
[2,] 1.89859 5.212805 -0.318374
[3,] 4.53457 -0.283977 10.055271
>

Extract a data.frame from a list within Rcpp

This is probably a really simple question, but I can't figure out what's wrong.
I have a list that I pass to an Rcpp function, and the first element of that list is a data.frame.
How do I get that data.frame?
bar = list(df = data.frame(A = 1:3,B=letters[1:3]),some_other_variable = 2)
foo(bar)
And the following C++ code:
#include <Rcpp.h>
// [[Rcpp::export]]
Rcpp::NumericVector bar(Rcpp::List test){
Rcpp::DataFrame df_test = test["df"];
Rcpp::NumericVector result = df_test["A"];
return result;
}
I get the following error on the line DataFrame df_test = test["df"]:
error: conversion from 'Rcpp::Vector<19>::NameProxy{aka 'Rcpp::internal::generic_name_proxy<19, Rcpp::PreserveStorage> to 'Rcpp::DataFrame{aka 'Rcpp::DataFrame_ImplRcpp::PreserveStorage ambiguous
Anyone know what I'm missing? Thanks.
There may be a combination of issues going on with the instantiation and construction of List and DataFrame objects. See the (old !!) RcppExamples package for working examples.
Here is a repaired version of your code that works and does something with the vector inside the data.frame:
Code
#include <Rcpp.h>
// [[Rcpp::export]]
int bar(Rcpp::List test){
Rcpp::DataFrame df(test["df"]);
Rcpp::IntegerVector ivec = df["A"];
return Rcpp::sum(ivec);
}
/*** R
zz <- list(df = data.frame(A = 1:3,B=letters[1:3]),some_other_variable = 2)
bar(zz)
*/
Demo
> Rcpp::sourceCpp("~/git/stackoverflow/70035630/answer.cpp")
> zz <- list(df = data.frame(A = 1:3,B=letters[1:3]),some_other_variable = 2)
> bar(zz)
[1] 6
>
Edit: For completeness, the assignment op can be used with a SEXP as in SEXP df2 = test["df"]; which can then used to instantiate a data.frame. Template programming is difficult and not all corners are completely smoothed.

Ignore missing values while finding min in Rcpp

I am trying to find the minimum of 2 values from 2 vectors in Rcpp. But the following does not compile:
#include <cmath>
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector timesTwo(int time_length, double BXadd,
NumericVector vn_complete, NumericVector vn1_complete) {
// Empty vectors
NumericVector BX (time_length);
for(int t = 0; t < time_length; t++) {
BX[t] = BXadd * sqrt(std::min(na_omit(vn_complete[t], vn1_complete[t])));
}
return BX;
// return vn_complete[0];
}
Error 1 occurred building shared library.
It works if I don't use na_omit.
R code for running the function:
Rcpp::sourceCpp("test.cpp")
timesTwo(5, 2, 5:9, 1:5)
What follows below is a slightly non-sensical answer (as it only works with vectors not containing NA) but it has all the component your code has, and it compiles.
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector foo(int time_length, double BXadd,
NumericVector vn_complete, NumericVector vn1_complete) {
// Empty vectors
NumericVector BX (time_length);
vn_complete = na_omit(vn_complete);
vn1_complete = na_omit(vn1_complete);
for(int t = 0; t < time_length; t++) {
double a = vn_complete[t];
double b = vn1_complete[t];
BX[t] = BXadd * std::sqrt(std::min(a,b));
}
return BX;
}
// Edited version with new function added
// [[Rcpp::export]]
NumericVector foo2(double BXadd, NumericVector vn_complete,
NumericVector vn1_complete) {
return BXadd * sqrt(pmin(vn_complete, vn1_complete));
}
/*** R
foo(5, 2, 5:9, 1:5)
foo2(5, 2, 5:9, 1:5)
*/
For a real solution you will have to think harder about what the removal of NA is supposed to do as it will alter the lenth of your vectors too. So this still needs work.
Lastly, your whole function can be written in R as
2 * sqrt(pmin(5:9, 1:5))
and I think you could write that same expression using Rcpp sugar too as we have pmin() and sqrt():
// [[Rcpp::export]]
NumericVector foo2(double BXadd, NumericVector vn_complete,
NumericVector vn1_complete) {
return BXadd * sqrt(pmin(vn_complete, vn1_complete));
}

Using R's "which" function in Rcpp, not returning values

I've written an Rcpp function to call R's which function to check for equality. It compiles fine but it appears that it is only returning values for the first item in a vector: mywhich(samplevector, samplevector[1]) returns a value, mywhich(samplevector, samplevector[2]) returns numeric(0).
The code of the function is below, it only needs to run on Numeric and Integer Vectors
#include <Rcpp.h>
using namespace Rcpp;
//[[Rcpp::export]]
SEXP mywhich(SEXP x, SEXP y) {
//For each supported type, turn it into the 'real' type and
//perform the operation. We can use TYPEOF to check the type.
switch(TYPEOF(x)){
case REALSXP: {
Environment base("package:base");
Function f("which");
NumericVector answer = f(as<NumericVector>(y) == as<NumericVector>(x));
return wrap(answer);
}
case INTSXP: {
Environment base("package:base");
Function f("which");
IntegerVector answer = f(as<IntegerVector>(y) == as<IntegerVector>(x));
return wrap(answer);
}
default: {
stop("Only integer and numeric vectors are supported");
}
}}
any help would be appreciated
When you do <long vector> == <short vector> in R, the short vector gets recycled to match the long vector's length. This does not happen in Rcpp! In your case, you want to do <vector> == <single element vector>, which can be done in Rcpp with <vector> == <double/int/...>. This means you have to select the 0-Element from the single element vector. In your code:
#include <Rcpp.h>
using namespace Rcpp;
//[[Rcpp::export]]
SEXP mywhich(SEXP x, SEXP y) {
//For each supported type, turn it into the 'real' type and
//perform the operation. We can use TYPEOF to check the type.
switch(TYPEOF(x)){
case REALSXP: {
Environment base("package:base");
Function f("which");
NumericVector answer = f(as<NumericVector>(y)(0) == as<NumericVector>(x));
// ^^^
return wrap(answer);
}
case INTSXP: {
Environment base("package:base");
Function f("which");
IntegerVector answer = f(as<IntegerVector>(y)(0) == as<IntegerVector>(x));
// ^^^
return wrap(answer);
}
default: {
stop("Only integer and numeric vectors are supported");
}
}}
BTW, I am not convinced that you need which from R to find the indices in a LogicalVector that are true.

Weird define in C++ preprocessor

I've come across this
#define DsHook(a,b,c) if (!c##_) { INT_PTR* p=b+*(INT_PTR**)a; VirtualProtect(&c##_,4,PAGE_EXECUTE_READWRITE,&no); *(INT_PTR*)&c##_=*p; VirtualProtect(p,4,PAGE_EXECUTE_READWRITE,&no); *p=(INT_PTR)c; }
and everything is clear except the "c##_" word, what does that mean?
It means to "glue" together, so c and _ get "glued together" to form c_. This glueing happens after argument replacement in the macro. See my example:
#define glue(a,b) a##_##b
const char *hello_world = "Hello, World!";
int main(int arg, char *argv[]) {
printf("%s\n", glue(hello,world)); // prints Hello, World!
return 0;
}
It is called a token-pasting operator. Example:
// preprocessor_token_pasting.cpp
#include <stdio.h>
#define paster( n ) printf( "token" #n " = %d", token##n )
int token9 = 9;
int main()
{
paster(9);
}
Output
token9 = 9
That's concatenation that appends an underscore to the name passed as c. So when you use
DsHook(a,b,Something)
that part turns into
if (!Something_)
After the preprocessor, your macro will be expanded as:
if (!c_) { INT_PTR* p=b+*(INT_PTR**)a; VirtualProtect(&c_,4,PAGE_EXECUTE_READWRITE,&no); *(INT_PTR*)&c_=*p; VirtualProtect(p,4,PAGE_EXECUTE_READWRITE,&no); *p=(INT_PTR)c; }
The ## directive concatenates the value of c which you pass as a macro parameter to _
Simple one:
#define Check(a) if(c##x == 0) { }
At call site:
int varx; // Note the x
Check(var);
Would expand as:
if(varx == 0) { }
It is called Token Concatenation and it is used to concatenate tokens during the preprocessing
For example the following code will print out the values of the values of c, c_, c_spam:
#include<stdio.h>
#define DsHook(a,b,c) if (!c##_) \
{printf("c=%d c_ = %d and c_spam = %d\n",\
c, c##_,c##_spam);}
int main(){
int a,b,c=3;
int c_ = 0, c_spam = 4;
DsHook(a,b,c);
return 0;
}
Output:
c=3 c_ = 0 and c_spam = 4

Resources