Boost logo

Ublas :

Subject: Re: [ublas] Accessing the indices of non-zero elements in a UBLAS sparse vector
From: John Reid (j.reid_at_[hidden])
Date: 2011-09-23 03:59:23


On 21/09/11 18:10, Oswin Krause wrote:
> Hi Tarek,
>
> the normal iterator iterates over all elements (it assumes that you want
> to change all elements and not only the non-zeros).
>
> If you only want to change the non-zero elements you have to write
> something like this:
>
> mapped_vector<double> sparseVec;
> //...
> for(mapped_vector<double>::const_iterator pos = sparseVec.begin(); pos !=
> sparseVec.end();++pos){
> sparseVec(pos.index()) = 1;
> }
>
> By default you should never use mapped_vector<double>::iterator except you
> don't need access to all elements!
>
> it's true that this is not well documented. I also found that out only
> after long google sessions :)
>
> I hope i could help,
>

I have a related question. Suppose I want to iterate over the non-zero
elements and change some of them. There seems to be no conversion from
const_iterator to iterator so I'm using a const_cast. Is this guaranteed
to work for all sparse vector types. For example:

#include <boost/numeric/ublas/vector_sparse.hpp>
#include <boost/numeric/ublas/io.hpp>

void
test_iterators() {
     using namespace boost::numeric::ublas;
     mapped_vector< double > v( 30, 10 );
     v( 4 ) = 4;
     v( 14 ) = 14;
     v( 24 ) = 24;
     std::cout << v << std::endl;

     const mapped_vector< double > & cv = v;
     for( mapped_vector< double >::const_iterator i = cv.begin();
cv.end() != i; ++i ) {
         std::cout << i.index() << " : " << *i << "\n";
         //mapped_vector< double >::iterator j = i; ///!!!! Would like
this to work
         mapped_vector< double >::value_type & v = const_cast<
mapped_vector< double >::value_type & >( *i ); /// Using const_cast here
         v += 1;
     }
     std::cout << v << std::endl;
}

Thanks,
John.