Boost logo

Ublas :

Subject: Re: [ublas] Accessing the indices of non-zero elements in a UBLAS sparse vector
From: Oswin Krause (Oswin.Krause_at_[hidden])
Date: 2011-09-23 04:54:55


Hi,

i already answered your question. You can only convert iterators to
const_iterators, but not the other way around (this is also true for all
std collections). The way to do it is:

for( mapped_vector< double >::const_iterator i = cv.begin(); i !=
cv.end(); ++i ) {
          std::cout << i.index() << " : " << *i << "\n";
          cv(i.index()) += 1;//access *i using the index in cv
}

a bit prettier and for most compilers not slower in release mode.

>
> 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.