synaps/upol/gcd.h

00001 
00002 /********************************************************************
00003  *   This file is part of the source code of the SYNAPS library.
00004  *   Author(s): F.Carreras, B.Mourrain, O.Ruatta, C.Tanasescu
00005  *   $Id: Gcd.h,v 1.1 2005/07/11 08:12:26 mourrain Exp $
00006  ********************************************************************/
00007 #ifndef SYNAPS_UPOL_GCD_H
00008 #define SYNAPS_UPOL_GCD_H
00009 //--------------------------------------------------------------------
00010 #include <synaps/init.h>
00011 #include <synaps/upol.h>
00012 #include <synaps/upol/SturmSeq.h>
00013 #include <synaps/base/Debug_util.h>
00014 //--------------------------------------------------------------------
00015 
00016 __BEGIN_NAMESPACE_SYNAPS
00017 
00018 template<class C> void contentcoeff( C & a, const C & c ) { a = c; };
00019 template<class C, class POL>
00020 void contentcoeff( C & tmp, const POL & p)
00021 {
00022   //  typedef typename POL::value_type coeff_type;
00023   //  typedef typename POL::size_type size_type;
00024   tmp = C(0);
00025   int d = degree(p);
00026   for(int i = 0; i <= d; i++)
00027     {
00028       C b;
00029       contentcoeff(b,p[i]);
00030       if ( b != C(0) )
00031         {
00032           tmp = gcd(tmp,b);
00033         };
00034     };
00035 }
00036 template<class C, class UPOL> 
00037   C contentcoeff( const UPOL & p ) { C tmp; contentcoeff(tmp,p); return tmp; };
00041 template<class POL>
00042 typename POL::value_type content(const POL & p)
00043 {
00044   typedef typename POL::value_type coeff_type;
00045   typedef typename POL::size_type size_type;
00046   size_type d = degree(p);
00047   coeff_type tmp = p[0];
00048   for(size_type i = 1; i <= d; i++)
00049     tmp = gcd(tmp,p[i]);
00050   return  tmp;
00051 }
00055 template<class R>
00056 double content(const UPolDse<double, R > & p)
00057 {
00058   double r=1.;
00059   if (degree(p)>=0)
00060         r = p[degree(p)];
00061   return r;
00062 }
00063 
00064 
00069 template<class C, class R>
00070 UPolDse<C, R> gcd(const UPolDse<C, R> & P, const UPolDse<C, R> & Q)
00071 {
00072   typedef SturmSeq<C,UPolDse<C,R>,std::vector<UPolDse<C,R> > > stha_t;
00073   if ((degree(P) < 0))
00074         return Q;
00075   else if (degree(Q) < 0)
00076         return P;
00077   else if ((degree(P) == 0) || (degree(Q) ==0))
00078         return UPolDse<C,R>(1);
00079   else {
00080     stha_t s(P,Q,HABICHT());
00081     typename stha_t::reverse_iterator it = s.rep().rbegin();
00082     for(; (it!= s.rep().rend()) && (*it == 0) ; ++it);
00083     UPolDse<C,R> RES=*it;
00084     C tmp=content(RES);
00085     RES/=tmp;
00086     return RES;
00087   }
00088 }
00089 
00090 
00091 template<class C, class R>
00092 UPolDse<C,R> lcm(const UPolDse<C,R> & p, const UPolDse<C,R> & q)
00093 {
00094   return (p/gcd(p,q))*q;
00095 }
00096 
00097 
00098 template<class C> inline
00099 bool gcd_coeffs_stop(const C& p, const type::false_t & ) { return p == C(1); };
00100 template<class C> inline
00101 bool gcd_coeffs_stop(const C& p, const type::true_t &  ) { return degree(p) == 0; };
00102 template<class C> inline
00103 bool gcd_coeffs_stop(const C& p ) { return gcd_coeffs_stop(p, typename ispolynomial<C>::T() ); };
00104 
00105 template< typename C, class R >
00106 C gcd_coeffs( const UPolDse<C,R> & pol )
00107 {
00108   typedef UPolDse<C,R> polynom;
00109   typedef typename polynom::const_iterator iterator;
00110   typedef typename polynom::value_type coeff;
00111   coeff p;
00112   iterator b = pol.begin();
00113   ++b;
00114   p = gcd( *(pol.begin()), *b );
00115   ++b;
00116   while( b != pol.end() && ! gcd_coeffs_stop(p)  ) { 
00117     p = gcd(p,*b);
00118     ++b; 
00119   };
00120   
00121   if ( b != pol.end() ) return C(1); 
00122   
00123   return p;
00124 };
00125   
00126   
00127 
00128 
00129 __END_NAMESPACE_SYNAPS
00130 
00131 #endif // SYNAPS_UPOL_GCD_H
00132 

SYNAPS DOCUMENTATION
logo