The following Rcpp code is the minimal reproducible example for a much larger code that generates the identical compilation error. It seems that I cannot asign a numeric matrix to a list and the list then again to another matrix.
#include <Rcpp.h>
using namespace Rcpp;
//[[Rcpp::export]]
List return_a(NumericMatrix a, NumericMatrix b){
//the function only returns the input matrix a
List result(1);
result(0) = a;
return(result);
}
//[[Rcpp::export]]
List wrapper_cpp(NumericMatrix a, NumericMatrix b){
//the function is a dummy wrapper for much more code
List Step1(1);
List results(1);
Step1 = return_a(a,b);
a = Step1(0);
results(0) = a;
return(results);
}
The code above gives the following compilation error that I shortened:
error: ambiguous overload for 'operator=' (operand types are 'Rcpp::NumericMatrix {aka Rcpp::Matrix<14>}' and 'Rcpp::Vector<19>::Proxy ...
a = Step1(0);
My real function is much more complex. I need to manipulate matrices in several loops and in each step the matrices are returned by each function within a list. I then need to extract these lists to manipulate the matrices further. How can this be done?
Besides the error that #Ralf already mentioned, you were simply trying too much. Sometimes we need an intermediate step as the template magic is ... finicky. The following works.
Code
#include <Rcpp.h>
using namespace Rcpp;
//[[Rcpp::export]]
List return_a(NumericMatrix a, NumericMatrix b){
//the function only returns the input matrix a
List result(1);
result(0) = a;
return(result);
}
//[[Rcpp::export]]
List wrapper_cpp(NumericMatrix a, NumericMatrix b){
//the function is a dummy wrapper for much more code
List results(1);
List Step1 = return_a(a,b);
NumericMatrix tmp = Step1(0);
results(0) = tmp;
return(results);
}
Output
R> Rcpp::sourceCpp("~/git/stackoverflow/54771818/answer.cpp")
R> wrapper_cpp(matrix(1:4,2,2), matrix(4:1,2,2))
[[1]]
[,1] [,2]
[1,] 1 3
[2,] 2 4
R>
Related
Initially, I was importing some data from R directly into a C++ function like so:
#include <RcppArmadillo.h>
using namespace Rcpp;
// [[Rcpp::depends(RcppArmadillo)]]
List gibbs(List dat) {
int N = dat["N"];
arma::vec y = dat["y"];
...
}
Eventually, I needed more than just N and y (the input_data list has many separate vectors and matrices I need to import). So, I thought it would be a good idea to create a class Data to store all the input variables and automatically do some pre-processing in the constructor. Something like
#include <RcppArmadillo.h>
using namespace Rcpp;
// [[Rcpp::depends(RcppArmadillo)]]
class Data {
public:
int N;
arma::vec y;
// other data
Data(List input_data) {
N = input_data["N"];
y = input_data["y"];
// pre-processing steps
}
};
However, this doesn't work. It gives the following error:
object_LocLev.cpp:12:7: error: use of overloaded operator '=' is ambiguous (with operand types 'arma::vec' (aka 'Col<double>') and 'Rcpp::Vector<19>::NameProxy' (aka 'generic_name_proxy<19>'))
y = input_data["y"];
~ ^ ~~~~~~~~~~~~~~~
My question is why does this error appear? Is there a better way of assigning y?
I have two functions written with Rcpp.
The first function f takes a NumericVector as input and returns a NumericVector as output. But often, f is meant to be treated as a scalar function. When I call it from R, it doesn't matter, since R will treat any scalar as a vector anyways, so I don't have to bother about it. I can both use f as a scalar or a vector function, e.g. f(1) and f(c(1,2,3,4) both work.
Question 1: Is this a bad idea? Should I make TWO separate functions, one scalar, and one vectorized? For example, is there some unwanted overhead when I call f from R using scalar input rather than a vector?
The second function g needs to use f purely as a scalar function. This causes a problem because I need to call f from Rcpp when I am defining g.... now I can't use it as a scalar function by calling f(x) for some double x.
I tried doing something like this from inside the definition of g:
NumericVector x = NumericVector::create(value); //create vector of length 1
f(x) //use f(x) as scalar
but timing the code took absurdly long (since the function g needs to perform the above operation many times).
Question 2: Is there a way to more quickly treat f as a scalar function just like I would if I was in R?
My current solution is to do what I asked in Queston 1: create another f function which is scalar, and then call THAT one from g, so that inside g we simply say
alternative_f(x) //use alternative f as scalar
You could factor out the scalar code into a separate (inline) function and call that from both f (with std::transform) and g (+ additional logic). Simplified example:
#include <Rcpp.h>
inline double f_impl (double x) {
return x * 2;
}
// [[Rcpp::export]]
double g (double x) {
return f_impl(x) + 2;
}
// [[Rcpp::export]]
Rcpp::NumericVector f (Rcpp::NumericVector x) {
Rcpp::NumericVector y(Rcpp::no_init(x.length()));
std::transform(x.begin(), x.end(), y.begin(), f_impl);
return y;
}
Why does the following code not compile?
library(Rcpp)
cppFunction('
int rows(const NumericMatrix& X) {
using Eigen::MatrixXf;
typedef Eigen::Map<MatrixXf> MapMat;
MapMat X1(as<MapMat>(X));
return X1.rows();
}', depends = "RcppEigen")
It throws the following error:
error: no matching function for call to 'Eigen::Map<Eigen::Matrix<float, -1, -1> >::Map(Rcpp::Vector<14, Rcpp::PreserveStorage>::iterator, int&, int&)'
OUT get() {return OUT(vec.begin(), d_nrow, d_ncol );}
The same code works fine when I used MatrixXd instead.
Thanks.
NumericMatrix uses type double (as opposed to float). Eigen does not support implicit type casting between matrices using different types. Your code appears to try and read the memory of a double NumericMatrix as a float Eigen matrix. Just use the MatrixXd type instead.
I am brand new to Rcpp. I am trying to using the R package RcppEigen to get the determinant of a matrix. The following code is saved in a file and I use sourceCpp to use it. There is no compilation error when I use sourceCpp. When using getDeterminant(A) in R, A is a matrix. It always complains the following error.
"Error: could not find function "getDeterminant""
However, the getEigenValues works well.
I appreciate a lot if anybody is happy to help me with this.
Thanks a lot!
#include <RcppEigen.h>
// [[Rcpp::depends(RcppEigen)]]
using Eigen::Map; // 'maps' rather than copies
using Eigen::MatrixXd; // variable size matrix, double precision
using Eigen::VectorXd; // variable size vector, double precision
using Eigen::SelfAdjointEigenSolver; // one of the eigenvalue solvers
using Eigen::MatrixXi;
using Eigen::MatrixBase;
// [[Rcpp::export]]
VectorXd getEigenValues(Map<MatrixXd> M) {
SelfAdjointEigenSolver<MatrixXd> es(M);
return es.eigenvalues();
}
// [[Rcpp:export]]
double getDeterminant(Map<MatrixXd> AA){
return AA.determinant();
}
You are missing a : in the second Rcpp Attributes tag: Rcpp::export is the form the regular expression looks for.
If you add it, the functions becomes accessible:
R> Rcpp::sourceCpp("/tmp/crystal.cpp")
R> M <- matrix(1:9,3,3)*1.0
R> getEigenValues(M)
[1] 2.80689e-16 6.99265e-01 1.43007e+01
R> getDeterminant(M)
[1] 0
R>
All right, so I'm programming in R and I want to make a C++ function. I've imported the Rcpp and inline libraries. For right now, I'm just trying to make a simple function that adds 2 numbers, but no matter what I try, I get errors.
Here's my code:
cppstring = 'double ss = RcppSexp(s).asDouble(); return RcppSexp(ss+4).asSexp();'
hi <- cfunction(body=cppstring, signature(s="double"), Rcpp = TRUE)
and when I enter that second line, I get
file628a34ce.cpp: In function ‘SEXPREC* file628a34ce(SEXPREC*)’:
file628a34ce.cpp:9: error: ‘RcppSexp’ was not declared in this scope
make: *** [file628a34ce.o] Error 1
ERROR(s) during compilation: source code errors or compiler configuration errors!
Program source:
1: #include <Rcpp.h>
2:
3:
4: extern "C" {
5: SEXP file628a34ce ( SEXP s );
6: }
7:
8: SEXP file628a34ce ( SEXP s ) {
9: double ss = RcppSexp(s).asDouble(); return RcppSexp(ss+4).asSexp();
10: Rf_warning("your C program does not return anything!");
11: return R_NilValue;
12: }
Error in compileCode(f, code, language, verbose) :
Compilation ERROR, function(s)/method(s) not created! file628a34ce.cpp: In function ‘SEXPREC* file628a34ce(SEXPREC*)’:
file628a34ce.cpp:9: error: ‘RcppSexp’ was not declared in this scope
make: *** [file628a34ce.o] Error 1
I've tried everything I could possibly think of, from casting, to moving code around, to #including RcppSexp, to just plain returning s, and every time I get some error, whether it's
cannot convert ‘double’ to ‘SEXPREC*’ in return
or
invalid use of undefined type ‘struct SEXPREC’
or
forward declaration of ‘struct SEXPREC’
...I'm so confused :( I've looked at several examples online, and what I currently have seems to be what everyone else is doing, and it magically works for them...
What is this SEXPREC* thing I keep seeing everywhere? And what is that extern "C" function thing that it makes? And why does it generate statements AFTER my return statement and tell me that my function doesn't return anything, even though it does?
Is there a reason you are not starting from the (literally!!) dozens of Rcpp examples using inline?
Also, what on earth is RcppSexp? What documentation are your following?
Here is an example I did last night for someone on the rcpp-devel (which you should probably join):
library(Rcpp)
library(inline)
xorig <- c(1, -2, 3, -4, 5, -6, 7)
code <- '
Rcpp::NumericVector x(xs);
Rcpp::NumericVector xa = sapply( x, ::fabs );
return(xa);
'
xabs <- cxxfunction(signature(xs="numeric"),
plugin="Rcpp",
body=code)
xabs(xorig)
This is a more advanced example as it uses Rcpp sugar to give us vectorised expression a la R in C++, which we demonstrate here with a the simple sapply() from Rcpp sugar:
R> library(Rcpp)
R> library(inline)
R>
R> xorig <- c(1, -2, 3, -4, 5, -6, 7)
R>
R> code <- '
+ Rcpp::NumericVector x(xs);
+ Rcpp::NumericVector xa = sapply( x, ::fabs );
+ return(xa);
+ '
R>
R> xabs <- cxxfunction(signature(xs="numeric"),
+ plugin="Rcpp",
+ body=code)
R>
R> xabs(xorig)
[1] 1 2 3 4 5 6 7
R>
This most clearly demonstrates two of your requests: we use the implicit template converters as<>() to go from a SEXP given from R to the initial vector, and then use the implicit template converter wrap() to return the transformed second vector.
All this is explained in detail in the Rcpp-introduction vignette and the other vignettes in the Rcpp documentation,.