简体   繁体   中英

block diagonal matrix armadillo

I'm trying to build a block diagonal matrix out of a field (List) object in Armadillo . My code compiles but hangs:

    // [[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);
}

As johanmaack suggested, the main problem is that the dimvec vector doesn't have the right size. Your code is simply trashing memory, leading to a crash. Changing arma::ivec dimvec to arma::ivec dimvec(n) solves this.

However, your code has another problem, in that you are likely to make the same or similar mistake again. Your code is currently accessing the elements of dimvec through the [] operator, which doesn't have bounds checks. This is why no error was reported. Instead, use the () operator which has bounds checks in Armadillo. In other words, change dimvec[i] to dimvec(i) . Disable the bounds checks only when you are sure that your code works correctly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM