Parcourir la source

Add Garside element

Jean Fromentin il y a 8 ans
Parent
commit
ae45a505c6
7 fichiers modifiés avec 177 ajouts et 40 suppressions
  1. 35 8
      ext/garside/braids.cpp
  2. 6 0
      ext/garside/braids.hpp
  3. 21 1
      ext/garside/check
  4. 36 3
      ext/garside/init.cpp
  5. 3 0
      ext/garside/init.hpp
  6. 27 4
      ext/garside/monoid.cpp
  7. 49 24
      ext/garside/monoid.hpp

+ 35 - 8
ext/garside/braids.cpp

@@ -40,12 +40,13 @@ void braids_init(){
   ArtinA_mf.set_left_complement(&ArtinA_left_sc);
   ArtinA_mf.set_right_complement(&ArtinA_right_sc);
   ArtinA_mf.set_ranked_phi_germ(&ArtinA_rpg);
-
+  ArtinA_mf.set_ranked_garside_word_factory(&ArtinA_rgwf);
+  
   DualA_mf.data=(void*)type_DualWordA;
   DualA_mf.set_left_complement(&DualA_left_sc);
   DualA_mf.set_right_complement(&DualA_right_sc);
-  DualA_mf.data=(void*)type_DualWordA;
   DualA_mf.set_ranked_phi_germ(&DualA_rpg);
+  DualA_mf.set_ranked_garside_word_factory(&DualA_rgwf);
 }
 
 //------------------------------------------------
@@ -84,9 +85,9 @@ int ArtinA_right_sc(const Generator& x,const Generator& y,Generator* comp){
   }
 }
 
-//--------------------------------------------
-// Generator ArtinA_rpg(size_t,Generator,int)
-//--------------------------------------------
+//----------------------------------
+// ArtinA_rpg(size_t,Generator,int)
+//----------------------------------
 
 Generator ArtinA_rpg(size_t r,const Generator& x,int p){
   int power=abs(p)%2;
@@ -95,6 +96,21 @@ Generator ArtinA_rpg(size_t r,const Generator& x,int p){
   return -(r+x);
 }
 
+//---------------------
+// ArtinA_rgwf(size_t)
+//---------------------
+
+Word ArtinA_rgwf(size_t r){
+  Word res(r*(r+1)/2);
+  size_t ind=0;
+  for(size_t n=r;n>0;--n){
+    for(size_t i=1;i<=n;++i){
+      res[ind++]=i;
+    }
+  }
+  return res;
+}
+
 //--------------------
 // DualA_gnum(size_t)
 //--------------------
@@ -204,9 +220,9 @@ int DualA_right_sc(const Generator& x,const Generator& y,Generator* comp){
   return 1;
 }
 
-//-------------------------------------------
-// Generator DualA_rpg(size_t,Generator,int)
-//-------------------------------------------
+//---------------------------------
+// DualA_rpg(size_t,Generator,int)
+//---------------------------------
 
 Generator DualA_rpg(size_t r,const Generator& x,int p){
   int n=r+1;
@@ -227,3 +243,14 @@ Generator DualA_rpg(size_t r,const Generator& x,int p){
   return sign*generator(i,j);
 }
 
+//--------------------
+// DualA_rgwf(size_t)
+//--------------------
+
+Word DualA_rgwf(size_t r){
+  Word res(r);
+  for(size_t i=0;i<r;++i){
+    res[i]=generator(i+1,i+2);
+  }
+  return res;
+}

+ 6 - 0
ext/garside/braids.hpp

@@ -60,6 +60,9 @@ int ArtinA_right_sc(const Generator& x,const Generator &y,Generator* comp);
 // \param p power to apply
 Generator ArtinA_rpg(size_t r,const Generator& x,int p);
 
+//! Ranked Garside word factory
+Word ArtinA_rgwf(size_t r);
+
 //-----------------
 // Dual of type A
 //-----------------
@@ -82,6 +85,9 @@ int DualA_right_sc(const Generator& x,const Generator &y,Generator* comp);
 // \param p power to apply
 Generator DualA_rpg(size_t r,const Generator& x,int p);
 
+//! Ranked Garside word factory
+Word DualA_rgwf(size_t r);
+
 //**********************
 //* Inline definitions *
 //**********************

+ 21 - 1
ext/garside/check

@@ -1,3 +1,15 @@
+#*******************
+#* Artin of type A *
+#*******************
+
+# Garside element
+
+ArtinA.garside_element(0)==a0
+ArtinA.garside_element(1)==a1
+ArtinA.garside_element(2)==a1*a2*a1
+ArtinA.garside_element(3)==a1*a2*a3*a1*a2*a1
+ArtinA.garside_element(4)==a1*a2*a3*a4*a1*a2*a3*a1*a2*a1
+
 #******************
 #* Dual of type A *
 #******************
@@ -151,4 +163,12 @@ DualA.phi(2,a13,-4)==a23
 DualA.phi(2,A12)==A23
 DualA.phi(2,A23)==A13
 DualA.phi(2,A13)==A12
-DualA.phi(2,a12*A13)==a23*A12
+DualA.phi(2,a12*A13)==a23*A12
+
+# Garside element
+
+DualA.garside_element(0)==a00
+DualA.garside_element(1)==a12
+DualA.garside_element(2)==a12*a23
+DualA.garside_element(3)==a12*a23*a34
+DualA.garside_element(4)==a12*a23*a34*a45

+ 36 - 3
ext/garside/init.cpp

@@ -48,13 +48,21 @@ extern "C"{
   Word x14({generator(1,4)});
   Word x24({generator(2,4)});
   Word x34({generator(3,4)});
+  Word x15({generator(1,5)});
+  Word x25({generator(2,5)});
+  Word x35({generator(3,5)});
+  Word x45({generator(4,5)});
   Word X12({(Generator)(-generator(1,2))});
   Word X13({(Generator)(-generator(1,3))});
   Word X23({(Generator)(-generator(2,3))});
   Word X14({(Generator)(-generator(1,4))});
   Word X24({(Generator)(-generator(2,4))});
   Word X34({(Generator)(-generator(3,4))});
-  
+  Word X15({(Generator)(-generator(1,5))});
+  Word X25({(Generator)(-generator(2,5))});
+  Word X35({(Generator)(-generator(3,5))});
+  Word X45({(Generator)(-generator(4,5))});
+
   void init(){
     braids_init();
   }
@@ -80,6 +88,7 @@ extern "C"{
   
   Gomu::Module::Function member_functions[]={
     //ArtinMonoidFamilyA
+    {"ArtinWordA","garside_element",{"ArtinMonoidFamilyA","Integer"},(void*)mt_garside_element},
     {"Boolean","is_left_divisible",{"ArtinMonoidFamilyA","ArtinWordA","ArtinWordA"},(void*)mt_is_left_divisible},
     {"Tuple","is_left_divisible_x",{"ArtinMonoidFamilyA","ArtinWordA","ArtinWordA"},(void*)mt_is_left_divisible_x},
     {"Boolean","is_right_divisible",{"ArtinMonoidFamilyA","ArtinWordA","ArtinWordA"},(void*)mt_is_right_divisible},
@@ -110,6 +119,7 @@ extern "C"{
     {"ArtinWordA","inverse",{"ArtinWordA"},(void*)word_inverse},
 
     //DualMonoidFamilyA
+    {"DualWordA","garside_element",{"DualMonoidFamilyA","Integer"},(void*)mt_garside_element},
     {"Boolean","is_left_divisible",{"DualMonoidFamilyA","DualWordA","DualWordA"},(void*)mt_is_left_divisible},
     {"Tuple","is_left_divisible_x",{"DualMonoidFamilyA","DualWordA","DualWordA"},(void*)mt_is_left_divisible_x},
     {"Boolean","is_right_divisible",{"DualMonoidFamilyA","DualWordA","DualWordA"},(void*)mt_is_right_divisible},
@@ -165,12 +175,20 @@ extern "C"{
     {"a14","DualWordA",(void*)&x14},
     {"a24","DualWordA",(void*)&x24},
     {"a34","DualWordA",(void*)&x34},
+    {"a15","DualWordA",(void*)&x15},
+    {"a25","DualWordA",(void*)&x25},
+    {"a35","DualWordA",(void*)&x35},
+    {"a45","DualWordA",(void*)&x45},
     {"A12","DualWordA",(void*)&X12},
     {"A13","DualWordA",(void*)&X13},
     {"A23","DualWordA",(void*)&X23},
     {"A14","DualWordA",(void*)&X14},
     {"A24","DualWordA",(void*)&X24},
     {"A34","DualWordA",(void*)&X34},
+    {"A15","DualWordA",(void*)&X15},
+    {"A25","DualWordA",(void*)&X25},
+    {"A35","DualWordA",(void*)&X35},
+    {"A45","DualWordA",(void*)&X45},
     {"ArtinA","ArtinMonoidFamilyA",(void*)&ArtinA_mf},
     {"DualA","DualMonoidFamilyA",(void*)&DualA_mf},
     SYMB_SENTINEL
@@ -181,6 +199,17 @@ extern "C"{
 //* Fonctions definitions *
 //*************************
 
+//-------------------------------------------
+// Word garside_element(MonoidTrait,Integer)
+//-------------------------------------------
+
+void* mt_garside_element(void* m,void* r){
+  MonoidTrait* monoid=(MonoidTrait*)m;
+ if(not monoid->has_garside_element())
+    RuntimeError("Monoid doesn't have Garside element");
+ return (void*)(new Word(monoid->garside_element(Gomu::get_slong(r))));
+}
+
 //--------------------------------------------------
 // Boolean is_left_divisible(MonoidTrait,Word,Word)
 //--------------------------------------------------
@@ -329,8 +358,10 @@ void* mt_left_reverse2(void* m,void* num,void* den){
 
 void* mt_phi(void* m,void* r,void* w){
   MonoidTrait* monoid=(MonoidTrait*)m;
+  if(not monoid->has_garside_automorphism())
+    RuntimeError("Monoid has not Garside automorphism");
   size_t rank=Gomu::get_slong(r);
-  return new Word(monoid->map_phi(rank,*(Word*)w));
+  return new Word(monoid->phi(rank,*(Word*)w));
 }
 
 //--------------------------------------------
@@ -339,9 +370,11 @@ void* mt_phi(void* m,void* r,void* w){
 
 void* mt_phi_power(void* m,void* r,void* w,void* p){
   MonoidTrait* monoid=(MonoidTrait*)m;
+  if(not monoid->has_garside_automorphism())
+    RuntimeError("Monoid has not Garside automorphism");
   size_t rank=Gomu::get_slong(r);
   int power=Gomu::get_slong(p);
-  return new Word(monoid->map_phi(rank,*(Word*)w,power));
+  return new Word(monoid->phi(rank,*(Word*)w,power));
 }
 
 //----------------------------------------------

+ 3 - 0
ext/garside/init.hpp

@@ -46,6 +46,9 @@ void* mf_generators_number(void* m,void* n);
 //* MonoidTrait *
 //***************
 
+//! Return garside element of a given rank
+void* mt_garside_element(void* m,void* r);
+
 //! Test is a left divides b
 void* mt_is_left_divisible(void* m,void* a,void* b);
 

+ 27 - 4
ext/garside/monoid.cpp

@@ -324,6 +324,16 @@ MonoidFamily::~MonoidFamily(){
 //* MonoidTrait *
 //***************
 
+//----------------------------
+// MonoidTrait::MonoidTrait()
+//----------------------------
+
+MonoidTrait::MonoidTrait(){
+  left_reversing=nullptr;
+  right_reversing=nullptr;
+  ranked_phi_germ=nullptr;
+  ranked_garside_word_factory=nullptr;
+}
 //-----------------------------
 // MonoidTrait::~MonoidTrait()
 //-----------------------------
@@ -333,6 +343,19 @@ MonoidTrait::~MonoidTrait(){
   if(right_reversing!=nullptr) delete right_reversing;
 }
 
+
+//-----------------------------------------
+// MonoidTrait::apply_phi(size_t,Word,int)
+//------------------------------------------
+
+void
+MonoidTrait::apply_phi(size_t r,Word& w,int p){
+  size_t s=w.size();
+  for(size_t i=0;i<s;++i){
+    w[i]=ranked_phi_germ(r,w[i],p);
+  }
+}
+
 //-----------------------------------------------------------
 // MonoidTrait::is_left_divisible_x(const Word&,const Word&)
 //-----------------------------------------------------------
@@ -395,12 +418,12 @@ MonoidTrait::left_gcd_x(const Word& a,const Word& b){
   return pair<Word,Word>(left_numerator(),div);
 }
 
-//---------------------------------------
-// MonoidTrait::map_phi(size_t,Word,int)
-//---------------------------------------
+//-----------------------------------
+// MonoidTrait::phi(size_t,Word,int)
+//-----------------------------------
 
 Word
-MonoidTrait::map_phi(size_t r,const Word& w,int p){
+MonoidTrait::phi(size_t r,const Word& w,int p){
   size_t s=w.size();
   Word res(s);
   for(size_t i=0;i<s;++i){

+ 49 - 24
ext/garside/monoid.hpp

@@ -26,6 +26,16 @@
 
 #define MAX_COMPLEMENT_SIZE 64
 
+//***************************
+//* Early class definitions *
+//***************************
+
+class Reversing;
+class LeftReversing;
+class RightReversing;
+class PresentedMonoid;
+class Word;
+
 //************
 //* Typedefs *
 //************
@@ -40,17 +50,9 @@ typedef string(*DisplayGenerator)(const Generator& x);
 typedef size_t(*GeneratorsNumber)(size_t n);
 //! Ranked Generator bijection
 typedef Generator(*RankedGeneratorBijection)(size_t r,const Generator& x,int p);
-
-//***************************
-//* Early class definitions *
-//***************************
-
-class Reversing;
-class LeftReversing;
-class RightReversing;
-class PresentedMonoid;
-class Word;
-
+//! Return a ranked word
+typedef Word(*RankedWordFactory)(size_t r);
+  
 //********************* 
 //* Class definitions *
 //*********************
@@ -167,6 +169,8 @@ public:
   RightReversing* right_reversing;
   //! Ranked Garside automorphism germ
   RankedGeneratorBijection ranked_phi_germ;
+  //! Ranked Garside element factory
+  RankedWordFactory ranked_garside_word_factory;
   
   //! Extra data
   void* data;
@@ -176,14 +180,23 @@ public:
   //! Destructor
   ~MonoidTrait();
 
+  //! Apply phi_r^p to the word
+  void apply_phi(size_t r,Word& w,int p=1);
+
+  //! Return garside_element of rank r
+  Word garside_element(size_t r);
+  
   //! Test if the family has a left complement
   bool has_left_complement() const;
    
   //! Test if the family has a right complement
   bool has_right_complement() const;
 
-  //! test if the famile has a Garside automorphism
+  //! Test if the family has a Garside automorphism
   bool has_garside_automorphism() const;
+
+  //! Test if the family has a Garside element
+  bool has_garside_element() const;
   
   //! Test if a is left divisible by b, i.e.,if it exists c such that a=b.c */
   bool is_left_divisible(const Word& a,const Word& b);
@@ -230,8 +243,8 @@ public:
   Word left_reverse(const Word& u,const Word& v);
 
   //! Return the word obtained under phi_r^p
-  Word map_phi(size_t r,const Word& w,int p=1);
-  
+  Word phi(size_t r,const Word& w,int p=1);
+
   //! Return right complement of x and y
   Word right_complement(const Generator& x,const Generator& y);
   
@@ -270,6 +283,10 @@ public:
 
   //! Set ranked phi germ
   void set_ranked_phi_germ(RankedGeneratorBijection rpg);
+  
+  //! Set ranked garside word factory
+  void set_ranked_garside_word_factory(RankedWordFactory rgwf);
+  
 };
 
 //--------------
@@ -441,11 +458,19 @@ MonoidFamily::generators_number(size_t n){
 // MonoidTrait
 //-------------
 
-inline
-MonoidTrait::MonoidTrait(){
-  left_reversing=nullptr;
-  right_reversing=nullptr;
-  ranked_phi_germ=nullptr;
+inline Word
+MonoidTrait::garside_element(size_t r){
+  return ranked_garside_word_factory(r);
+}
+
+inline bool
+MonoidTrait::has_garside_element() const{
+  return ranked_garside_word_factory!=nullptr;
+}
+
+inline bool
+MonoidTrait::has_garside_automorphism() const{
+  return ranked_phi_germ!=nullptr;
 }
 
 inline bool
@@ -458,11 +483,6 @@ MonoidTrait::has_right_complement() const{
   return right_reversing!=nullptr;
 }
 
-inline bool
-MonoidTrait::has_garside_automorphism() const{
-  return ranked_phi_germ!=nullptr;
-}
-
 inline bool
 MonoidTrait::is_left_divisible(const Word& a,const Word& b){
   right_reversing->set_word(b,a);
@@ -560,6 +580,11 @@ MonoidTrait::set_ranked_phi_germ(RankedGeneratorBijection rpg){
   ranked_phi_germ=rpg;
 }
 
+inline void
+MonoidTrait::set_ranked_garside_word_factory(RankedWordFactory rgwf){
+  ranked_garside_word_factory=rgwf;
+}
+
 //------
 // Word
 //------