00001
00002
00003
00004
00005
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
00023
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