braids.cpp 4.9 KB

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