2013-08-21 35 views
2

我在使用RcppRcppArmadillo包编译此简单c++代码时遇到了一些问题。采取以下简单的例子由数值标量相乘的矩阵的各列:在RcppArmadillo中将列向量乘以数字标量

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);' 

试图使用这个编译...

require(RcppArmadillo) 
armMult <- cxxfunction(signature(m = "numeric" , v = "numeric"), 
         code , plugin = "RcppArmadillo") 

结果编译错误....

#error: no match for 'operator*=' in 'arma::Mat<eT>::col(arma::uword) [with eT = double, arma::uword = unsigned int](((unsigned int)i)) *= v' 

但是,如果我们交换numeric变量v2.0如下....

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);' 

它编译就好了....

armMult <- cxxfunction(signature(m="numeric"), 
         code,plugin="RcppArmadillo") 

,然后我们可以做...

m <- matrix(1:4 , 2 , 2) 

armMult(m) 
    [,1] [,2] 
[1,] 2 6 
[2,] 4 8 

缺少什么我在这里?我如何使用简单的数字标量来完成这项工作。我想能够通过一个标量像...

armMult(m , 2.0) 

并返回与上述相同的结果。

回答

8

如果你想每次乘矩阵的列A由相应元素的矢量x然后试试这个:

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 
+1

+1很好的回答!您也应该将其作为[***此问题***](http://stackoverflow.com/q/18349053/1478381)的答案。 –

+1

或者如果您不太热衷,我会将其添加到我的答案中,并添加到其他答案的基准中。 –

+0

当然!继续并添加它:-) – chris

2

每当我从头开始讨论这样的问题时,我就从减少问题开始。尝试使用Armadillo标题的C++三层线程。让它工作,然后移动到RcppArmadillo。

编辑:你可以做得比你的答案更好,因为你不需要单独乘以每一列(尽管可以)。无论如何,这只是展示了RCPP属性

> 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 
> 
+0

谢谢。你对这个问题的评论帮助了这个新手很多。 –

+0

嗨德克,感谢您的编辑。其实,我想我正在从你的书中抽出一部分来减少问题。我实际上想要做的是将每个列乘以一个向量的每个对应元素([这个问题](http://stackoverflow.com/q/18349053/1478381)),但我想我会得到这个更简单的例子工作首先,但是这个解决方案很好的说明了Rcpp的属性。谢谢。 –

1

多亏了@DirkEddelbuettel评论那只是因为我还没有确定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