braids.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  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 "braids.hpp"
  20. #include "init.hpp"
  21. //******************
  22. //* Global objects *
  23. //******************
  24. MonoidFamily ArtinA_mf("Artin A-type",ArtinA_disp,ArtinA_gnum,ArtinA_rank);
  25. MonoidFamily DualA_mf("Dual A-type",DualA_disp,DualA_gnum,DualA_rank);
  26. //***********************
  27. //* Auxiliary functions *
  28. //***********************
  29. //---------------
  30. // braids_init()
  31. //---------------
  32. void braids_init(){
  33. ArtinA_mf.data=(void*)type_ArtinWordA;
  34. ArtinA_mf.set_left_complement(&ArtinA_left_sc);
  35. ArtinA_mf.set_right_complement(&ArtinA_right_sc);
  36. ArtinA_mf.set_ranked_phi_germ(&ArtinA_rpg);
  37. ArtinA_mf.set_ranked_garside_word_factory(&ArtinA_rgwf);
  38. DualA_mf.data=(void*)type_DualWordA;
  39. DualA_mf.set_left_complement(&DualA_left_sc);
  40. DualA_mf.set_right_complement(&DualA_right_sc);
  41. DualA_mf.set_ranked_phi_germ(&DualA_rpg);
  42. DualA_mf.set_ranked_garside_word_factory(&DualA_rgwf);
  43. }
  44. //------------------------------------------------
  45. // ArtinA_left_sc(Generator,Generator,Generator*)
  46. //------------------------------------------------
  47. int ArtinA_left_sc(const Generator& x,const Generator& y,Generator* comp){
  48. //Comp statisfy comp*x=...*y
  49. if(x==y) return 0;
  50. if(abs(x-y)==1){
  51. comp[0]=x;
  52. comp[1]=y;
  53. return 2;
  54. }
  55. else{
  56. comp[0]=y;
  57. return 1;
  58. }
  59. }
  60. //-------------------------------------------------
  61. // ArtinA_rigth_sc(Generator,Generator,Generator*)
  62. //-------------------------------------------------
  63. int ArtinA_right_sc(const Generator& x,const Generator& y,Generator* comp){
  64. //Comp satisfy x*comp=y*...
  65. if(x==y) return 0;
  66. if(abs(x-y)==1){
  67. comp[0]=y;
  68. comp[1]=x;
  69. return 2;
  70. }
  71. else{
  72. comp[0]=y;
  73. return 1;
  74. }
  75. }
  76. //----------------------------------
  77. // ArtinA_rpg(size_t,Generator,int)
  78. //----------------------------------
  79. Generator ArtinA_rpg(size_t r,const Generator& x,int p){
  80. int power=abs(p)%2;
  81. if(power==0) return x;
  82. if(x>0) return r-x;
  83. return -(r+x);
  84. }
  85. //---------------------
  86. // ArtinA_rgwf(size_t)
  87. //---------------------
  88. Word ArtinA_rgwf(size_t r){
  89. Word res(r*(r+1)/2);
  90. size_t ind=0;
  91. for(size_t n=r;n>0;--n){
  92. for(size_t i=1;i<=n;++i){
  93. res[ind++]=i;
  94. }
  95. }
  96. return res;
  97. }
  98. //--------------------
  99. // DualA_gnum(size_t)
  100. //--------------------
  101. inline size_t
  102. DualA_gnum(size_t n){
  103. size_t res=0;
  104. for(size_t i=1;i<n;++i){
  105. res+=i;
  106. }
  107. return res;
  108. }
  109. //-----------------------------------------------
  110. // DualA_left_sc(Generator,Generator,Generator*)
  111. //-----------------------------------------------
  112. int DualA_left_sc(const Generator& x,const Generator& y,Generator* comp){
  113. //Case 1
  114. if(x==y) return 0;
  115. uint p=get_i(x);
  116. uint q=get_j(x);
  117. uint r=get_i(y);
  118. uint s=get_j(y);
  119. //Case 5 and 6
  120. if(p==r){
  121. comp[0]=(q<s)?y:generator(s,q);
  122. return 1;
  123. }
  124. //Case 7 and 8
  125. if(q==s){
  126. comp[0]=(p<r)?y:generator(r,p);
  127. return 1;
  128. }
  129. //Case 3
  130. if(p==s){
  131. comp[0]=y;
  132. return 1;
  133. }
  134. //Case 5
  135. if(q==r){
  136. comp[0]=generator(p,s);
  137. return 1;
  138. }
  139. //Case 9
  140. if(p<r and r<q and q<s){
  141. comp[0]=generator(r,q);
  142. comp[1]=generator(p,s);
  143. return 2;
  144. }
  145. //Case 10
  146. if(r<p and p<s and s<q){
  147. comp[0]=generator(s,q);
  148. comp[1]=generator(r,p);
  149. return 2;
  150. }
  151. //Case 2
  152. comp[0]=y;
  153. return 1;
  154. }
  155. //------------------------------------------------
  156. // DualA_right_sc(Generator,Generator,Generator*)
  157. //------------------------------------------------
  158. int DualA_right_sc(const Generator& x,const Generator& y,Generator* comp){
  159. //Case 1
  160. if(x==y) return 0;
  161. uint p=get_i(x);
  162. uint q=get_j(x);
  163. uint r=get_i(y);
  164. uint s=get_j(y);
  165. //Case 5 and 6
  166. if(p==r){
  167. comp[0]=(q<s)?generator(q,s):y;
  168. return 1;
  169. }
  170. //Case 7 and 8
  171. if(q==s){
  172. comp[0]=(p<r)?generator(p,r):y;
  173. return 1;
  174. }
  175. //Case 3
  176. if(p==s){
  177. comp[0]=generator(r,q);
  178. return 1;
  179. }
  180. //Case 5
  181. if(q==r){
  182. comp[0]=y;
  183. return 1;
  184. }
  185. //Case 9
  186. if(p<r and r<q and q<s){
  187. comp[0]=generator(q,s);
  188. comp[1]=generator(p,r);
  189. return 2;
  190. }
  191. //Case 10
  192. if(r<p and p<s and s<q){
  193. comp[0]=generator(p,s);
  194. comp[1]=generator(r,q);
  195. return 2;
  196. }
  197. //Case 2
  198. comp[0]=y;
  199. return 1;
  200. }
  201. //---------------------------------
  202. // DualA_rpg(size_t,Generator,int)
  203. //---------------------------------
  204. Generator DualA_rpg(size_t r,const Generator& x,int p){
  205. int n=r+1;
  206. int power=p%n;
  207. if(power<0) power+=n;
  208. int sign,absx;
  209. if(x>0){
  210. sign=1;
  211. absx=x;
  212. }
  213. else{
  214. sign=-1;
  215. absx=-x;
  216. }
  217. int i=(get_i(absx)-1+power)%n+1;
  218. int j=(get_j(absx)-1+power)%n+1;
  219. if(i>j) swap(i,j);
  220. return sign*generator(i,j);
  221. }
  222. //--------------------
  223. // DualA_rgwf(size_t)
  224. //--------------------
  225. Word DualA_rgwf(size_t r){
  226. Word res(r);
  227. for(size_t i=0;i<r;++i){
  228. res[i]=generator(i+1,i+2);
  229. }
  230. return res;
  231. }