Parcourir la source

Add phi-splitting for module Garside

Jean Fromentin il y a 8 ans
Parent
commit
4cf7adbfcc
5 fichiers modifiés avec 97 ajouts et 1 suppressions
  1. 12 1
      ext/garside/check
  2. 37 0
      ext/garside/init.cpp
  3. 6 0
      ext/garside/init.hpp
  4. 36 0
      ext/garside/monoid.cpp
  5. 6 0
      ext/garside/monoid.hpp

+ 12 - 1
ext/garside/check

@@ -188,4 +188,15 @@ DualA.phi_tail(2,delta3)==delta2
 DualA.phi_tail(3,delta4)==delta3
 DualA.phi_tail(1,delta2*delta2)==delta1*delta1
 DualA.phi_tail(2,delta3*delta3)===delta2*delta2
-DualA.phi_tail(3,delta4*delta4)===delta3*delta3
+DualA.phi_tail(3,delta4*delta4)===delta3*delta3
+
+# phi-splitting
+DualA.phi_splitting(1,delta2)==[a12,a00,delta1]
+DualA.phi_splitting(1,delta2*delta2)==[a12,a12,a00,delta1*delta1]
+DualA.phi_splitting(2,a12)==[a12]
+DualA.phi_splitting(2,a23)==[a23]
+DualA.phi_splitting(2,a13)==[a13]
+DualA.phi_splitting(2,a34)==[a23,a00]
+DualA.phi_splitting(2,a24)==[a13,a00]
+DualA.phi_splitting(2,a14)==[a23,a00,a00]
+DualA.phi_splitting(2,delta3)==[a23,a00,delta2]

+ 37 - 0
ext/garside/init.cpp

@@ -107,6 +107,8 @@ extern "C"{
     {"ArtinWordA","phi",{"ArtinMonoidFamilyA","Integer","ArtinWordA"},(void*)mt_phi},
     {"ArtinWordA","phi",{"ArtinMonoidFamilyA","Integer","ArtinWordA","Integer"},(void*)mt_phi_power},
     {"ArtinWordA","phi_tail",{"ArtinMonoidFamilyA","Integer","ArtinWordA"},(void*)mt_phi_tail},
+    {"Tuple","phi_tail_x",{"ArtinMonoidFamilyA","Integer","ArtinWordA"},(void*)mt_phi_tail_x},
+    {"Array","phi_splitting",{"ArtinMonoidFamilyA","Integer","ArtinWordA"},(void*)mt_phi_splitting},
     {"ArtinWordA","right_complement",{"ArtinMonoidFamilyA","ArtinWordA","ArtinWordA"},(void*)mt_right_complement},
     {"ArtinWordA","right_denominator",{"ArtinMonoidFamilyA"},(void*)mt_right_denominator},
     {"ArtinWordA","right_lcm",{"ArtinMonoidFamilyA","ArtinWordA","ArtinWordA"},(void*)mt_right_lcm},
@@ -139,6 +141,8 @@ extern "C"{
     {"DualWordA","phi",{"DualMonoidFamilyA","Integer","DualWordA"},(void*)mt_phi},
     {"DualWordA","phi",{"DualMonoidFamilyA","Integer","DualWordA","Integer"},(void*)mt_phi_power},
     {"DualWordA","phi_tail",{"DualMonoidFamilyA","Integer","DualWordA"},(void*)mt_phi_tail},
+    {"Tuple","phi_tail_x",{"DualMonoidFamilyA","Integer","DualWordA"},(void*)mt_phi_tail_x},
+    {"Array","phi_splitting",{"DualMonoidFamilyA","Integer","DualWordA"},(void*)mt_phi_splitting},
     {"DualWordA","right_complement",{"DualMonoidFamilyA","DualWordA","DualWordA"},(void*)mt_right_complement},
     {"DualWordA","right_denominator",{"DualMonoidFamilyA"},(void*)mt_right_denominator},
     {"DualWordA","right_lcm",{"DualMonoidFamilyA","DualWordA","DualWordA"},(void*)mt_right_lcm},
@@ -393,6 +397,39 @@ void* mt_phi_tail(void* m,void* r,void* w){
   return new Word(monoid->phi_tail(rank,*(Word*)w));
 }
 
+//--------------------------------------------------
+// (Word,Word) phi_tail_x(MonoidTrait,Integer,Word)
+//--------------------------------------------------
+
+void* mt_phi_tail_x(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);
+  pair<Word,Word> p=monoid->phi_tail_x(rank,*(Word*)w);
+  Gomu::TupleValue* res=new Gomu::TupleValue(2);
+  Gomu::Type* type=(Gomu::Type*)monoid->data;
+  res->tab[0]=Gomu::Value(type,new Word(p.first));
+  res->tab[1]=Gomu::Value(type,new Word(p.second));
+  return (void*)res;
+}
+
+//-----------------------------------------------------
+// Array[Word] phi_splitting(MonoidTrait,Integer,Word)
+//-----------------------------------------------------
+
+void* mt_phi_splitting(void* m,void* r,void* w){
+  MonoidTrait* monoid=(MonoidTrait*)m;
+  size_t rank=Gomu::get_slong(r);
+  Array<Word> a=monoid->phi_splitting(rank,*(Word*)w);
+  Gomu::ArrayValue* res=new Gomu::ArrayValue(a.size());
+  res->type=(Gomu::Type*)monoid->data;
+  for(size_t i=0;i<res->size;++i){
+    res->tab[i]=(void*)(new Word(a.read(i)));
+  }
+  return (void*)res;
+}
+
 //----------------------------------------------
 // Word right_complement(MonoidTrait,Word,Word)
 //----------------------------------------------

+ 6 - 0
ext/garside/init.hpp

@@ -91,6 +91,12 @@ void* mt_phi_power(void* m,void* r,void* w,void* p);
 //! Return ranked phi-tail of an element
 void* mt_phi_tail(void* m,void* r,void* w);
 
+//! Return ranked phi-tail of an element together with remainder
+void* mt_phi_tail_x(void* m,void* r,void* w);
+
+//! Return the ranked phi-splitting of an element
+void* mt_phi_splitting(void* m,void* r,void* w);
+
 //! Left reverse a word
 void* mt_left_reverse(void* m,void* w);
 

+ 36 - 0
ext/garside/monoid.cpp

@@ -460,6 +460,42 @@ MonoidTrait::phi_tail(size_t r,const Word& w){
   return res;
 }
 
+//--------------------------------------
+// MonoidTrait::phi_tail_x(size_t,Word)
+//--------------------------------------
+
+pair<Word,Word>
+MonoidTrait::phi_tail_x(size_t r,const Word& w){
+  Word u=w;
+  Word res;
+  Word delta=garside_element(r);
+  while(true){
+    pair<Word,Word> temp=right_gcd_x(u,delta);
+    if(temp.first.is_empty()) return pair<Word,Word>(u,res);
+    res=res*temp.first;
+    u=temp.second;
+  }
+  return pair<Word,Word>(u,res);
+}
+
+//-----------------------------------------
+// MonoidTrait::phi_splitting(size_t,Word)
+//-----------------------------------------
+
+Array<Word>
+MonoidTrait::phi_splitting(size_t r,const Word& w){
+  deque<Word> res;
+  Word u=w;
+  while(not u.is_empty()){
+    pair<Word,Word> p=phi_tail_x(r,u);
+    u=phi(r+1,p.first,-1);
+    res.push_front(p.second);
+  }
+  Array<Word> res_array(res.size());
+  for(size_t i=0;i<res.size();++i) res_array[i]=res[i];
+  return res_array;
+}
+
 //----------------------------------------------------
 // MonoidTrait::right_complement(Generator,Generator)
 //----------------------------------------------------

+ 6 - 0
ext/garside/monoid.hpp

@@ -251,6 +251,12 @@ public:
   //! Return ranked phi-tail of an element
   Word phi_tail(size_t r,const Word& w);
 
+  //! Return ranked phi-tail of an element together with remainder
+  pair<Word,Word> phi_tail_x(size_t r,const Word& w);
+
+  //! Return the ranked phi-splitting of an element
+  Array<Word> phi_splitting(size_t r,const Word& w);
+  
   //! Return right complement of x and y
   Word right_complement(const Generator& x,const Generator& y);