RankAtoms.h

Go to the documentation of this file.
00001 //
00002 //  Copyright (C) 2004-2008 Greg Landrum and Rational Discovery LLC
00003 //
00004 //   @@ All Rights Reserved  @@
00005 //
00006 
00007 //! \file RankAtoms.h
00008 /*!
00009     \brief Utility functionality used by atom rankers.
00010 */
00011 #ifndef _RD_RANKATOMS_H_
00012 #define _RD_RANKATOMS_H_
00013 
00014 #include <queue>
00015 #include <vector>
00016 #include <list>
00017 #include <algorithm>
00018 
00019 namespace RankAtoms {
00020   typedef std::vector<int> INT_VECT;
00021   typedef std::list<int> INT_LIST;
00022 
00023   //! utility function for ranking atoms
00024   void updateInPlayIndices(const INT_VECT &ranks,INT_LIST &indicesInPlay);
00025 
00026   //! returns the count of unique items in an std::vector
00027   template <typename T>
00028   unsigned int countClasses(const std::vector<T> &vect){
00029     std::vector<T> sortedVect = vect;
00030     std::sort(sortedVect.begin(),sortedVect.end(),std::less<T>());
00031     typename std::vector<T>::iterator newEnd=std::unique(sortedVect.begin(),sortedVect.end());
00032     return newEnd-sortedVect.begin();
00033   }
00034 
00035   //! functor for implementing > on two std::pairs.  The first entries are compared.
00036   template <typename T>
00037   struct pairGTFunctor {
00038     bool operator() (const std::pair<T,int> &v1,const std::pair<T,int> &v2){
00039       return v1.first > v2.first;
00040     }
00041   };
00042 
00043   //! function for implementing < on two std::pairs.  The first entries are compared.
00044   template <typename T>
00045   bool pairLess(const std::pair<T,int> &v1,const std::pair<T,int> &v2){
00046     return v1.first < v2.first;
00047   }
00048 
00049   template <typename T>
00050   class argless {
00051   public:
00052     argless(const T& c) : container(c) {};
00053     bool operator() (unsigned int v1,unsigned int v2){
00054       return container[v1]<container[v2];
00055     }
00056     const T &container;
00057   };
00058 
00059   
00060   //! ranks the entries in a vector
00061   /*!
00062     \param vect the vector to rank
00063     \param res  is used to return the ranks of each entry
00064   */
00065   template <typename T>  
00066   void rankVect(const std::vector<T> &vect,INT_VECT &res){
00067     PRECONDITION(res.size()>=vect.size(),"vector size mismatch");
00068     unsigned int nEntries = vect.size();
00069 
00070     std::vector< unsigned int > indices(nEntries);
00071     for(unsigned int i=0;i<nEntries;++i) indices[i]=i; 
00072     std::sort(indices.begin(),indices.end(),argless< std::vector<T> >(vect) );
00073 
00074     int currRank=0;
00075     T lastV = vect[indices[0]];
00076     for(unsigned int i=0;i<nEntries;++i){
00077       T v = vect[indices[i]];
00078       if(v==lastV){
00079         res[indices[i]] = currRank;
00080       } else {
00081         res[indices[i]] = ++currRank;
00082         lastV = v;
00083       }
00084     }
00085   }    
00086 
00087   //! finds the relative rankings of the entries in \c vals.
00088   /*!
00089     \param nAtoms         the number of points in play
00090     \param vals           the values to be ranked
00091     \param indicesInPlay  a list containing the indices that
00092            are being considered (only those entries in \c ranks
00093            that appear in \c indicesInPlay will be modified)
00094     \param ranks          the current ranks of entries, this is updated
00095            with new ranks
00096   */
00097   template <typename T>
00098   void sortAndRankVect(unsigned int nAtoms,
00099                        const std::vector<T> &vals,
00100                        const INT_LIST &indicesInPlay,
00101                        INT_VECT &ranks) {
00102     // --------------
00103     //
00104     // start by getting the internal ranking of the values passed in
00105     //
00106     // --------------
00107     INT_VECT newRanks;
00108     newRanks.resize(vals.size());
00109     rankVect(vals,newRanks);
00110 
00111     // --------------
00112     //  
00113     // At the end of this operation, fixedRanks will contain the ranks
00114     // of atoms that are no longer active (-1 for active atoms).
00115     //
00116     // --------------
00117     for(INT_LIST::const_iterator ilCIt=indicesInPlay.begin();
00118         ilCIt!=indicesInPlay.end();++ilCIt){
00119       ranks[*ilCIt] = -1;
00120     }
00121 
00122 #ifdef VERYVERBOSE_CANON
00123     std::cout << "new: ";
00124     debugVect(newRanks);
00125     std::cout << "fixed: ";
00126     debugVect(ranks);
00127 #endif
00128 
00129     INT_VECT idxVect;
00130     idxVect.assign(indicesInPlay.begin(),indicesInPlay.end());
00131 
00132     // -------------
00133     //
00134     //  Loop over all the new ranks.  We'll know that we're done
00135     //  when currNewRank > maxNewRank
00136     //
00137     // -------------
00138     INT_VECT::iterator ivIt;
00139     int currNewRank= *(std::min_element(newRanks.begin(),newRanks.end()));
00140     int maxNewRank = *(std::max_element(newRanks.begin(),newRanks.end()));
00141     while(currNewRank<=maxNewRank){
00142       //
00143       // If this rank is already present in ranks, increment
00144       //  this rank and all new ranks that are higher:
00145       //
00146       while(std::find(ranks.begin(),ranks.end(),currNewRank)!=ranks.end()){
00147         for(ivIt=newRanks.begin();ivIt!=newRanks.end();++ivIt){
00148           if(*ivIt>=currNewRank)
00149             *ivIt += 1;
00150         }
00151         // increment both thie current rank *and* the maximum new rank
00152         ++currNewRank;
00153         ++maxNewRank;
00154       }
00155 
00156       //
00157       //  now grab all entries with this new rank and copy them into
00158       //  the ranks list
00159       //
00160       ivIt=std::find(newRanks.begin(),newRanks.end(),currNewRank);
00161       while(ivIt!=newRanks.end()){
00162         int offset=ivIt-newRanks.begin();
00163         int idx = idxVect[offset];
00164         ranks[idx] = currNewRank;
00165         ivIt++;
00166         ivIt=std::find(ivIt,newRanks.end(),currNewRank);
00167       }
00168       ++currNewRank;
00169     }
00170   }
00171 }
00172 #endif

Generated on Fri Apr 3 06:03:02 2009 for RDCode by  doxygen 1.5.6