PermLib
|
00001 // --------------------------------------------------------------------------- 00002 // 00003 // This file is part of PermLib. 00004 // 00005 // Copyright (c) 2009-2011 Thomas Rehn <thomas@carmen76.de> 00006 // All rights reserved. 00007 // 00008 // Redistribution and use in source and binary forms, with or without 00009 // modification, are permitted provided that the following conditions 00010 // are met: 00011 // 1. Redistributions of source code must retain the above copyright 00012 // notice, this list of conditions and the following disclaimer. 00013 // 2. Redistributions in binary form must reproduce the above copyright 00014 // notice, this list of conditions and the following disclaimer in the 00015 // documentation and/or other materials provided with the distribution. 00016 // 3. The name of the author may not be used to endorse or promote products 00017 // derived from this software without specific prior written permission. 00018 // 00019 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 00020 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00021 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 00022 // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 00023 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 00024 // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00025 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00026 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00027 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 00028 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 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(dom_int n); 00051 protected: 00053 dom_int 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<std::list<typename PERM::ptr> > &S) const; 00066 00068 void mergeGenerators(std::vector<std::list<typename PERM::ptr> >& S, BSGS<PERM,TRANS>& ret) const; 00069 00071 static const unsigned long *empty; 00072 }; 00073 00074 // 00075 // ---- IMPLEMENTATION 00076 // 00077 00078 template <class PERM, class TRANS> 00079 const unsigned long *BaseConstruction<PERM, TRANS>::empty = static_cast<unsigned long*>(0); 00080 00081 00082 template <class PERM, class TRANS> 00083 BaseConstruction<PERM,TRANS>::BaseConstruction(dom_int 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<std::list<typename PERM::ptr> > &S) const 00090 { 00091 std::vector<dom_int> &B = bsgs.B; 00092 std::vector<TRANS> &U = bsgs.U; 00093 00094 B.insert(B.begin(), prescribedBaseBegin, prescribedBaseEnd); 00095 // extend base so that no group element fixes all base elements 00096 dom_int beta = m_n + 1; 00097 PointwiseStabilizerPredicate<PERM> stab_k(B.begin(), B.end()); 00098 for (ForwardIterator genIt = generatorsBegin ; genIt != generatorsEnd; ++genIt) { 00099 const typename PERM::ptr &gen = *genIt; 00100 if (stab_k(gen)) { 00101 if (bsgs.chooseBaseElement(*gen, beta)) { 00102 B.push_back(beta); 00103 stab_k = PointwiseStabilizerPredicate<PERM>(B.begin(), B.end()); 00104 } 00105 } 00106 } 00107 00108 if (B.empty()) { 00109 B.push_back(0); 00110 U.push_back(TRANS(m_n)); 00111 // the trivial group has an empty generator list 00112 std::list<typename PERM::ptr> S_0; 00113 S.push_back(S_0); 00114 U[0].orbit(B[0], S_0); 00115 return; 00116 } 00117 S.reserve(B.size()); 00118 00119 // pre-compute transversals and fundamental orbits for the current base 00120 unsigned int i = 0; 00121 std::vector<dom_int>::iterator Bit; 00122 for (Bit = B.begin(); Bit != B.end(); ++Bit) { 00123 std::list<typename PERM::ptr> S_i; 00124 std::copy_if(generatorsBegin, generatorsEnd, 00125 std::back_inserter(S_i), PointwiseStabilizerPredicate<PERM>(B.begin(), Bit)); 00126 00127 U.push_back(TRANS(m_n)); 00128 S.push_back(S_i); 00129 00130 bsgs.orbit(i, S_i); 00131 00132 ++i; 00133 } 00134 } 00135 00136 template <class PERM, class TRANS> 00137 void BaseConstruction<PERM,TRANS>::mergeGenerators(std::vector<std::list<typename PERM::ptr> >& S, BSGS<PERM,TRANS>& ret) const { 00138 std::map<PERM*,typename PERM::ptr> generatorMap; 00139 // merge all generators into one list 00140 BOOST_FOREACH(std::list<typename PERM::ptr> &S_j, S) { 00141 BOOST_FOREACH(typename PERM::ptr &gen, S_j) { 00142 bool found = false; 00143 BOOST_FOREACH(const typename PERM::ptr& genS, ret.S) { 00144 if (*genS == *gen) { 00145 found = true; 00146 generatorMap.insert(std::make_pair(gen.get(), genS)); 00147 break; 00148 } 00149 } 00150 if (!found) { 00151 ret.S.push_back(gen); 00152 generatorMap.insert(std::make_pair(gen.get(), gen)); 00153 } 00154 } 00155 } 00156 00157 BOOST_FOREACH(TRANS& U_i, ret.U) { 00158 U_i.updateGenerators(generatorMap); 00159 } 00160 } 00161 00162 } 00163 00164 #endif // -- BASECONSTRUCTION_H