/* * gfanlib_symmetry.cpp * * Created on: Oct 22, 2010 * Author: anders */ #include "gfanlib_symmetry.h" #include using namespace std; namespace gfan{ class Trie { class TrieNode { typedef map Map; Map m; public: TrieNode() { } TrieNode(IntVector const &v, int i) { if(ifirst]) ret+=j->second.stabilizerSize(v,i+1); } return ret; } void search(ZVector const &v, ZVector &building, Permutation &tempPerm, Permutation &ret, ZVector &optimal, int i, bool &isImproving)const { if(i==v.size()){ret=tempPerm;optimal=building;isImproving=false;return;} if(isImproving) building[i]=-0x7fffffff; else building[i]=optimal[i]; for(Map::const_iterator j=m.begin();j!=m.end();j++) if(building[i]first]) { isImproving=true; building[i]=v[j->first]; } for(Map::const_iterator j=m.begin();j!=m.end();j++) if(v[j->first]==building[i]) { tempPerm[i]=j->first; j->second.search(v,building,tempPerm,ret,optimal,i+1,isImproving); } } void searchStabalizer(ZVector const &v, ZVector &building, Permutation &tempPerm, Permutation &ret, ZVector &optimal, int i, bool &isImproving, ZVector const &toBeFixed)const { if(i==v.size()) if(!(tempPerm.apply(v)first]) { tempPerm[i]=j->first; j->second.searchStabalizer(v,building,tempPerm,ret,optimal,i+1,isImproving,toBeFixed); } } /* this code contains mistakes void searchStabalizer(IntegerVector const &v, IntegerVector &building, IntegerVector &tempPerm, IntegerVector &ret, IntegerVector &optimal, int i, bool &isImproving, IntegerVector const &toBeFixed)const { if(i==v.size()){ret=tempPerm;optimal=building;isImproving=false;debug<<"DEEP";return;} if(isImproving) building[i]=-0x7fffffff; else building[i]=optimal[i]; for(Map::const_iterator j=m.begin();j!=m.end();j++) if(toBeFixed[i]==toBeFixed[j->first]) if(v[j->first]>building[i]) { isImproving=true; building[i]=v[j->first]; } for(Map::const_iterator j=m.begin();j!=m.end();j++) if(toBeFixed[i]==toBeFixed[j->first]) if(v[j->first]==building[i]) { debug.printInteger(i);debug<<":"; debug.printInteger(j->first);debug<<" "; tempPerm[i]=j->first; j->second.searchStabalizer(v,building,tempPerm,ret,optimal,i+1,isImproving,toBeFixed); } }*/ // void doubleSearch(); void insert(Permutation const &v, int i) { if(i==v.size())return; if(m.count(v[i])) m[v[i]].insert(v,i+1); else m[v[i]]= TrieNode(v,i+1); } /* void print(int i, int n)const { if(i==n)return; for(Map::const_iterator j=m.begin();j!=m.end();j++) { {for(int j=0;j<2*i;j++)debug<<" ";} debug.printInteger(j->first); debug<<"\n"; j->second.print(i+1,n); } }*/ int size(int i,int n)const { if(i==n)return 1; int ret=0; for(Map::const_iterator j=m.begin();j!=m.end();j++) ret+=j->second.size(i+1,n); return ret; } }; public: TrieNode theTree; int n; Trie(int n_): n(n_), theTree(Permutation(n_),0) { } int size()const { return theTree.size(0,n); } void insert(Permutation const &v) { theTree.insert(v,0); // debug<size(); } void SymmetryGroup::computeClosure(Permutation const &v) //does this work?? { ElementContainer newOnes; newOnes.insert(v); while(!newOnes.empty()) { static int i; i++; Permutation v=*newOnes.begin(); for(ElementContainer::const_iterator i=elements.begin();i!=elements.end();i++) { { Permutation n=i->apply(v); if(0==elements.count(n)) newOnes.insert(n); } { Permutation n=v.apply(*i); if(0==elements.count(n)) newOnes.insert(n); } } newOnes.erase(v); elements.insert(v); } } /* void SymmetryGroup::computeClosure(IntegerVectorList const &l) { // for(IntegerVectorList::const_iterator i=l.begin();i!=l.end();i++) // computeClosure(*i); bool growing=true; while(growing) { growing=false; for(ElementContainer::const_iterator i=elements.begin();i!=elements.end();i++) { for(IntegerVectorList::const_iterator j=l.begin();j!=l.end();j++) { { IntegerVector n(compose(*i,*j)); growing|=(0==elements.count(n)); elements.insert(n); } { IntegerVector n(compose(*i,*j)); growing|=(0==elements.count(n)); elements.insert(n); } } } } } */ /* void SymmetryGroup::print(FILE *f) { AsciiPrinter P(f); P.printString("Printing SymmetryGroup\n"); IntegerVectorList l; for(ElementContainer::const_iterator i=elements.begin();i!=elements.end();i++) { // P.printVector(*i); // P.printNewLine(); l.push_back(*i); } P.printVectorList(l); fprintf(f,"Group order=%i\n",elements.size()); P.printString("Done printing SymmetryGroup.\n"); } */ Permutation Permutation::apply(Permutation const &b)const { IntVector ret(size()); assert(size()==b.size()); for(int i=0;isearch(v); return usedPermutation->apply(v); } return trie->search(v).apply(v); } ZVector ret=v; ElementContainer::const_iterator usedPerm; for(ElementContainer::const_iterator i=elements.begin();i!=elements.end();i++) { ZVector q=i->apply(v); if(! (qsearch(v); // debug<<"Trie"<searchStabalizer(v,fixed),v); } IntegerVector ret=v; for(ElementContainer::const_iterator i=elements.begin();i!=elements.end();i++) if(compose(*i,fixed)==fixed) { IntegerVector q=compose(*i,v); if(retsearchStabalizer(v,fixed),v); // debug<<"Input"<searchStabalizer(v,fixed),v); } return ret; } #endif bool Permutation::isPermutation(IntVector const &a) { int n=a.size(); IntVector temp(n); for(int i=0;i=n)return false; temp[i]=i; } for(int i=0;istabilizerSize(stable); } else { for(SymmetryGroup::ElementContainer::const_iterator j=elements.begin();j!=elements.end();j++) { bool doesFix=true; for(int i=0;i ret2; for(ElementContainer::const_iterator i=elements.begin();i!=elements.end();i++) ret2.insert(i->fundamentalDomainInequality()); ZMatrix ret(0,sizeOfBaseSet()); for(set::const_iterator i=ret2.begin();i!=ret2.end();i++) if(!i->isZero())ret.appendRow(*i); return ret; } void SymmetryGroup::createTrie() { trie=new Trie(sizeOfBaseSet()); for(ElementContainer::const_iterator i=elements.begin();i!=elements.end();i++) trie->insert(*i); } bool SymmetryGroup::isTrivial()const { ElementContainer::const_iterator i=elements.begin(); assert(i!=elements.end()); i++; return i==elements.end(); } #if 0 static int mergeSortRek(IntegerVector &v, int begin, int end, IntegerVector &temp) { if(end-begin<2)return 0; int med=(begin+end)>>1; int nswaps=mergeSortRek(v,begin,med,temp); nswaps+=mergeSortRek(v,med,end,temp); { int Astart=begin; int Alength=med-begin; int Bstart=med; int Blength=end-med; int nextFree=begin; while(nextFree!=end) { // debug<<"Astart:"<