块对角矩阵Armadillo

3
我正在尝试使用Armadillo中的一个field(列表)对象构建一个块对角矩阵。我的代码可以编译,但是却一直处于等待状态:
    // [[Rcpp::export]]
arma::mat blockDiag( arma::field<mat> x ) {

//x: list of matrices 

unsigned int n = x.n_rows ;
int dimen = 0 ;
arma::ivec dimvec ;

    for(unsigned int i=0; i<n; i++) {
        dimvec[i] = x(i,0).n_rows ; 
        dimen += dimvec[i] ;
    }

mat X(dimen,dimen,fill::zeros);
int idx=0;

    for(unsigned int i=0; i<n; i++) {
        X.submat( idx, idx, idx + dimvec[i] - 1, idx + dimvec[i] - 1 ) = x(i,0) ;
        idx = idx + dimvec[i] ;
    }

    return(X);
}

2
您需要使用正确的大小初始化dimvec,即arma :: ivec dimvec(n); - johanmaack
@johanmaack 再次感谢,我以为只需要实例化变量。 - nopeva
1
你的 blockDiag() 函数存在性能问题:它通过复制传递了 x 变量。对于 field<mat> 对象来说,这是相当昂贵的。为了避免复制,将函数声明更改为使用引用:blockDiag(arma::field<mat>& x)。注意额外的 &。其他所有内容都保持不变,包括函数的使用/调用。 - mtall
在哪些情况下,如果您在不同的函数中使用名称x作为变量,则使用&是安全的? - nopeva
1个回答

4
正如johanmaack所建议的那样,主要问题是向量的大小不正确。你的代码简单地破坏了内存,导致崩溃。将更改为可以解决这个问题。
然而,你的代码还有另一个问题,你很可能会再次犯同样或类似的错误。你目前正在通过[]运算符访问的元素,该运算符没有边界检查。这就是为什么没有报告错误的原因。相反,使用在Armadillo中具有边界检查的()运算符。换句话说,将更改为。只有在确保代码正确工作时才禁用边界检查。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接