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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With