permutations.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /**
  2. * This file is part of Gomu.
  3. *
  4. * Copyright 2016 by Jean Fromentin <jean.fromentin@math.cnrs.fr>
  5. *
  6. * Gomu is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Gomu is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Gomu. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "permutations.hpp"
  20. PermutationEnumerator<CoxeterA>::PermutationEnumerator(uint64 r):n(r),sigma(r){
  21. }
  22. void
  23. PermutationEnumerator<CoxeterA>::reset(){
  24. sigma=Permutation<CoxeterA>(n);
  25. }
  26. const Permutation<CoxeterA>&
  27. PermutationEnumerator<CoxeterA>::get() const{
  28. return sigma;
  29. }
  30. bool
  31. PermutationEnumerator<CoxeterA>::next(){
  32. for(int first=n-1;first>0;--first){
  33. if(sigma.win[first]<sigma.win[first+1]){
  34. int j=n;
  35. while(sigma.win[j]<sigma.win[first]) --j;
  36. swap(sigma.win[j],sigma.win[first]);
  37. int i=first+1;
  38. j=n;
  39. while(i<j) swap(sigma.win[i++],sigma.win[j--]);
  40. return true;
  41. }
  42. }
  43. return false;
  44. }
  45. PermutationEnumerator<CoxeterB>::PermutationEnumerator(uint64 r):PermutationEnumerator<CoxeterA>(r),sigmaB(r),sign(0){
  46. }
  47. void
  48. PermutationEnumerator<CoxeterB>::reset(){
  49. PermutationEnumerator<CoxeterA>::reset();
  50. sigmaB=Permutation<CoxeterB>(n);
  51. sign=0;
  52. }
  53. const Permutation<CoxeterB>&
  54. PermutationEnumerator<CoxeterB>::get() const{
  55. return sigmaB;
  56. }
  57. bool
  58. PermutationEnumerator<CoxeterB>::next(){
  59. ++sign;
  60. if(sign==(1<<n)){
  61. sign=0;
  62. if(not PermutationEnumerator<CoxeterA>::next()) return false;
  63. sigmaB.m128=sigma.m128;
  64. }
  65. else{
  66. uint64 mask=(1<<(n-1));
  67. for(uint64 i=1;i<=n;++i){
  68. sigmaB.win[i]=(mask&sign)?-sigma.win[i]:sigma.win[i];
  69. mask>>=1;
  70. }
  71. }
  72. return true;
  73. };
  74. PermutationEnumerator<CoxeterD>::PermutationEnumerator(uint64 r):PermutationEnumerator<CoxeterA>(r),sigmaD(r),sign(0){
  75. }
  76. void
  77. PermutationEnumerator<CoxeterD>::reset(){
  78. PermutationEnumerator<CoxeterA>::reset();
  79. sigmaD=Permutation<CoxeterD>(n);
  80. sign=0;
  81. }
  82. const Permutation<CoxeterD>&
  83. PermutationEnumerator<CoxeterD>::get() const{
  84. return sigmaD;
  85. }
  86. bool
  87. PermutationEnumerator<CoxeterD>::next(){
  88. ++sign;
  89. if(sign==(1<<n)){
  90. sign=0;
  91. if(not PermutationEnumerator<CoxeterA>::next()) return false;
  92. sigmaD.m128=sigma.m128;
  93. }
  94. else{
  95. if(__builtin_popcountll(sign)%2==0){
  96. uint64 mask=1;
  97. for(uint64 i=1;i<=n;++i){
  98. sigmaD.win[i]=(mask&sign)?-sigma.win[i]:sigma.win[i];
  99. mask<<=1;
  100. }
  101. }
  102. else return next();
  103. }
  104. return true;
  105. };
  106. int
  107. PermutationEnumerator<CoxeterA>::cmp(const PermutationEnumerator<CoxeterA>& E) const{
  108. if(n==E.n) return 0;
  109. if(n<E.n) return 1;
  110. return -1;
  111. }
  112. int
  113. PermutationEnumerator<CoxeterB>::cmp(const PermutationEnumerator<CoxeterB>& E) const{
  114. if(n==E.n) return 0;
  115. if(n<E.n) return 1;
  116. return -1;
  117. }
  118. int
  119. PermutationEnumerator<CoxeterD>::cmp(const PermutationEnumerator<CoxeterD>& E) const{
  120. if(n==E.n) return 0;
  121. if(n<E.n) return 1;
  122. return -1;
  123. }