在两个for循环中分配

时间:2018-04-01 21:44:59

标签: rcpp

我正在尝试构建一个特定的矩阵但是使用简单的R可能需要花费大量时间来考虑我必须使用的条目的大小。我在Rcpp中使用Armadillo功能编写了一个函数,因为我需要使用线性代数部分来处理矩阵。我的代码是下一个:

library('Rcpp')
library('inline')
library('RcppArmadillo')

cppFunction("arma::mat GramMat(arma::mat A, double parametro, int n) {
            arma::mat resultado=A;
            double temp;
            for (int i=0; i<n; i++){
              for (int j=i; j<n; j++){
                  resultado(j,i)= exp(-1*parametro*((A.col(i)-A.col(j)).t() * (A.col(i)-A.col(j))));
              }
            }
            for (int i=0; i<n; i++){
              for (int j=0; j<i; j++){
                resultado(i,j)=resultado(j,i);
              }
            }
            return resultado;}",depends="RcppArmadillo") 

我收到了下一个错误:

               temp= exp(-1*parametro*((A.col(i)-A.col(j)).t() * (A.col(i)-A.col(j))));
                   ^
make: *** [file548914af6578.o] Error 1

问题在于分配,因为我尝试仅分配1并且分配工作正常。我认为可能问题出在右侧,但是我用Rcout打印它并提供了很好的数字。

1 个答案:

答案 0 :(得分:1)

当我尝试编译代码时,我看到了一条信息量更大的错误消息:

  

file2f78133e7bc2.cpp:在函数'arma :: mat GramMat(arma :: mat,   double,int)':file2f78133e7bc2.cpp:14:99:错误:无法转换   “ARMA :: enable_if2,   arma :: subview_col,arma :: eglue_minus&gt;,arma :: op_htrans&gt;,   arma :: eGlue,arma :: subview_col,   arma :: eglue_minus&gt;,arma :: glue_times&gt ;,arma :: eop_scalar_times&gt;,   ARMA :: eop_exp&GT; &gt; ::结果{aka const   ARMA ::期末,   arma :: subview_col,arma :: eglue_minus&gt;,arma :: op_htrans&gt;,   arma :: eGlue,arma :: subview_col,   arma :: eglue_minus&gt;,arma :: glue_times&gt ;,arma :: eop_scalar_times&gt;,   分配时arma :: eop_exp&gt;}'到'double'                      resultado(j,i)= exp(-1 * parametro *((A.col(i)-A.col(j))。t()*(A.col(i)-A.col(j)) ));                                                                                                      ^ make:*** [file2f78133e7bc2.o]错误1

这直接引导我们解决问题;操作

(A.col(i)-A.col(j)).t() * (A.col(i)-A.col(j))

返回无法直接转换为double的类型。但是,我们可以使用arma::as_scalar()来解决此问题(请参阅Armadillo文档中的here);以下编译的罚款对我来说:

cppFunction("arma::mat GramMat(arma::mat A, double parametro, int n) {
            arma::mat resultado=A;
            double temp;
            for (int i=0; i<n; i++){
              for (int j=i; j<n; j++){
                  resultado(j,i)= arma::as_scalar(exp(-1*parametro*((A.col(i)-A.col(j)).t() * (A.col(i)-A.col(j)))));
              }
            }
            for (int i=0; i<n; i++){
              for (int j=0; j<i; j++){
                resultado(i,j)=resultado(j,i);
              }
            }
            return resultado;}",depends="RcppArmadillo") 

当然,在这段代码中还有很多其他事情可以改进。例如,正如Dirk Eddelbuettel指出的那样,您实际上从未在代码中使用temp。您可能还想使用arma::dot()来获取(A.col(i)-A.col(j))的点积(请参阅Armadillo文档中的here - 因为arma::dot()返回一个双精度,它也会无需使用arma::as_scalar())等。