Tobias Reisch
Tobias Reisch

Reputation: 3

How to use write access using iterators and armadillo sparse matrices?

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

Answers (1)

Dirk is no longer here
Dirk is no longer here

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

Related Questions