3

我在使用和包编译这个简单的c++代码时遇到了一些麻烦。举一个简单的例子,将矩阵的每一列乘以一个数值标量:RcppRcppArmadillo

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 )

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

4

3 回答 3

9

如果要将矩阵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
于 2013-08-23T14:39:34.193 回答
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
> 
于 2013-08-21T15:32:29.247 回答
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
于 2013-08-21T15:39:57.653 回答