00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef TRANSVERSAL_H_
00034 #define TRANSVERSAL_H_
00035
00036 #include "sorter/base_sorter.h"
00037 #include "transversal/orbit.h"
00038
00039 #include <map>
00040 #include <list>
00041 #include <vector>
00042
00043 #include <boost/foreach.hpp>
00044 #include <boost/shared_ptr.hpp>
00045
00046 namespace permlib {
00047
00048 template <class PERM>
00049 class Transversal;
00050
00051 template <class PERM>
00052 std::ostream &operator<< (std::ostream &out, const Transversal<PERM> &t) {
00053 out << "{";
00054 BOOST_FOREACH (boost::shared_ptr<PERM> p, t.m_transversal) {
00055 if (p)
00056 out << *p << ", ";
00057 else
00058 out << "O, ";
00059 }
00060 out << "}";
00061 return out;
00062 }
00063
00065 template <class PERM>
00066 class Transversal : public Orbit<PERM,ulong> {
00067 public:
00069
00072 Transversal(uint n);
00074 virtual ~Transversal() {}
00075
00077 virtual PERM* at(ulong val) const = 0;
00078
00080 virtual bool trivialByDefinition(const PERM& x, ulong to) const = 0;
00081
00083 virtual bool contains(const ulong& val) const;
00084
00086 std::list<ulong>::const_iterator begin() const { return this->m_orbit.begin(); };
00088 std::list<ulong>::const_iterator end() const { return this->m_orbit.end(); };
00089
00091 uint size() const { return this->m_orbit.size(); }
00092
00094 inline uint n() const { return m_n; }
00095
00097
00101 template <class InputIterator>
00102 void sort(InputIterator Bbegin, InputIterator Bend);
00103
00105 inline bool sorted() const { return m_sorted; }
00106
00108 struct TrivialAction {
00110 ulong operator()(const PERM &p, ulong v) const {
00111 return p / v;
00112 }
00113 };
00114
00116
00120 virtual void orbit(ulong alpha, const PERMlist &generators);
00122
00127 virtual void orbitUpdate(ulong alpha, const PERMlist &generators, const PERMptr &g);
00128
00130
00134 virtual void permute(const PERM& g, const PERM& gInv);
00136
00139 virtual void updateGenerators(const std::map<PERM*,PERMptr>& generatorChange) {}
00140
00141 virtual const ulong& element() const;
00142
00144 friend std::ostream &operator<< <> (std::ostream &out, const Transversal<PERM> &p);
00145 protected:
00147 uint m_n;
00148
00150 std::vector<boost::shared_ptr<PERM> > m_transversal;
00151
00153 std::list<ulong> m_orbit;
00154
00156 bool m_sorted;
00157
00159 virtual void registerMove(ulong from, ulong to, const PERMptr &p);
00160
00161 virtual bool foundOrbitElement(const ulong& alpha, const ulong& alpha_p, const PERMptr& p);
00162 };
00163
00164
00165
00166
00167
00168 template <class PERM>
00169 Transversal<PERM>::Transversal(uint n)
00170 : m_n(n), m_transversal(n), m_sorted(false)
00171 { }
00172
00173 template <class PERM>
00174 void Transversal<PERM>::orbit(ulong beta, const PERMlist &generators) {
00175 return Orbit<PERM,ulong>::orbit(beta, generators, TrivialAction(), m_orbit);
00176 }
00177
00178 template <class PERM>
00179 void Transversal<PERM>::orbitUpdate(ulong beta, const PERMlist &generators, const PERMptr &g) {
00180 return Orbit<PERM,ulong>::orbitUpdate(beta, generators, g, TrivialAction(), m_orbit);
00181 }
00182
00183 template <class PERM>
00184 bool Transversal<PERM>::foundOrbitElement(const ulong& alpha, const ulong& alpha_p, const PERMptr& p) {
00185 if (!m_transversal[alpha_p]) {
00186 if (!p) {
00187 PERMptr identity(new PERM(m_n));
00188 registerMove(alpha, alpha_p, identity);
00189 } else {
00190 registerMove(alpha, alpha_p, p);
00191 }
00192 return true;
00193 }
00194 return false;
00195 }
00196
00197 template <class PERM>
00198 bool Transversal<PERM>::contains(const ulong& val) const {
00199 return m_transversal[val] != 0;
00200 }
00201
00202 template <class PERM>
00203 void Transversal<PERM>::registerMove(ulong from, ulong to, const PERMptr &p) {
00204 m_sorted = false;
00205 }
00206
00207
00208 template <class PERM>
00209 template <class InputIterator>
00210 void Transversal<PERM>::sort(InputIterator Bbegin, InputIterator Bend) {
00211 this->m_orbit.sort(BaseSorter(m_n, Bbegin, Bend));
00212 m_sorted = true;
00213 }
00214
00215 template <class PERM>
00216 void Transversal<PERM>::permute(const PERM& g, const PERM& gInv) {
00217 std::vector<boost::shared_ptr<PERM> > temp(m_n);
00218 for (ulong i=0; i<m_n; ++i) {
00219 const ulong j = g / i;
00220 temp[j] = m_transversal[i];
00221 }
00222 std::copy(temp.begin(), temp.end(), m_transversal.begin());
00223 BOOST_FOREACH(ulong& alpha, this->m_orbit) {
00224 alpha = g / alpha;
00225 }
00226 m_sorted = false;
00227 }
00228
00229 template <class PERM>
00230 inline const ulong& Transversal<PERM>::element() const {
00231 return m_orbit.front();
00232 }
00233
00234 }
00235
00236 #endif // -- TRANSVERSAL_H_