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 00096 // extend base so that no group element fixes all base elements 00097 dom_int beta = m_n + 1; 00098 PointwiseStabilizerPredicate<PERM> stab_k(B.begin(), B.end()); 00099 for (ForwardIterator genIt = generatorsBegin ; genIt != generatorsEnd; ++genIt) { 00100 const typename PERM::ptr &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 // pre-compute transversals and fundamental orbits for the current base 00111 unsigned int i = 0; 00112 std::vector<dom_int>::iterator Bit; 00113 for (Bit = B.begin(); Bit != B.end(); ++Bit) { 00114 std::list<typename PERM::ptr> 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<std::list<typename PERM::ptr> >& S, BSGS<PERM,TRANS>& ret) const { 00129 std::map<PERM*,typename PERM::ptr> generatorMap; 00130 // merge all generators into one list 00131 BOOST_FOREACH(std::list<typename PERM::ptr> &S_j, S) { 00132 BOOST_FOREACH(typename PERM::ptr &gen, S_j) { 00133 bool found = false; 00134 BOOST_FOREACH(const typename PERM::ptr& 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