Reputation: 3
I have to replace some columns in a sparse matrix with columns from another sparse matrix that has the same nonzero elements, just different values, based on a condition.
I am struggling with write access using iterators in Armadillo. The docs say that using sp_mat::col_iterator provides read/write access, however, when I try to write a value *it = B.col(...)
I get an error message error: no match for ‘operator=’ (operand types are ‘arma::SpValProxy<arma::SpMat<double> >’ and ‘arma::SpSubview_col<double>’)
. Do I have a syntax mistake or am I understanding the concept of "write access" wrong?
arma::sp_mat A = arma::sprandu(100, 100, 0.01);
arma::sp_mat B(A);
B *= 2;
arma::vec condition = arma::randi<arma::vec>(100, arma::distr_param(0, 1));
arma::sp_mat::col_iterator it = A.begin();
arma::sp_mat::col_iterator it_end = A.end();
for(; it != it_end; ++it){
if (condition(it.col())==1){
*it = B.col(it.col());
}
}
My solution at the moment is to write a function collecting the indices & values from the respective matrix and then use batch initialization, similar to Access and modify the non zero elements of sparse matrix of class arma::sp_mat using Rcpp code. Nevertheless I would still like to learn about read/write access and iterators.
Upvotes: 0
Views: 523
Reputation: 368241
Looking at the (generally excellent) Armadillo documentation, I think you are up a against a design issue. Quoting
Caveats:
- to modify the non-zero elements in a safer manner, use .transform() or .for_each() instead of iterators;
- writing a zero value into a sparse matrix through an iterator will invalidate all current iterators associated with the sparse matrix row iterators for sparse matrices are only useful with Armadillo 8.500 and later versions; in earlier versions they are inefficient
Upvotes: 2