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 SCHREIERSIMSCONSTRUCTION_H_
00034 #define SCHREIERSIMSCONSTRUCTION_H_
00035
00036 #include "construct/base_construction.h"
00037 #include "bsgs.h"
00038 #include "generator/schreier_generator.h"
00039
00040 #include <boost/foreach.hpp>
00041
00042 namespace permlib {
00043
00045 template <class PERM, class TRANS>
00046 class SchreierSimsConstruction : public BaseConstruction<PERM, TRANS> {
00047 public:
00049
00052 explicit SchreierSimsConstruction(uint n);
00053
00055
00057 template <class ForwardIterator>
00058 BSGS<PERM, TRANS> construct(ForwardIterator generatorsBegin, ForwardIterator generatorsEnd) const;
00059
00061
00067 template <class ForwardIterator, class InputIterator>
00068 BSGS<PERM, TRANS> construct(ForwardIterator generatorsBegin, ForwardIterator generatorsEnd, InputIterator prescribedBaseBegin, InputIterator prescribedBaseEnd) const;
00069
00071 mutable uint m_statScheierGeneratorsConsidered;
00072 };
00073
00074
00075
00076
00077
00078 template <class PERM, class TRANS>
00079 SchreierSimsConstruction<PERM,TRANS>::SchreierSimsConstruction(uint n)
00080 : BaseConstruction<PERM, TRANS>(n), m_statScheierGeneratorsConsidered(0)
00081 { }
00082
00083 template <class PERM, class TRANS>
00084 template <class ForwardIterator>
00085 inline BSGS<PERM, TRANS> SchreierSimsConstruction<PERM,TRANS>::construct(ForwardIterator generatorsBegin, ForwardIterator generatorsEnd) const {
00086 return construct(generatorsBegin, generatorsEnd, BaseConstruction<PERM,TRANS>::empty, BaseConstruction<PERM,TRANS>::empty);
00087 }
00088
00089 template <class PERM, class TRANS>
00090 template <class ForwardIterator, class InputIterator>
00091 BSGS<PERM, TRANS> SchreierSimsConstruction<PERM, TRANS>
00092 ::construct(ForwardIterator generatorsBegin, ForwardIterator generatorsEnd, InputIterator prescribedBaseBegin, InputIterator prescribedBaseEnd) const
00093 {
00094 const uint &n = BaseConstruction<PERM, TRANS>::m_n;
00095 BSGS<PERM, TRANS> ret(n);
00096 std::vector<ulong> &B = ret.B;
00097 std::vector<TRANS> &U = ret.U;
00098 std::vector<PERMlist> S;
00099 setup(generatorsBegin, generatorsEnd, prescribedBaseBegin, prescribedBaseEnd, ret, S);
00100
00101 std::vector<boost::shared_ptr<SchreierGenerator<PERM, TRANS> > > SchreierGens;
00102 SchreierGens.push_back(boost::shared_ptr<SchreierGenerator<PERM, TRANS> >(new SchreierGenerator<PERM, TRANS>(&U[0], S[0].begin(), S[0].end())));
00103
00104 uint j = 1;
00105 bool breakUp = false;
00106 while (j >= 1) {
00107 breakUp = false;
00108 SchreierGenerator<PERM, TRANS> &sg = *SchreierGens[j-1];
00109 sg.update(&U[j-1], S[j-1].begin(), S[j-1].end());
00110
00111 while (sg.hasNext()) {
00112 ++m_statScheierGeneratorsConsidered;
00113 DEBUG(for(uint jjj=0; jjj<j; ++jjj) std::cout << " ";)
00114 DEBUG(std::cout << "schreier j = " << (j-1) << " [" << S[j-1].size() << "," << U[j-1].size() << "]: ";)
00115 PERM g = sg.next();
00116 PERM h(n);
00117
00118 uint k = ret.sift(g, h, j);
00119 if (k < B.size() - j || !h.isIdentity()) {
00120
00121 h.flush();
00122
00123 if (j == B.size()) {
00124 ulong gamma = n+1;
00125 if (ret.chooseBaseElement(h, gamma)) {
00126 B.push_back(gamma);
00127 }
00128 BOOST_ASSERT(j < B.size());
00129 S.push_back(PERMlist());
00130 U.push_back(TRANS(n));
00131 }
00132 boost::shared_ptr<PERM> hPtr(new PERM(h));
00133 S[j].insert(S[j].end(), hPtr);
00134
00135 ret.orbitUpdate(j, S[j], hPtr);
00136 if (j >= SchreierGens.size()) {
00137 boost::shared_ptr<SchreierGenerator<PERM, TRANS> > localVar(new SchreierGenerator<PERM, TRANS>(&U[j], S[j].begin(), S[j].end()));
00138 SchreierGens.push_back(localVar);
00139 } else {
00140 SchreierGens[j]->update(S[j].size() - 1);
00141 }
00142
00143 breakUp = true;
00144 ++j;
00145 break;
00146 }
00147 }
00148 if (!breakUp)
00149 --j;
00150 }
00151
00152 mergeGenerators(S, ret);
00153
00154 return ret;
00155 }
00156
00157 }
00158
00159 #endif // -- SCHREIERSIMSCONSTRUCTION_H_