/** * This file is part of Gomu. * * Copyright 2016 by Jean Fromentin <jean.fromentin@math.cnrs.fr> * * Gomu is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Gomu is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Gomu. If not, see <http://www.gnu.org/licenses/>. */ #include "permutations.hpp" PermutationEnumerator<CoxeterA>::PermutationEnumerator(uint64 r):n(r),sigma(r){ } void PermutationEnumerator<CoxeterA>::reset(){ sigma=Permutation<CoxeterA>(n); } const Permutation<CoxeterA>& PermutationEnumerator<CoxeterA>::get() const{ return sigma; } bool PermutationEnumerator<CoxeterA>::next(){ for(int first=n-1;first>0;--first){ if(sigma.win[first]<sigma.win[first+1]){ int j=n; while(sigma.win[j]<sigma.win[first]) --j; swap(sigma.win[j],sigma.win[first]); int i=first+1; j=n; while(i<j) swap(sigma.win[i++],sigma.win[j--]); return true; } } return false; } PermutationEnumerator<CoxeterB>::PermutationEnumerator(uint64 r):PermutationEnumerator<CoxeterA>(r),sigmaB(r),sign(0){ } void PermutationEnumerator<CoxeterB>::reset(){ PermutationEnumerator<CoxeterA>::reset(); sigmaB=Permutation<CoxeterB>(n); sign=0; } const Permutation<CoxeterB>& PermutationEnumerator<CoxeterB>::get() const{ return sigmaB; } bool PermutationEnumerator<CoxeterB>::next(){ ++sign; if(sign==(1<<n)){ sign=0; if(not PermutationEnumerator<CoxeterA>::next()) return false; sigmaB.m128=sigma.m128; } else{ uint64 mask=(1<<(n-1)); for(uint64 i=1;i<=n;++i){ sigmaB.win[i]=(mask&sign)?-sigma.win[i]:sigma.win[i]; mask>>=1; } } return true; }; PermutationEnumerator<CoxeterD>::PermutationEnumerator(uint64 r):PermutationEnumerator<CoxeterA>(r),sigmaD(r),sign(0){ } void PermutationEnumerator<CoxeterD>::reset(){ PermutationEnumerator<CoxeterA>::reset(); sigmaD=Permutation<CoxeterD>(n); sign=0; } const Permutation<CoxeterD>& PermutationEnumerator<CoxeterD>::get() const{ return sigmaD; } bool PermutationEnumerator<CoxeterD>::next(){ ++sign; if(sign==(1<<n)){ sign=0; if(not PermutationEnumerator<CoxeterA>::next()) return false; sigmaD.m128=sigma.m128; } else{ if(__builtin_popcountll(sign)%2==0){ uint64 mask=1; for(uint64 i=1;i<=n;++i){ sigmaD.win[i]=(mask&sign)?-sigma.win[i]:sigma.win[i]; mask<<=1; } } else return next(); } return true; }; int PermutationEnumerator<CoxeterA>::cmp(const PermutationEnumerator<CoxeterA>& E) const{ if(n==E.n) return 0; if(n<E.n) return 1; return -1; } int PermutationEnumerator<CoxeterB>::cmp(const PermutationEnumerator<CoxeterB>& E) const{ if(n==E.n) return 0; if(n<E.n) return 1; return -1; } int PermutationEnumerator<CoxeterD>::cmp(const PermutationEnumerator<CoxeterD>& E) const{ if(n==E.n) return 0; if(n<E.n) return 1; return -1; }