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 BASETRANSPOSE_H_
00034 #define BASETRANSPOSE_H_
00035
00036 #include <permlib/predicate/pointwise_stabilizer_predicate.h>
00037 #include <permlib/generator/generator.h>
00038
00039 #include <boost/scoped_ptr.hpp>
00040 #include <boost/iterator/indirect_iterator.hpp>
00041
00042 namespace permlib {
00043
00045
00048 template<class PERM, class TRANS>
00049 class BaseTranspose {
00050 public:
00052 BaseTranspose();
00054 virtual ~BaseTranspose() {}
00055
00057
00061 void transpose(BSGS<PERM,TRANS> &bsgs, uint i) const;
00062
00064 mutable uint m_statScheierGeneratorsConsidered;
00066 mutable uint m_statNewGenerators;
00067 protected:
00069
00075 virtual Generator<PERM>* setupGenerator(BSGS<PERM,TRANS> &bsgs, uint i, const PERMlist &S_i, const TRANS &U_i) const = 0;
00076 };
00077
00078
00079
00080
00081
00082 template<class PERM, class TRANS>
00083 BaseTranspose<PERM,TRANS>::BaseTranspose()
00084 : m_statScheierGeneratorsConsidered(0), m_statNewGenerators(0)
00085 { }
00086
00087 template<class PERM, class TRANS>
00088 void BaseTranspose<PERM,TRANS>::transpose(BSGS<PERM,TRANS> &bsgs, uint i) const {
00089 std::vector<ulong> &B = bsgs.B;
00090 std::vector<TRANS> &U = bsgs.U;
00091
00092 if (i+1 >= B.size())
00093
00094 return;
00095
00096 PERMlist S_i;
00097 std::copy_if(bsgs.S.begin(), bsgs.S.end(), std::back_inserter(S_i), PointwiseStabilizerPredicate<PERM>(B.begin(), B.begin() + i));
00098
00099 std::swap(B[i], B[i+1]);
00100
00101 PERMlist S_i1;
00102 std::copy_if(bsgs.S.begin(), bsgs.S.end(), std::back_inserter(S_i1), PointwiseStabilizerPredicate<PERM>(B.begin(), B.begin() + (i+1)));
00103
00104 uint targetTransversalSize = U[i+1].size() * U[i].size();
00105
00106
00107 TRANS U_i(U[i].n());
00108 U_i.orbit(B[i], S_i);
00109 targetTransversalSize /= U_i.size();
00110
00111 m_statScheierGeneratorsConsidered = 0;
00112 m_statNewGenerators = 0;
00113 TRANS U_i1(U[i+1].n());
00114 U_i1.orbit(B[i+1], S_i1);
00115 boost::scoped_ptr<Generator<PERM> > generator(setupGenerator(bsgs, i, S_i, U_i));
00116 BOOST_ASSERT(generator != 0);
00117
00118 while (U_i1.size() < targetTransversalSize) {
00119 bool newGeneratorFound = false;
00120 while (generator->hasNext()) {
00121 PERM g = generator->next();
00122 ++m_statScheierGeneratorsConsidered;
00123 boost::indirect_iterator<typename PERMlist::iterator> sBegin(S_i1.begin()), sEnd(S_i1.end());
00124 if (!U_i1.contains(g / B[i+1]) && std::find(sBegin, sEnd, g) == sEnd) {
00125 g.flush();
00126 boost::shared_ptr<PERM> gen(new PERM(g));
00127 S_i1.push_front(gen);
00128 ++m_statNewGenerators;
00129 U_i1.orbitUpdate(B[i+1], S_i1, gen);
00130 newGeneratorFound = true;
00131 break;
00132 }
00133 }
00134 if (!newGeneratorFound)
00135
00136 break;
00137 }
00138 BOOST_ASSERT(U_i1.size() >= targetTransversalSize);
00139
00140 bsgs.S.insert(bsgs.S.end(), S_i1.begin(), boost::next(S_i1.begin(), m_statNewGenerators));
00141 U[i] = U_i;
00142 U[i+1] = U_i1;
00143 }
00144
00145 }
00146
00147 #endif // -- BASETRANSPOSE_H_