两个for循环内的赋值

Assignment inside two for loops

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

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 打印了它,并且提供了井号。

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

file2f78133e7bc2.cpp: In function ‘arma::mat GramMat(arma::mat, double, int)’: file2f78133e7bc2.cpp:14:99: error: cannot convert ‘arma::enable_if2, arma::subview_col, arma::eglue_minus>, arma::op_htrans>, arma::eGlue, arma::subview_col, arma::eglue_minus>, arma::glue_times>, arma::eop_scalar_times>, arma::eop_exp> >::result {aka const arma::eOp, arma::subview_col, arma::eglue_minus>, arma::op_htrans>, arma::eGlue, arma::subview_col, arma::eglue_minus>, arma::glue_times>, arma::eop_scalar_times>, arma::eop_exp>}’ to ‘double’ in assignment resultado(j,i)= exp(-1*parametro*((A.col(i)-A.col(j)).t() * (A.col(i)-A.col(j)))); ^ make: *** [file2f78133e7bc2.o] Error 1

这直接导致了我们的问题;操作

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

returns 无法直接转换为 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") 

当然,这段代码还有很多其他地方可以改进。例如,作为 Armadillo 文档中的 Dirk Eddelbuettel points out, you actually never use temp in your code. You might also want to use arma::dot() to get the dot product of (A.col(i)-A.col(j)) with itself (see here——作为 arma::dot() returns 一个双精度数,它也将消除使用 arma::as_scalar()) 等的需要