问题
I am having some trouble compiling this simple c++
code using Rcpp
and the RcppArmadillo
package. Take the following simple example to multiply each column of a matrix by a numeric scalar:
code <- 'arma::mat out = Rcpp::as<arma::mat>(m);
for(int i = 0; i < out.n_cols; ++i){
out.col(i) *= v;
}
return Rcpp::wrap( out );'
Trying to compile this using...
require( RcppArmadillo )
armMult <- cxxfunction( signature( m = "numeric" , v = "numeric" ),
code , plugin = "RcppArmadillo" )
Results in the compile error....
#error: no match for 'operator*=' in 'arma::Mat<eT>::col(arma::uword) [with eT = double, arma::uword = unsigned int](((unsigned int)i)) *= v'
However, if we swap the numeric
variable v
for 2.0
as below....
code <- 'arma::mat out = Rcpp::as<arma::mat>(m);
for(int i = 0; i < out.n_cols; ++i){
out.col(i) *= 2.0; //Notice we use 2.0 instead of a variable
}
return Rcpp::wrap( out );'
It compiles just fine....
armMult <- cxxfunction( signature(m="numeric"),
code,plugin="RcppArmadillo")
And we can then do...
m <- matrix( 1:4 , 2 , 2 )
armMult( m )
[,1] [,2]
[1,] 2 6
[2,] 4 8
What am I missing here? How can I make this work with a simple numeric scalar. I would like to be able to pass a scalar like...
armMult( m , 2.0 )
And return the same result as above.
回答1:
If you want to multiply each column of a matrix A by the corresponding element of a vector x then try this:
Rcpp:::cppFunction(
"arma::mat fun(arma::mat A, arma::rowvec x)
{
A.each_row() %= x;
return A;
}", depends = "RcppArmadillo"
)
fun(matrix(rep(1, 6), 3, 2), c(5, 1))
[,1] [,2]
[1,] 5 1
[2,] 5 1
[3,] 5 1
回答2:
Whenever I scratch my head over issues like this, I start by reducing the problem. Try a C++ three-liner just using Armadillo headers. Make it work, then move it over to RcppArmadillo.
Edit: One can do better than your answer as you don't need to multiply each column individually (though one can). Anyway, this just shows off Rcpp Attributes:
> cppFunction("arma::mat simon(arma::mat m, double v) { return m * v;}",
+ depends="RcppArmadillo")
> simon(matrix(1:4,2,2), 3)
[,1] [,2]
[1,] 3 9
[2,] 6 12
>
回答3:
Thanks to a comment by @DirkEddelbuettel it was simply because I had not defined v
...
code <- '
arma::mat out = Rcpp::as<arma::mat>(m);
double scl = Rcpp::as<double>(v);
for(int i = 0; i < out.n_cols; ++i){
out.col(i) *= scl;
}
return Rcpp::wrap( out );
'
armMult <- cxxfunction( signature( m = "numeric" , v = "numeric" ),
code , plugin = "RcppArmadillo" )
armMult( m , 2.0 )
[,1] [,2]
[1,] 2 6
[2,] 4 8
来源:https://stackoverflow.com/questions/18361570/multiplying-a-column-vector-by-a-numeric-scalar-in-rcpparmadillo