synaps/upol/quotient.h

00001 /*********************************************************************
00002 *      This file is part of the source code of SYNAPS kernel.        *
00003 *   Author(s): B. Mourrain, H. Prieto, GALAAD, INRIA                 *
00004 **********************************************************************
00005 History:
00006     1998/07/01 first version by HP.
00007     2000/03/02 updated by BM, use modules.
00008 **********************************************************************/
00009 #ifndef SYNAPS_UPOL_MODUPOL_H
00010 #define SYNAPS_UPOL_MODUPOL_H
00011 //------------------------------------------------------------------
00012 #include <synaps/init.h>
00013 #include <synaps/base/type.h>
00014 #include <synaps/upol/UPOLDAR.m>
00015 #include <synaps/upol/UPolDse.h>
00016 #include <synaps/upol/horner.h>
00017 #include <synaps/linalg/MatrStr.h>
00018 #include <synaps/linalg/hankel.h>
00019 #ifdef FFT
00020 #include <synaps/upol/mult_fft.h>
00021 #endif
00022 #include <synaps/upol/resultant.h>
00023 //----------------------------------------------------------------------
00024 __BEGIN_NAMESPACE_SYNAPS
00025 //--------------------------------------------------------------------
00028 namespace quotient 
00029 {
00037   template<class C, class R=UPolDse<C> >
00038     struct ModUPol
00039     {
00040       
00041       R poly;
00042       
00043       typedef typename R::value_type       value_type;
00044       typedef typename R::size_type        size_type;
00045       typedef typename R::iterator         iterator;
00046       typedef typename R::reverse_iterator iterator_r;
00047       typedef upol::horner<C>              rep_type;
00048       typedef ModUPol<C,R>                 self_t;
00049       
00050       ModUPol():poly() {}
00051       ModUPol(const R & r): poly(r) {}
00052       ModUPol(const ModUPol<R> & Mod):  poly(Mod.poly) {}
00053       
00054       template<class S>
00055       void  monomial_to_horner(rep_type& h, const S & pol);
00056       template<class S>
00057       void  horner_to_monomial(S& h, const rep_type & h);
00058       
00059       // Returns the quotient dimension
00060       size_type dim() {return UPOLDAR::degree(poly);}
00061       
00062       void  assign(rep_type& r, const rep_type & a)   {r=a;}
00063       void  assign(rep_type& r, const R & a)          {monomial_to_horner(r,a);}
00064       void  assign(rep_type& r, const value_type & a)
00065       {r.resize(dim()); r[dim()-1]=a/poly[dim()];}
00066       void  assign(rep_type& r, int a) {assign(r,value_type(a));}
00067 
00068       void  add(rep_type& r, const rep_type & a, const rep_type& b);
00069       void  add(rep_type& r, const rep_type & a);
00070       void  sub(rep_type& r, const rep_type & a, const rep_type& b);
00071       void  sub(rep_type& r, const rep_type & a);
00072       void  mul(rep_type& r, const rep_type & a, const rep_type& b);
00073       void  mul(rep_type& r, const rep_type & a, const C& b);
00074       void  div(rep_type& r, const rep_type & a, const C& b);
00075       
00076       void  square(rep_type& r, const rep_type & a);
00077       
00078       void  print(std::ostream & os, const rep_type & a)
00079       { R p; horner_to_monomial(p,a); UPOLDAR::print(os,p); }
00080       void  read (std::istream & is, rep_type & a);
00081     };
00082 
00084     template <class C, class R>
00085       void ModUPol<C,R>::add(rep_type & r,const rep_type & a, const rep_type& b)
00086       {
00087         r.resize(dim());  UPOLDAR::add(r,a,b);
00088       }
00089     
00091       template <class C, class R>
00092         void ModUPol<C,R>::add(rep_type & r,const rep_type & a)
00093         {
00094           r.resize(dim());  UPOLDAR::add(r,a);
00095         }
00096       
00098         template <class C, class R>
00099           void ModUPol<C,R>::sub(rep_type & r,const rep_type & a, const rep_type& b)
00100           {
00101             r.resize(dim());  UPOLDAR::sub(r,a,b);
00102           }
00103 
00105 template <class C, class R>
00106 void ModUPol<C,R>::sub(rep_type & r,const rep_type & a)
00107 {
00108   r.resize(dim());  UPOLDAR::sub(r,a);
00109 }
00110 
00112 template <class C, class R>
00113 void ModUPol<C,R>::square(rep_type & x,const rep_type & f)
00114 {
00115   assert(&x != &f);
00116 
00117   typedef typename R::value_type  value_type;
00118   typedef typename R::size_type   size_type;
00119 
00120   size_type degree = dim();
00121   size_type M = 2*degree;
00122 
00123   // Compute the convolution product poly * f,
00124   // by a product of the FFT of poly and f
00125   x.resize(M); VECTOR::init(x,0);
00126 
00127 #ifdef FFT
00128   UPOLDAR::mul_fft(x, poly, f);
00129 #else
00130   UPOLDAR::mul_index(x, poly, f);
00131   //  VECTOR::print(std::cout,x);std::cout<<std::endl;
00132 #endif
00133 
00134   // Change the signs of the last degree terms of poly*f
00135   for (size_type i = M-1; i>=degree; i--) x[i]*= value_type(-1);
00136 
00137   // Now, we compute the convolution of this result and f
00138   linalg::rep1d<value_type> res(M+degree-1);
00139 
00140 #ifdef FFT
00141   UPOLDAR::mul_fft(res,x,f);
00142 #else
00143   UPOLDAR::mul_index(res,x,f);
00144   //  VECTOR::print(std::cout,res);std::cout<<std::endl;
00145 #endif
00146 
00147   // We keep only the middle part.
00148   for (size_type j = 0, i = degree; i<M; i++,j++)
00149     x[j] = value_type(-1)*(res[i]);
00150 
00151   for(size_type i = degree; i<x.size();++i) x[i]=0;
00152 
00153   UPOLDAR::checkdegree(x);
00154   //      delete [] res;
00155 }
00156 
00157 //----------------------------------------------------------------------
00159 template <class C,class R>
00160 void ModUPol<C,R>::mul(rep_type & x, const rep_type & a, const rep_type& b)
00161 {
00162   typedef typename R::size_type   size_type;
00163   typedef typename R::value_type  value_type;
00164 
00165   size_type degree = dim();
00166   rep_type res(degree,type::AsSize()), temp(degree,type::AsSize());
00167 
00168   add(temp,a,b);
00169   square(x,temp);
00170   sub(temp,a,b);
00171   square(res,temp);
00172   sub(x,res);
00173   VECTOR::div_ext(x,value_type(4));
00174   //      delete [] res.tab_;
00175 }
00176 
00177 //----------------------------------------------------------------------
00184 template <class C, class R>
00185 template<class S>
00186 void ModUPol<C,R>::monomial_to_horner(rep_type &x, const S &  pol)
00187 {
00188   typedef typename R::value_type  value_type;
00189   typedef typename R::size_type   size_type;
00190   typedef typename R::rep_type    rep_type;
00191 
00192   size_type degree = dim();
00193   rep_type h1(2*degree-1, type::AsSize());
00194   h1[degree-1]=1/poly[degree];
00195   for (size_type i = degree; i < 2*degree-1; i++)
00196     {
00197       for(size_type j=0; j<degree; j++)
00198         h1[i] -= h1[i-degree+j]*poly[j];
00199       h1[i]/=poly[degree];
00200     }
00201   //VECTOR::print(std::cout,h1);std::cout<<std::endl;
00202 
00203   /* If x is expressed in the monomial basis and we want it in
00204      the Horner basis, we compute x = H1 * x. */
00205   MatrStr<linalg::hankel<value_type> >  P(degree, degree, h1.begin());
00206   rep_type tmp(pol.begin(),pol.end());
00207   tmp.resize(degree);
00208   x.resize(degree); VECTOR::init(x,0);
00209   using namespace MATRIX; mul_vect(x,P,tmp);
00210   //  VECTOR::print(std::cout,x);std::cout<<std::endl;
00211   VECTOR::reverse(x,degree);
00212 }
00213 
00214 //----------------------------------------------------------------------
00221 template <class C, class R>
00222 template<class S>
00223 void ModUPol<C,R>::horner_to_monomial(S &x, const rep_type &  pol)
00224 {
00225   typedef typename R::value_type  value_type;
00226   typedef typename R::size_type   size_type;
00227   typedef typename R::rep_type    rep_type;
00228 
00229   size_type degree = dim();
00230   rep_type h1(2*degree,type::AsSize());
00231   R r(degree,type::AsSize());
00232 
00233   /* if x is expressed in the Horner basis and we want it
00234      in the monomial basis, we compute x = P*x. */
00235   MatrStr<linalg::hankel<value_type> > P =bezout(poly);
00236   //  cout <<P<<endl;
00237   S tmp(pol.begin(),pol.end()); tmp.resize(degree);
00238   VECTOR::reverse(tmp,degree);
00239   x.resize(degree); VECTOR::init(x,0);
00240   using namespace MATRIX; mul_vect(x,P,tmp);
00241  }
00242 //----------------------------------------------------------------------
00243 } //namespace quotient
00244 __END_NAMESPACE_SYNAPS
00245 //----------------------------------------------------------------------
00246 #endif // SYNAPS_UPOL_MODUPOL_H
00247 

SYNAPS DOCUMENTATION
logo