synaps/upol/square_free.h

00001 /********************************************************************
00002  *   This file is part of the source code of the SYNAPS library.
00003  *   Author(s): F.Carreras, B.Mourrain, O.Ruatta, C.Tanasescu
00004  *   $Id: SquareFree.h,v 1.1 2005/07/11 08:12:26 mourrain Exp $
00005  ********************************************************************/
00006 #ifndef SYNAPS_UPOL_SQUAREFREE_H_
00007 #define SYNAPS_UPOL_SQUAREFREE_H_
00008 //--------------------------------------------------------------------
00009 #include <list>
00010 #include <vector>
00011 #include <synaps/init.h>
00012 #include <synaps/arithm/pow.h>
00013 #include <synaps/arithm/sign.h>
00014 #include <synaps/arithm/gmp.h>
00015 #include <synaps/base/Seq.h>
00016 #include <synaps/upol/UPolDse.h>
00017 #include <synaps/upol/gcd.h>
00018 
00019 
00020 __BEGIN_NAMESPACE_SYNAPS
00021 
00022 /*************************************************************************/
00026 template<class C>
00027 UPolDse<C> square_free(const UPolDse<C> & p)
00028 {
00029   if(p==0)
00030     return UPolDse<C>(0);
00031   else
00032     {
00033       typedef UPolDse<C> Pol;
00034       Pol h = p, dp = diff(h);
00035       Pol g = gcd(h,dp);
00036       h/=g;
00037       return h;
00038     }
00039 }
00040 /*************************************************************************/
00041 template<class C>
00042 UPolDse<UPolDse<C> > square_free(const UPolDse<UPolDse<C> > & p)
00043 {
00044   typedef UPolDse<UPolDse<C> > PolPol;
00045   typedef UPolDse<C> Pol;
00046   PolPol h = p;
00047   PolPol dp = diff(p);
00048   PolPol g = gcd(h,dp);
00049   if (degree(g) >= 0){
00050   C tmp = content(g[0]);
00051   for(int i=1;i <= degree(g);++i){
00052       tmp = gcd(tmp,content(g[i]));
00053   }
00054   for(int i=0;i<=degree(g);i++)
00055     g[i]/=tmp;
00056   }
00057   h/=g;
00058   return h;
00059 }
00060 
00061 /*************************************************************************/
00068 template < typename RT >
00069 Seq< UPolDse<RT> >
00070 square_free_factorisation( const UPolDse<RT>& f)
00071 {
00072 
00073   typedef UPolDse<RT>    Poly;
00074 
00075   Seq< Poly > res;
00076 
00077   res.resize( UPOLDAR::degree(f) );
00078 
00079   Poly df = UPOLDAR::diff(f);
00080 
00081   Poly c = gcd(f, df);
00082   
00083   if ( UPOLDAR::degree( c) <= 0) {
00084       res[0] = f;
00085       res.resize(1);
00086       return res;
00087   }
00088   
00089   int i = 1;
00090   int n = 0;
00091   Poly w = f / c;
00092   Poly y = df / c;
00093   Poly z = y - UPOLDAR::diff(w);
00094   Poly g;
00095   
00096   while ( true ) {
00097       g = gcd( w, z);
00098       if ( UPOLDAR::degree( g) > 0) {
00099           res[i] = g;
00100       }
00101       ++i;
00102       w /= g;
00103       y = z / g;
00104       z = y - UPOLDAR::diff( w);
00105       if ( UPOLDAR::degree(z) <= 0) break;
00106   }
00107   res[i] = w;
00108   res.resize(i+1);
00109   return res;
00110 }
00111 
00112 
00113 template < typename RT >
00114 Seq< UPolDse<RT> >
00115 square_free_factorization( const UPolDse<RT>& f, SturmSeq<RT>& sth)
00116 {
00117 
00118   typedef UPolDse<RT>    Poly;
00119   Seq< Poly > res;
00120 
00121   res.resize( UPOLDAR::degree(f) );
00122 
00123   Poly df = UPOLDAR::diff(f);
00124 
00125   Poly c;
00126   sth = SturmSeq<RT>( f / content(f), df, SUBRES());
00127 
00128   typename SturmSeq<RT>::reverse_iterator it = sth.rep().rbegin();
00129   
00130   for (int i = 0; i < sth.size(); ++i) {
00131     if ( degree( sth[i]) >= 0 )  sth[i] /= content(sth[i]);
00132   }
00133 
00134   for(; (it!= sth.rep().rend()) && (*it == 0) ; ++it);
00135   RT temp = content( *it);
00136   c = (*it) / temp;
00137   
00138   if ( UPOLDAR::degree(c) <= 0) {
00139       res[0] = f;
00140       res.resize(1);
00141       return res;
00142   }
00143   
00144   int i = 1;
00145   int n = 0;
00146 
00147   Poly w = f / c;
00148   Poly y = df / c;
00149   Poly z = y - UPOLDAR::diff(w);
00150   Poly g;
00151   
00152   while ( true ) {
00153       g = gcd( w, z);
00154       if ( UPOLDAR::degree( g) > 0) {
00155           res[i] = g;
00156       }
00157       ++i;
00158       w /= g;
00159       y = z / g;
00160       z = y - UPOLDAR::diff( w);
00161       if ( UPOLDAR::degree(z) <= 0) break;
00162   }
00163   res[i] = w;
00164   res.resize(i+1);
00165   return res;
00166 
00167 }
00168 
00169 __END_NAMESPACE_SYNAPS
00170 //--------------------------------------------------------------------
00171 #endif // SYNAPS_UPOL_SQUAREFREE_H_

SYNAPS DOCUMENTATION
logo