Boost logo

Boost :

From: Antonio Piccolboni (Antonio_Piccolboni_at_[hidden])
Date: 2004-08-27 16:37:34


Hi everyone,
I have the following problem. I need to apply the same permutation to two
sequence collections.
The following code for the single permutation works like a charm:

random_shuffle(TGraphRowVectorIterator<Identifier>(theGraph.begin()),
                        TGraphRowVectorIterator<Identifier>(theGraph.end()));

(only, I haven't figured out how to random seed random_shuffle, but I
guess this is a question for another forum)

TGraphRowVectorIterator<Identifier> is a projection iterator.
Unfortunately when I wrote it I didn't know about boost so I wrote it by
hand and I hate that code now (attached at the end) but it seems to work
ok in many contexts.

Now to the simultaneous permutation of two:

  random_shuffle
     (boost::make_zip_iterator
      (boost::make_tuple
       (TGraphRowVectorIterator<long>(firstGraph.begin()),
        TGraphRowVectorIterator<long>(secondGraph.begin())
        )
       ),
      boost::make_zip_iterator
      (boost::make_tuple
       (TGraphRowVectorIterator<long>(firstGraph.end()),
        TGraphRowVectorIterator<long>(secondGraph.end())
        )
       )
      );

(I think if this is going to work I will make it my favorite example of
generic programming. Isn't it a thing of beauty? Can this be solved in C
without duplicating and uglyfying the shuffle code?).

This unfortunately doesn't return a permutation. The resulting vector has
repetitions in it. I debugged the code all the way inside iter_swap and it
looks like the side effects of the swap are propagated only to one of the
arguments, to my astonishment because they have THE SAME TYPE. So if I
screwed with the iterator definition, which is totally a possibility, it
should simply not permute anything. I am not yet ready to claim there is a
bug in zip_iterator, but this is very suspicios. Thanks for anyone's help

Antonio

----Ugly iterator code, is there anythng wrong with the signatures? Thank
God for the <iterator>!-------

template<class Identifier>
   class TGraphRowVectorIterator :
   public iterator<random_access_iterator_tag, vector<double>, long> {
   typename TGraph<Identifier>::iterator rowIterator;
   public:
   TGraphRowVectorIterator<Identifier> (typename
TGraph<Identifier>::iterator rowI) {
     rowIterator = rowI;
   }

   TGraphRowVectorIterator<Identifier> () {
   }

   vector <double> & operator *() const {
     return rowIterator->values;
   }

   vector <double> * operator ->() {
     return &(operator*());
   }

   bool operator == (const TGraphRowVectorIterator<Identifier> & that)
const {
     return rowIterator == that.rowIterator;
   }

   bool operator != (const TGraphRowVectorIterator<Identifier> & that)
const {
     return !(*this == that);
   }

   bool operator < (const TGraphRowVectorIterator<Identifier> & that) const
{
     return rowIterator < that.rowIterator;
   }

   bool operator >= (const TGraphRowVectorIterator<Identifier> & that)
const {
     return !(*this < that);
   }

   bool operator >(const TGraphRowVectorIterator<Identifier> & that) const {
     return (*this >= that) && (*this != that);
   }

   bool operator <= (const TGraphRowVectorIterator<Identifier> & that)
const {
     return !(*this > that);
   }

   TGraphRowVectorIterator<Identifier> operator ++ (){
     rowIterator ++;
     return *this;
   }

   TGraphRowVectorIterator<Identifier> operator -- (){
     rowIterator --;
     return *this;
   }

   TGraphRowVectorIterator<Identifier> operator ++ (int){
     TGraphRowVectorIterator<Identifier> tmp(*this);
     rowIterator ++;
     return tmp;
   }

   TGraphRowVectorIterator<Identifier> operator -- (int){
     TGraphRowVectorIterator<Identifier> tmp(*this);
     rowIterator --;
     return tmp;
   }

   TGraphRowVectorIterator<Identifier> operator + (long drow) {
     return TGraphRowVectorIterator<Identifier> (rowIterator + drow);
   }

   TGraphRowVectorIterator<Identifier> operator += (long drow) {
     rowIterator += drow;
     return *this;
   }

   TGraphRowVectorIterator<Identifier> operator - (long drow) const{
     return (*this + (-drow));
   }

   long operator - (TGraphRowVectorIterator<Identifier> that) const {
     return rowIterator - that.rowIterator;
   }

   Identifier position() {
     return rowIterator->position();
   }
};

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk