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 SHALLOWSCHREIERTREETRANSVERSAL_H_
00034 #define SHALLOWSCHREIERTREETRANSVERSAL_H_
00035
00036 #include <permlib/transversal/schreier_tree_transversal.h>
00037
00038 #include <boost/scoped_ptr.hpp>
00039 #include <boost/dynamic_bitset.hpp>
00040
00041 namespace permlib {
00042
00044 template <class PERM>
00045 class ShallowSchreierTreeTransversal : public SchreierTreeTransversal<PERM> {
00046 public:
00048 ShallowSchreierTreeTransversal(unsigned int n);
00049
00050 virtual void orbit(ulong beta, const PERMlist &generators);
00051 virtual void orbitUpdate(ulong alpha, const PERMlist &generators, const PERMptr &g);
00052
00053 virtual void updateGenerators(const std::map<PERM*,PERMptr>& generatorChange);
00055
00059 ShallowSchreierTreeTransversal<PERM> clone(const std::map<PERM*,PERMptr>& generatorChange) const;
00060
00061 virtual void permute(const PERM& g, const PERM& gInv);
00062 protected:
00064 PERMlist m_cubeLabels;
00065
00067 void addNewCubeLabel(ulong beta, const PERM &s, const ulong &beta_prime);
00068 };
00069
00070
00071
00072
00073
00074 template <class PERM>
00075 ShallowSchreierTreeTransversal<PERM>::ShallowSchreierTreeTransversal(unsigned int n)
00076 : SchreierTreeTransversal<PERM>(n)
00077 { }
00078
00079 template <class PERM>
00080 void ShallowSchreierTreeTransversal<PERM>::orbitUpdate(ulong beta, const PERMlist &generators, const PERMptr &g) {
00081 this->orbit(beta, generators);
00082 }
00083
00084 template <class PERM>
00085 void ShallowSchreierTreeTransversal<PERM>::orbit(ulong beta, const PERMlist &generators) {
00086 const ulong &n = Transversal<PERM>::m_n;
00087 std::vector<boost::shared_ptr<PERM> > &transversal = Transversal<PERM>::m_transversal;
00088
00089 if (Transversal<PERM>::size() == 0) {
00090 Transversal<PERM>::m_orbit.push_back(beta);
00091 boost::shared_ptr<PERM> identity(new PERM(n));
00092 transversal[beta] = identity;
00093 }
00094
00095 typename std::list<ulong>::const_iterator it;
00096
00097 PERM g(n);
00098 typename PERMlist::const_iterator genIt = generators.begin();
00099 for (it = Transversal<PERM>::m_orbit.begin(); it != Transversal<PERM>::m_orbit.end(); ++it) {
00100 for (genIt = generators.begin(); genIt != generators.end(); ++genIt) {
00101 const ulong &beta_prime = *it;
00102 if (!transversal[**genIt / beta_prime]) {
00103 addNewCubeLabel(beta, **genIt, beta_prime);
00104 }
00105 }
00106 }
00107 }
00108
00109 template <class PERM>
00110 void ShallowSchreierTreeTransversal<PERM>::addNewCubeLabel(ulong beta, const PERM &s, const ulong &beta_prime) {
00111 std::vector<boost::shared_ptr<PERM> > &transversal = Transversal<PERM>::m_transversal;
00112 boost::shared_ptr<PERM> gPath(SchreierTreeTransversal<PERM>::at(beta_prime));
00113 *gPath *= s;
00114
00115 gPath->flush();
00116
00117
00118
00119 std::list<ulong> tempOrbit;
00120 typename std::list<ulong>::const_iterator orbIt = Transversal<PERM>::m_orbit.begin();
00121 for (; orbIt != Transversal<PERM>::m_orbit.end(); ++orbIt) {
00122 const ulong alpha = *gPath / *orbIt;
00123
00124
00125 if (!transversal[alpha]) {
00126 transversal[alpha] = gPath;
00127 tempOrbit.push_back(alpha);
00128 }
00129 }
00130 Transversal<PERM>::m_orbit.splice(Transversal<PERM>::m_orbit.end(), tempOrbit);
00131
00132 m_cubeLabels.push_back(gPath);
00133
00134 boost::shared_ptr<PERM> gPathInv(new PERM(*gPath));
00135 gPathInv->invertInplace();
00136
00137
00138
00139
00140 ulong beta1 = *gPathInv / beta;
00141 if (!transversal[beta1]) {
00142 transversal[beta1] = gPathInv;
00143 Transversal<PERM>::m_orbit.push_back(beta1);
00144 }
00145
00146 const ulong &n = Transversal<PERM>::m_n;
00147 boost::dynamic_bitset<> omega(n);
00148 boost::dynamic_bitset<> todo(n);
00149 ulong i;
00150 omega[beta1] = 1;
00151 BOOST_FOREACH(const PERMptr& l, m_cubeLabels) {
00152 for (i = 0; i < n; ++i) {
00153 if (!omega[i])
00154 continue;
00155 ulong alpha = *l / i;
00156 todo[alpha] = 1;
00157 if (!transversal[alpha]) {
00158 transversal[alpha] = l;
00159 Transversal<PERM>::m_orbit.push_back(alpha);
00160 }
00161 }
00162 omega |= todo;
00163 }
00164
00165 m_cubeLabels.push_front(gPathInv);
00166 }
00167
00168 template <class PERM>
00169 void ShallowSchreierTreeTransversal<PERM>::updateGenerators(const std::map<PERM*,PERMptr>& generatorChange) {
00170 }
00171
00172 template <class PERM>
00173 ShallowSchreierTreeTransversal<PERM> ShallowSchreierTreeTransversal<PERM>::clone(const std::map<PERM*,PERMptr>& generatorChange) const {
00174 ShallowSchreierTreeTransversal<PERM> ret(*this);
00175 std::map<PERM*,PERMptr> labelMap;
00176 BOOST_FOREACH(PERMptr& p, ret.m_cubeLabels) {
00177 PERM* gen = p.get();
00178 p = PERMptr(new PERM(*p));
00179 labelMap.insert(std::make_pair(gen, p));
00180 }
00181 ret.SchreierTreeTransversal<PERM>::updateGenerators(labelMap);
00182 return ret;
00183 }
00184
00185 template <class PERM>
00186 void ShallowSchreierTreeTransversal<PERM>::permute(const PERM& g, const PERM& gInv) {
00187 Transversal<PERM>::permute(g, gInv);
00188 BOOST_FOREACH(PERMptr& p, m_cubeLabels) {
00189 *p ^= gInv;
00190 *p *= g;
00191 p->flush();
00192 }
00193 }
00194
00195 }
00196
00197 #endif // -- SHALLOWSCHREIERTREETRANSVERSAL_H_