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 BASECONSTRUCTION_H
00034 #define BASECONSTRUCTION_H
00035
00036 #include <map>
00037
00038 #include <permlib/predicate/pointwise_stabilizer_predicate.h>
00039
00040 namespace permlib {
00041
00043 template <class PERM, class TRANS>
00044 class BaseConstruction {
00045 public:
00047
00050 explicit BaseConstruction(uint n);
00051 protected:
00053 uint m_n;
00054
00056
00064 template <class ForwardIterator, class InputIterator>
00065 void setup(ForwardIterator generatorsBegin, ForwardIterator generatorsEnd, InputIterator prescribedBaseBegin, InputIterator prescribedBaseEnd, BSGS<PERM, TRANS> &bsgs, std::vector<PERMlist> &S) const;
00066
00068 void mergeGenerators(std::vector<PERMlist>& S, BSGS<PERM,TRANS>& ret) const;
00069
00071 static const ulong *empty;
00072 };
00073
00074
00075
00076
00077
00078 template <class PERM, class TRANS>
00079 const ulong *BaseConstruction<PERM, TRANS>::empty = static_cast<ulong*>(0);
00080
00081
00082 template <class PERM, class TRANS>
00083 BaseConstruction<PERM,TRANS>::BaseConstruction(uint n)
00084 : m_n(n)
00085 { }
00086
00087 template <class PERM, class TRANS>
00088 template <class ForwardIterator, class InputIterator>
00089 void BaseConstruction<PERM,TRANS>::setup(ForwardIterator generatorsBegin, ForwardIterator generatorsEnd, InputIterator prescribedBaseBegin, InputIterator prescribedBaseEnd, BSGS<PERM, TRANS> &bsgs, std::vector<PERMlist> &S) const
00090 {
00091 std::vector<ulong> &B = bsgs.B;
00092 std::vector<TRANS> &U = bsgs.U;
00093
00094 B.insert(B.begin(), prescribedBaseBegin, prescribedBaseEnd);
00095
00096
00097 ulong beta = m_n + 1;
00098 PointwiseStabilizerPredicate<PERM> stab_k(B.begin(), B.end());
00099 for (ForwardIterator genIt = generatorsBegin ; genIt != generatorsEnd; ++genIt) {
00100 const PERMptr &gen = *genIt;
00101 if (stab_k(gen)) {
00102 if (bsgs.chooseBaseElement(*gen, beta)) {
00103 B.push_back(beta);
00104 stab_k = PointwiseStabilizerPredicate<PERM>(B.begin(), B.end());
00105 }
00106 }
00107 }
00108 BOOST_ASSERT(!B.empty());
00109
00110
00111 uint i = 0;
00112 std::vector<ulong>::iterator Bit;
00113 for (Bit = B.begin(); Bit != B.end(); ++Bit) {
00114 PERMlist S_i;
00115 std::copy_if(generatorsBegin, generatorsEnd,
00116 std::back_inserter(S_i), PointwiseStabilizerPredicate<PERM>(B.begin(), Bit));
00117
00118 U.push_back(TRANS(m_n));
00119 S.push_back(S_i);
00120
00121 bsgs.orbit(i, S_i);
00122
00123 ++i;
00124 }
00125 }
00126
00127 template <class PERM, class TRANS>
00128 void BaseConstruction<PERM,TRANS>::mergeGenerators(std::vector<PERMlist>& S, BSGS<PERM,TRANS>& ret) const {
00129 std::map<PERM*,PERMptr> generatorMap;
00130
00131 BOOST_FOREACH(PERMlist &S_j, S) {
00132 BOOST_FOREACH(PERMptr &gen, S_j) {
00133 bool found = false;
00134 BOOST_FOREACH(const PERMptr& genS, ret.S) {
00135 if (*genS == *gen) {
00136 found = true;
00137 generatorMap.insert(std::make_pair(gen.get(), genS));
00138 break;
00139 }
00140 }
00141 if (!found) {
00142 ret.S.push_back(gen);
00143 generatorMap.insert(std::make_pair(gen.get(), gen));
00144 }
00145 }
00146 }
00147 BOOST_FOREACH(TRANS& U_i, ret.U) {
00148 U_i.updateGenerators(generatorMap);
00149 }
00150 }
00151
00152 }
00153
00154 #endif // -- BASECONSTRUCTION_H