00001 #ifndef SYNAPS_UPOL_EUCLIDIAN_H
00002 #define SYNAPS_UPOL_EUCLIDIAN_H
00003
00004 #include <synaps/init.h>
00005 #include <synaps/base/type.h>
00006 #include <synaps/arithm/pow.h>
00007 #include <synaps/upol/UPOLDAR.m>
00008
00009
00010 __BEGIN_NAMESPACE_SYNAPS
00011
00012
00014 namespace EUCLIDIAN
00015 {
00016 using UPOLDAR::lcoeff;
00017 using UPOLDAR::degree;
00018
00024 template<class R>
00025 void div_rem(R & q, R & a, const R & b)
00026 {
00027
00028 typedef typename R::iterator iterator;
00029 R t;
00030 typename R::value_type lb=b[degree(b)];
00031 q=0;
00032 while (degree(a)>=degree(b)) {
00033 typename R::value_type p = a[degree(a)]/lb;
00034 R m( a[degree(a)]/lb, degree(a)-degree(b) );
00035 t=b*m;
00036 t[degree(a)]=a[degree(a)];
00037 a-=t;
00038 q += m;
00039 }
00040 }
00041
00047 template<class R>
00048 void pseudo_div_rem(R & q, R & a, const R & b)
00049 {
00050 typedef typename R::iterator iterator;
00051 R t;
00052 typename R::value_type lb=b[degree(b)];
00053 q=0;
00054 while (degree(a)>=degree(b)) {
00055 R m(a[degree(a)],degree(a)-degree(b));
00056 t=b*m;
00057 a*=lb;
00058 t[degree(a)]=a[degree(a)];
00059 a-=t;
00060 q+=m;
00061 }
00062 }
00063
00064
00069 template<class Poly>
00070 void prem(const Poly& f, const Poly& g, Poly& q, Poly & r)
00071 {
00072 r = f * pow(lcoeff(g), degree(f) - degree(g) + 1);
00073 q = 0;
00074 while (degree(r) >= degree(g)) {
00075 int delta = degree(r) - degree(g);
00076 q = q + Poly(1,delta) * (lcoeff(r)/lcoeff(g));
00077 r = r - ( (g * Poly(1, delta)) * (lcoeff(r)/lcoeff(g)) );
00078 }
00079 return;
00080 }
00081
00082
00086 template<class Poly>
00087 Poly prem(const Poly& f, const Poly& g, Poly& q)
00088 {
00089 Poly r(f * pow(lcoeff(g), degree(f) - degree(g) + 1) );
00090 q = 0;
00091 while (degree(r) >= degree(g)) {
00092 int delta = degree(r) - degree(g);
00093 q = q + Poly(1,delta) * (lcoeff(r)/lcoeff(g));
00094 r = r - ( (g * Poly(1, delta)) * (lcoeff(r)/lcoeff(g)) );
00095 }
00096 return r;
00097 }
00098
00099
00103 template<class Poly>
00104 Poly prem(const Poly& f, const Poly& g)
00105 {
00106 Poly r(f * pow(lcoeff(g), degree(f) - degree(g) + 1) );
00107 Poly q = 0;
00108 while (degree(r) >= degree(g)) {
00109 int delta = degree(r) - degree(g);
00110
00111 r = r - ( (g * Poly(1, delta)) * (lcoeff(r)/lcoeff(g)) );
00112 }
00113 return r;
00114 }
00115
00119 template<class Poly>
00120 Poly pquo(const Poly& f, const Poly& g)
00121 {
00122 Poly r(f * pow(lcoeff(g), degree(f) - degree(g) + 1) );
00123 Poly q = 0;
00124 while (degree(r) >= degree(g)) {
00125 int delta = degree(r) - degree(g);
00126 q = q + Poly(1,delta) * (lcoeff(r)/lcoeff(g));
00127 r = r - ( (g * Poly(1, delta)) * (lcoeff(r)/lcoeff(g)) );
00128 }
00129 return q;
00130 }
00131
00132
00133
00134 template<class R>
00135 void div_pseudorem0(R & q, R & a, const R & b)
00136 {
00137 typedef typename R::iterator iterator;
00138 R t(degree(b)+1, type::AsSize());
00139 typename R::value_type lb=b[degree(b)];
00140 q=0;
00141 int c=0, dab =degree(a)-degree(b)+1;
00142 while (degree(a)>=degree(b)) {
00143 R m(a[degree(a)],degree(a)-degree(b));
00144 t=b*m;
00145 c++;
00146 a*=lb;
00147 t[degree(a)]=a[degree(a)];a-=t;
00148 q+=m;
00149 }
00150 a *= pow(lb, dab-c);
00151 }
00152
00153 }
00154
00155
00156
00157 __END_NAMESPACE_SYNAPS
00158
00159 #endif // SYNAPS_UPOL_EUCLIDIAN
00160