Share Pastebin
Guest
Public paste!

timvdm

By: a guest | Sep 29th, 2009 | Syntax: None | Size: 5.14 KB | Hits: 185 | Expires: Never
Copy text to clipboard
  1. #ifndef OB_PERMUTATION_H
  2. #define OB_PERMUTATION_H
  3.  
  4. #include <map>
  5. #include <vector>
  6.  
  7. #include <Eigen/Core>
  8.  
  9. namespace OpenBabel {
  10.  
  11.   struct Permutation
  12.   {
  13.     /**
  14.      * Default constructor.
  15.      */
  16.     Permutation()
  17.     {}
  18.  
  19.     /**
  20.      * Constructor taking a @p map as argument.
  21.      */
  22.     Permutation(const std::vector<unsigned int> &_map) : map(_map)
  23.     {}
  24.  
  25.     /**
  26.      * Constructor taking a @p matrix as argument.
  27.      */
  28.     Permutation(const Eigen::MatrixXi &matrix)
  29.     {
  30.       setMatrix(matrix);
  31.     }
  32.  
  33.     /**
  34.      * Copy constructor.
  35.      */
  36.     Permutation(const Permutation &other)
  37.     {
  38.       this->map = other.map;
  39.     }
  40.  
  41.     /**
  42.      * Print the permutation to std::cout in shortened notation.
  43.      */
  44.     void print() const
  45.     {
  46.       std::vector<unsigned int>::const_iterator i;
  47.       for (i = map.begin(); i != map.end(); ++i)
  48.         std::cout << *i << " ";
  49.       std::cout << std::endl;    
  50.     }
  51.  
  52.     Permutation apply(const Permutation &input) const
  53.     {
  54.       Permutation p;
  55.       if (input.map.size() != map.size())
  56.         return p;
  57.       p.map.resize(map.size());
  58.  
  59.       unsigned int index = 0;
  60.       std::vector<unsigned int>::const_iterator i;
  61.       for (i = map.begin(); i != map.end(); ++i, ++index) {
  62.         p.map[index] = input.map.at(*i-1);
  63.       }
  64.  
  65.       return p;  
  66.     }
  67.  
  68.     /**
  69.      * Compute the permutation matrix for this Permutation.
  70.      */
  71.     Eigen::MatrixXi matrix() const
  72.     {
  73.       int n = map.size();
  74.       Eigen::MatrixXi P = Eigen::MatrixXi::Zero(n, n);
  75.  
  76.       for (int i = 0; i < n; ++i) {
  77.         //P(map.at(i)-1, i) = 1;
  78.         P(i, map.at(i)-1) = 1;
  79.       }
  80.  
  81.       return P;
  82.     }
  83.  
  84.     /**
  85.      * Set the permutation matrix for this permutation. The matrix is
  86.      * converted to a shortened notation permutation.
  87.      */
  88.     void setMatrix(const Eigen::MatrixXi &m)
  89.     {
  90.       if (m.rows() != m.cols())
  91.         return;
  92.  
  93.       int size = m.rows();
  94.       map.resize(size);
  95.  
  96.       for (int i = 0; i < size; ++i)
  97.         for (int j = 0; j < size; ++j) {
  98.           if (m(i,j))
  99.             map[i] = j + 1;
  100.         }
  101.     }
  102.  
  103.     unsigned long NumInversions() const
  104.     {
  105.       std::vector<unsigned int> invVec; // the inversion vector
  106.       std::vector<unsigned int>::const_iterator i, j;
  107.       for (i = map.begin(); i != map.end(); ++i) {
  108.         int e = 0; // ith element
  109.         // loop over elements to the right
  110.         for (j = i; j != map.end(); ++j)
  111.           // increment e if element to the right is lower
  112.           if (*j < *i)
  113.             e++;
  114.  
  115.         invVec.push_back(e);
  116.       }
  117.  
  118.       unsigned long sum = 0;
  119.       for (std::vector<unsigned int>::iterator k = invVec.begin(); k != invVec.end(); ++k)
  120.         sum += *k;
  121.  
  122.       return sum;
  123.     }
  124.  
  125.  
  126.     /**
  127.      * Multiply two permutation matrices and return the resulting permutation.
  128.      * This is the same as applying the two permutations consecutively.
  129.      */
  130.     Permutation operator*(const Permutation &rhs) const
  131.     {
  132.       return apply(rhs);
  133.     }
  134.  
  135.     /**
  136.      * Equality operator. Two permutations are equal if their shortened notations
  137.      * are the same (compared element-by-element).
  138.      */
  139.     bool operator==(const Permutation &rhs) const
  140.     {
  141.       if (map.size() != rhs.map.size())
  142.         return false;
  143.  
  144.       std::vector<unsigned int>::const_iterator i1 = map.begin();
  145.       std::vector<unsigned int>::const_iterator i2 = rhs.map.begin();
  146.       for (; i1 != map.end(); ++i1, ++i2)
  147.         if (*i1 != *i2)
  148.           return false;
  149.  
  150.       return true;  
  151.     }
  152.  
  153.     std::vector<unsigned int> map; //!< The actual mapping in shortened notation
  154.   };
  155.  
  156.   struct PermutationGroup
  157.   {
  158.     /**
  159.      * Default constructor.
  160.      */
  161.     PermutationGroup()
  162.     {}
  163.  
  164.     /**
  165.      * Constructor taking vector of permutations as argument.
  166.      */
  167.     PermutationGroup(const std::vector<Permutation> &_permutations) : permutations(_permutations)
  168.     {}
  169.  
  170.     /**
  171.      * @return The number of permutations in this group.
  172.      */
  173.     unsigned int size() const
  174.     {
  175.       return permutations.size();
  176.     }
  177.  
  178.     /**
  179.      * Add permutation @p p to this permutation group.
  180.      */
  181.     void add(const Permutation &p)
  182.     {
  183.       permutations.push_back(p);
  184.       //invIndexes.push_back(p.NumInversions());
  185.     }
  186.  
  187.     /**
  188.      * @return A constant reference to the @p index-th permutation.
  189.      */
  190.     const Permutation& at(unsigned int index)
  191.     {
  192.       return permutations.at(index);
  193.     }
  194.  
  195.     /**
  196.      * @return True if this permutation group contains permutation @p p.
  197.      */
  198.     bool contains(const Permutation &p) const
  199.     {
  200.       //if (std::find(invIndexes.begin(), invIndexes.end(), p.NumInversions()) != invIndexes.end())
  201.       //  return true;
  202.       std::vector<Permutation>::const_iterator i;
  203.       for (i = permutations.begin(); i != permutations.end(); ++i)
  204.         if (*i == p)
  205.           return true;
  206.       return false;
  207.     }
  208.  
  209.     std::vector<Permutation> permutations; //!< The actual permutations in the group
  210.     //std::vector<unsigned long> invIndexes; //!< The inversion indexes
  211.   };
  212.  
  213. } // namespace
  214.  
  215. #endif