1 // -*- mode:C++ ; compile-command: "g++ -I.. -I../include -g -c quater.cc" -*-
2 /*
3  *  Copyright (C) 2001,2014 B. Parisse, Institut Fourier, 38402 St Martin d'Heres
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 3 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 #ifndef _GIAC_QUATER_H
19 #define _GIAC_QUATER_H
20 #include "first.h"
21 #include "gen.h"
22 #include <string>
23 
24 
25 #ifndef NO_NAMESPACE_GIAC
26 namespace giac {
27 #endif // ndef NO_NAMESPACE_GIAC
28 
29   extern const unary_function_ptr * const  at_quaternion; // user-level quaternion constructor
30 #ifndef NO_RTTI
31   class quaternion : public gen_user {
32   public:
33     gen r,i,j,k;
memory_alloc()34     virtual gen_user * memory_alloc() const {
35       quaternion * ptr= new quaternion(*this);
36       return dynamic_cast<gen_user *>(ptr);
37     }
quaternion(const quaternion & q)38     quaternion(const quaternion & q):r(q.r),i(q.i),j(q.j),k(q.k){};
quaternion(const gen & myr,const gen & myi,const gen & myj,const gen & myk)39     quaternion(const gen & myr,const gen & myi,const gen & myj,const gen & myk):r(myr),i(myi),j(myj),k(myk) {};
quaternion()40     quaternion():r(zero),i(zero),j(zero),k(zero) {};
41     quaternion(const gen & g);
42     virtual gen operator + (const gen & g) const {
43       quaternion q(g);
44       return quaternion(r+q.r,i+q.i,j+q.j,k+q.k);
45     }
46     virtual gen operator - (const gen & g) const {
47       quaternion q(g);
48       return quaternion(r-q.r,i-q.i,j-q.j,k-q.k);
49     }
50     virtual std::string print (GIAC_CONTEXT) const ;
51   };
52   gen _quaternion(const gen & args,GIAC_CONTEXT);
53 
54   class galois_field : public gen_user {
55   public:
56     gen p; // F_p^m, characteristic of the field
57     gen P; // minimal irreducible polynomial of degree m, as vector
58     gen x; // the name of the variable for construction
59     gen a; // value as a vector polynomial or undef (whole field)
memory_alloc()60     virtual gen_user * memory_alloc() const {
61       galois_field * ptr= new galois_field(*this,false);
62       // if (a != smod(a,p) && smod(a,p))  CERR << "not reduced" << '\n';
63       return ptr;
64     }
65     galois_field(const galois_field & q,bool doreduce=true);
66     galois_field(const gen p_,const gen & P_,const gen & x_,const gen & a_,bool doreduce=true);
67     galois_field(const gen & g,bool primitive,GIAC_CONTEXT);
68     void reduce(); // reduce a
69     virtual gen operator + (const gen & g) const;
70     virtual gen operator - (const gen & g) const;
71     virtual gen operator - () const;
72     virtual gen operator * (const gen & g) const;
73     virtual gen operator / (const gen & g) const;
74     virtual gen inv () const ;
75     virtual std::string print (GIAC_CONTEXT) const ;
76     virtual std::string texprint (GIAC_CONTEXT) const ;
77     virtual bool operator == (const gen &) const ;
78     virtual bool is_zero() const;
79     virtual bool is_one() const;
80     virtual bool is_minus_one() const;
81     virtual gen operator () (const gen &,GIAC_CONTEXT) const;
82     virtual gen operator [] (const gen &) ;
83     virtual gen operator > (const gen & g) const;
84     virtual gen operator < (const gen & g) const;
85     virtual gen operator >= (const gen & g) const;
86     virtual gen operator <= (const gen & g) const;
gcd(const gen &)87     virtual gen gcd (const gen &) const { return plus_one;}
gcd(const gen_user & a)88     virtual gen gcd (const gen_user & a) const { return plus_one; }
89     virtual gen polygcd (const polynome &,const polynome &,polynome &) const ;
90     virtual gen makegen(int i) const ;
91     virtual gen polyfactor (const polynome & p,factorization & f) const ;
conj(GIAC_CONTEXT)92     virtual gen conj(GIAC_CONTEXT) const { return *this;}
re(GIAC_CONTEXT)93     virtual gen re(GIAC_CONTEXT) const { return *this;}
im(GIAC_CONTEXT)94     virtual gen im(GIAC_CONTEXT) const {  return 0;}
95     virtual gen sqrt(GIAC_CONTEXT) const;
96     virtual gen rand(GIAC_CONTEXT) const;
97     polynome poly_reduce(const polynome & p) const ;
98   };
99 
100   // Is the polynomial v irreducible and primitive modulo p?
101   // If it is only irreducible, returns 2 and sets vmin
102   int is_irreducible_primitive(const vecteur & v,const gen & p,vecteur & vmin,bool primitive,GIAC_CONTEXT);
103   vecteur find_irreducible_primitive(const gen & p,int m,bool primitive,GIAC_CONTEXT);
104   gen _galois_field(const gen & args,GIAC_CONTEXT);
105 
106   struct gen_context_t {
107     gen g;
108     context * ptr ;
109   };
110   // All Galois field in a map[p^m]=generator of GF(p,m)
111   // the generator might be replaced by some polynomial of a GF(p,m*m2)
112   // if a binary operation on two elements of different GF(p,.) happens
113   typedef std::map<gen,gen_context_t,comparegen > gfmap;
114   gfmap & gf_list();
115   int gfsize(const gen & P);
116   bool has_gf_coeff(const gen & e,gen & p, gen & pmin);
117   bool has_gf_coeff(const vecteur & v,gen & p, gen & pmin);
118   bool has_gf_coeff(const gen & e);
119   bool has_gf_coeff(const vecteur & v);
120   // convert v in char 2, returns minimal polynomial or 0 (unknown) or -1 (unable to convert), set x to the generator of the field
121   int gf_char2_vecteur2vectorint(const vecteur & v,std::vector<int> & V,gen & x);
122   // convert m in char 2, returns minimal polynomial or 0 (unknown) or -1 (unable to convert), set x to the generator of the field
123   int gf_char2_matrice2vectorvectorint(const matrice & m,std::vector< std::vector<int> > & M,gen & x);
124   void gf_char2_vectorint2vecteur(const std::vector<int> & source,vecteur & target,int M,const gen & x);
125   void gf_char2_vectorvectorint2mat(const std::vector< std::vector<int> > & source,matrice & target,int M,const gen & x);
126   int dotgf_char2(const std::vector<int> & v,const std::vector<int> & w,int M);
127   bool gf_char2_mmult_atranb(const std::vector< std::vector<int> > & A,const std::vector< std::vector<int> > & tranB,std::vector< std::vector<int> > & C,int M);
128   bool gf_char2_rref(std::vector< std::vector<int> > & N,const gen & x,int M,vecteur & pivots,std::vector<int> & permutation,std::vector<int> & maxrankcols,gen & det,int l, int lmax, int c,int cmax,int fullreduction,int dont_swap_below,int rref_or_det_or_lu);
129   bool gf_char2_multpoly(const std::vector<int> & a,const std::vector<int> & b,std::vector<int> & res,int M);
130   bool gf_multpoly(const std::vector< std::vector<int> > & a,const std::vector< std::vector<int> > & b,std::vector< std::vector<int> > & res,const std::vector<int> & pmin,int modulo);
131   int gf_vecteur2vectorvectorint(const vecteur & v,std::vector< std::vector<int> > & V,gen & x,std::vector<int> & pmin);
132   bool gf_multpoly(const std::vector< std::vector<int> > & a,const std::vector< std::vector<int> > & b,std::vector< std::vector<int> > & res,const std::vector<int> & pmin,int modulo);
133   void gf_vectorvectorint2vecteur(const std::vector< std::vector<int> > & source,vecteur & target,const gen & carac,const vecteur & pmin,const gen & x);
134   void gf_vectorvectorint2vecteur(const std::vector< std::vector<int> > & source,vecteur & target,int carac,const std::vector<int> & pmin,const gen & x);
135 
136 #else // NO_RTTI
has_gf_coeff(const gen & e,gen & p,gen & pmin)137   inline bool has_gf_coeff(const gen & e,gen & p, gen & pmin){ return false; }
has_gf_coeff(const vecteur & v,gen & p,gen & pmin)138   inline bool has_gf_coeff(const vecteur & v,gen & p, gen & pmin){ return false; }
has_gf_coeff(const gen & e)139   inline bool has_gf_coeff(const gen & e){ return false; }
has_gf_coeff(const vecteur & v)140   inline bool has_gf_coeff(const vecteur & v){ return false; }
gf_char2_vecteur2vectorint(const vecteur & v,std::vector<int> & V,gen & x)141   inline int gf_char2_vecteur2vectorint(const vecteur & v,std::vector<int> & V,gen & x){ return -1; }
gf_char2_matrice2vectorvectorint(const matrice & m,std::vector<std::vector<int>> & M,gen & x)142   inline int gf_char2_matrice2vectorvectorint(const matrice & m,std::vector< std::vector<int> > & M,gen & x){ return -1;}
dotgf_char2(const std::vector<int> & v,const std::vector<int> & w,int M)143   inline int dotgf_char2(const std::vector<int> & v,const std::vector<int> & w,int M){ return 0; }
gf_char2_vectorint2vecteur(const std::vector<int> & source,vecteur & target,int M,const gen & x)144   inline void gf_char2_vectorint2vecteur(const std::vector<int> & source,vecteur & target,int M,const gen & x){};
gf_char2_vectorvectorint2mat(const std::vector<std::vector<int>> & source,matrice & target,int M,const gen & x)145   inline void gf_char2_vectorvectorint2mat(const std::vector< std::vector<int> > & source,matrice & target,int M,const gen & x){};
gf_char2_mmult_atranb(const std::vector<std::vector<int>> & A,const std::vector<std::vector<int>> & tranB,std::vector<std::vector<int>> & C,int M)146   inline   bool gf_char2_mmult_atranb(const std::vector< std::vector<int> > & A,const std::vector< std::vector<int> > & tranB,std::vector< std::vector<int> > & C,int M){ return false;};
gf_char2_rref(std::vector<std::vector<int>> & N,const gen & x,int M,vecteur & pivots,std::vector<int> & permutation,std::vector<int> & maxrankcols,gen & det,int l,int lmax,int c,int cmax,int fullreduction,int dont_swap_below,int rref_or_det_or_lu)147   inline bool gf_char2_rref(std::vector< std::vector<int> > & N,const gen & x,int M,vecteur & pivots,std::vector<int> & permutation,std::vector<int> & maxrankcols,gen & det,int l, int lmax, int c,int cmax,int fullreduction,int dont_swap_below,int rref_or_det_or_lu){ return false; };
gf_char2_multpoly(const std::vector<int> & a,const std::vector<int> & b,std::vector<int> & res,int M)148   inline bool gf_char2_multpoly(const std::vector<int> & a,const std::vector<int> & b,std::vector<int> & res,int M){ return false; }
gf_vecteur2vectorvectorint(const vecteur & v,std::vector<std::vector<int>> & V,gen & x,std::vector<int> & pmin)149   inline int gf_vecteur2vectorvectorint(const vecteur & v,std::vector< std::vector<int> > & V,gen & x,std::vector<int> & pmin){ return 0; }
gf_multpoly(const std::vector<std::vector<int>> & a,const std::vector<std::vector<int>> & b,std::vector<std::vector<int>> & res,const std::vector<int> & pmin,int modulo)150   inline bool gf_multpoly(const std::vector< std::vector<int> > & a,const std::vector< std::vector<int> > & b,std::vector< std::vector<int> > & res,const std::vector<int> & pmin,int modulo){ return false; }
gf_vectorvectorint2vecteur(const std::vector<std::vector<int>> & source,vecteur & target,const gen & carac,const vecteur & pmin,const gen & x)151   inline void gf_vectorvectorint2vecteur(const std::vector< std::vector<int> > & source,vecteur & target,const gen & carac,const vecteur & pmin,const gen & x){}
gf_vectorvectorint2vecteur(const std::vector<std::vector<int>> & source,vecteur & target,int carac,const std::vector<int> & pmin,const gen & x)152   inline void gf_vectorvectorint2vecteur(const std::vector< std::vector<int> > & source,vecteur & target,int carac,const std::vector<int> & pmin,const gen & x){};
153 
154 #endif // NO_RTTI
155 
156 #ifndef NO_NAMESPACE_GIAC
157 } // namespace giac
158 #endif // ndef NO_NAMESPACE_GIAC
159 
160 
161 #endif // _GIAC_QUATER_H
162