两个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()
) 等的需要
我正在尝试构建一个特定的矩阵,但考虑到我必须使用的条目的大小,仅使用 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()
) 等的需要