RDCode: RankAtoms.h Source File

- Main Page
- Namespaces
- Classes
- Files
- Directories

# 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   //! ranks the entries in a vector
    00050   /*!
    00051     \param vect the vector to rank
    00052     \param res  is used to return the ranks of each entry
    00053   */
    00054   template <typename T>
    00055   void rankVect(const std::vector<T> &vect,INT_VECT &res){
    00056     PRECONDITION(res.size()>=vect.size(),"vector size mismatch");
    00057     unsigned int nEntries = vect.size();
    00058
    00059     std::vector< std::pair<T,int> > sortedVect;
    00060     sortedVect.resize(nEntries);
    00061     for(unsigned int i=0;i<nEntries;++i){
    00062       sortedVect[i]=std::make_pair(vect[i],i);
    00063     }
    00064     std::sort(sortedVect.begin(),sortedVect.end(),pairLess<T>);
    00065     int currRank=0;
    00066     T lastV = sortedVect[0].first;
    00067     for(unsigned int i=0;i<nEntries;++i){
    00068       const std::pair<T,int> &p = sortedVect[i];
    00069       if(p.first==lastV){
    00070         res[p.second] = currRank;
    00071       } else {
    00072         res[p.second] = ++currRank;
    00073         lastV = p.first;
    00074       }
    00075     }
    00076   }
    00077
    00078   //! finds the relative rankings of the entries in \c vals.
    00079   /*!
    00080     \param nAtoms         the number of points in play
    00081     \param vals           the values to be ranked
    00082     \param indicesInPlay  a list containing the indices that
    00083            are being considered (only those entries in \c ranks
    00084            that appear in \c indicesInPlay will be modified)
    00085     \param ranks          the current ranks of entries, this is updated
    00086            with new ranks
    00087   */
    00088   template <typename T>
    00089   void sortAndRankVect(unsigned int nAtoms,
    00090                        const std::vector<T> &vals,
    00091                        const INT_LIST &indicesInPlay,
    00092                        INT_VECT &ranks) {
    00093     // --------------
    00094     //
    00095     // start by getting the internal ranking of the values passed in
    00096     //
    00097     // --------------
    00098     INT_VECT newRanks;
    00099     newRanks.resize(vals.size());
    00100     rankVect(vals,newRanks);
    00101
    00102     // --------------
    00103     //
    00104     // At the end of this operation, fixedRanks will contain the ranks
    00105     // of atoms that are no longer active (-1 for active atoms).
    00106     //
    00107     // --------------
    00108     for(INT_LIST::const_iterator ilCIt=indicesInPlay.begin();
    00109         ilCIt!=indicesInPlay.end();++ilCIt){
    00110       ranks[*ilCIt] = -1;
    00111     }
    00112
    00113 #ifdef VERYVERBOSE_CANON
    00114     std::cout << "new: ";
    00115     debugVect(newRanks);
    00116     std::cout << "fixed: ";
    00117     debugVect(ranks);
    00118 #endif
    00119
    00120     INT_VECT idxVect;
    00121     idxVect.assign(indicesInPlay.begin(),indicesInPlay.end());
    00122
    00123     // -------------
    00124     //
    00125     //  Loop over all the new ranks.  We'll know that we're done
    00126     //  when currNewRank > maxNewRank
    00127     //
    00128     // -------------
    00129     INT_VECT::iterator ivIt;
    00130     int currNewRank= *(std::min_element(newRanks.begin(),newRanks.end()));
    00131     int maxNewRank = *(std::max_element(newRanks.begin(),newRanks.end()));
    00132     while(currNewRank<=maxNewRank){
    00133       //
    00134       // If this rank is already present in ranks, increment
    00135       //  this rank and all new ranks that are higher:
    00136       //
    00137       while(std::find(ranks.begin(),ranks.end(),currNewRank)!=ranks.end()){
    00138         for(ivIt=newRanks.begin();ivIt!=newRanks.end();++ivIt){
    00139           if(*ivIt>=currNewRank)
    00140             *ivIt += 1;
    00141         }
    00142         // increment both thie current rank *and* the maximum new rank
    00143         ++currNewRank;
    00144         ++maxNewRank;
    00145       }
    00146
    00147       //
    00148       //  now grab all entries with this new rank and copy them into
    00149       //  the ranks list
    00150       //
    00151       ivIt=std::find(newRanks.begin(),newRanks.end(),currNewRank);
    00152       while(ivIt!=newRanks.end()){
    00153         int offset=ivIt-newRanks.begin();
    00154         int idx = idxVect[offset];
    00155         ranks[idx] = currNewRank;
    00156         ivIt++;
    00157         ivIt=std::find(ivIt,newRanks.end(),currNewRank);
    00158       }
    00159       ++currNewRank;
    00160     }
    00161   }
    00162 }
    00163 #endif