PermLib

permlib_api.h

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 #ifndef PERMLIB_API_H
00033 #define PERMLIB_API_H
00034 
00035 #include <permlib/permutation.h>
00036 #include <permlib/bsgs.h>
00037 #include <permlib/transversal/schreier_tree_transversal.h>
00038 #include <permlib/transversal/orbit_set.h>
00039 #include <permlib/construct/schreier_sims_construction.h>
00040 #include <permlib/change/conjugating_base_change.h>
00041 #include <permlib/search/classic/set_stabilizer_search.h>
00042 #include <permlib/search/classic/set_image_search.h>
00043 #include <permlib/search/orbit_lex_min_search.h>
00044 
00045 #include <boost/shared_ptr.hpp>
00046 #include <boost/iterator/counting_iterator.hpp>
00047 
00048 namespace permlib {
00049 
00050 // ---------------------------------------------------------------------
00051 // useful type definitions
00052 //
00053 
00054 typedef Permutation PERMUTATION;
00055 typedef SchreierTreeTransversal<PERMUTATION> TRANSVERSAL;
00056 typedef BSGS<PERMUTATION,TRANSVERSAL> PermutationGroup;
00057 typedef OrbitSet<PERMUTATION,unsigned long> OrbitAsSet;
00058 
00059 
00060 // ---------------------------------------------------------------------
00061 // BSGS construction
00062 //
00063 
00064 template<class InputIterator>
00065 boost::shared_ptr<PermutationGroup> construct(unsigned long n, InputIterator begin, InputIterator end) {
00066         SchreierSimsConstruction<PERMUTATION, TRANSVERSAL> schreierSims(n);
00067         boost::shared_ptr<PermutationGroup> group(new PermutationGroup(schreierSims.construct(begin, end)));
00068         return group;
00069 }
00070 
00071 
00072 // ---------------------------------------------------------------------
00073 // setwise stabilizer
00074 //
00075 
00076 template<class InputIterator>
00077 boost::shared_ptr<PermutationGroup> setStabilizer(const PermutationGroup& group, InputIterator begin, InputIterator end) {
00078         PermutationGroup copy(group);
00079         // change the base so that is prefixed by the set
00080         ConjugatingBaseChange<PERMUTATION,TRANSVERSAL,
00081                 RandomBaseTranspose<PERMUTATION,TRANSVERSAL> > baseChange(copy);
00082         baseChange.change(copy, begin, end);
00083         
00084         // prepare search without DCM pruning
00085         classic::SetStabilizerSearch<BSGS<PERMUTATION,TRANSVERSAL>, TRANSVERSAL> backtrackSearch(copy, 0);
00086         backtrackSearch.construct(begin, end);
00087         
00088         // start the search
00089         boost::shared_ptr<PermutationGroup> stabilizer(new PermutationGroup(copy.n));
00090         backtrackSearch.search(*stabilizer);
00091         return stabilizer;
00092 }
00093 
00094 
00095 // ---------------------------------------------------------------------
00096 // set image
00097 //
00098 
00099 template<class InputIterator>
00100 boost::shared_ptr<Permutation> setImage(const PermutationGroup& group, InputIterator begin, InputIterator end, InputIterator begin2, InputIterator end2) {
00101         PermutationGroup copy(group);
00102         // change the base so that is prefixed by the set
00103         ConjugatingBaseChange<PERMUTATION,TRANSVERSAL,
00104                 RandomBaseTranspose<PERMUTATION,TRANSVERSAL> > baseChange(copy);
00105         baseChange.change(copy, begin, end);
00106         
00107         // prepare search without DCM pruning
00108         classic::SetImageSearch<BSGS<PERMUTATION,TRANSVERSAL>, TRANSVERSAL> backtrackSearch(copy, 0);
00109         backtrackSearch.construct(begin, end, begin2, end2);
00110         
00111         // start the search
00112         return backtrackSearch.searchCosetRepresentative();
00113 }
00114 
00115 
00116 // ---------------------------------------------------------------------
00117 // orbits
00118 //
00119 
00120 template<typename PDOMAIN,typename ACTION,typename InputIterator>
00121 std::list<boost::shared_ptr<OrbitSet<PERMUTATION,PDOMAIN> > > orbits(const PermutationGroup& group, InputIterator begin, InputIterator end) {
00122         typedef boost::shared_ptr<OrbitSet<PERMUTATION,PDOMAIN> > ORBIT;
00123         std::list<ORBIT> orbitList;
00124         
00125         for (; begin != end; ++begin) {
00126                 const PDOMAIN& alpha = *begin;
00127                 bool knownElement = false;
00128                 BOOST_FOREACH(const ORBIT& orb, orbitList) {
00129                         if (orb->contains(alpha)) {
00130                                 knownElement = true;
00131                                 break;
00132                         }
00133                 }
00134                 
00135                 if (knownElement)
00136                         continue;
00137                 
00138                 ORBIT orbit(new OrbitSet<PERMUTATION,PDOMAIN>());
00139                 orbit->orbit(alpha, group.S, ACTION());
00140                 orbitList.push_back(orbit);
00141         }
00142 
00143         return orbitList;
00144 }
00145 
00146 inline std::list<boost::shared_ptr<OrbitAsSet> > orbits(const PermutationGroup& group) {
00147         return orbits<unsigned long, Transversal<PERMUTATION>::TrivialAction>(group, boost::counting_iterator<unsigned long>(0), boost::counting_iterator<unsigned long>(group.n));
00148 }
00149 
00150 // ---------------------------------------------------------------------
00151 // smallest orbit element
00152 //
00153 
00154 inline dset smallestSetImage(const PermutationGroup& group, const dset& set) {
00155         OrbitLexMinSearch<PermutationGroup>  orbLexMin(group);
00156         return orbLexMin.lexMin(set);
00157 }
00158 
00159 
00160 } // namespace permlib
00161 
00162 
00163 #endif // PERMLIB_API_H
00164