00001
00002
00003
00004
00005
00006
00007 #ifndef SYNAPS_UPOL_UPOLDSE_H
00008 #define SYNAPS_UPOL_UPOLDSE_H
00009 #include <synaps/init.h>
00010 #include <synaps/base/parser.h>
00011 #include <stdlib.h>
00012 #include <string>
00013 #include <synaps/arithm/let.h>
00014 #include <synaps/arithm/REF.h>
00015 #include <synaps/linalg/VECTOR.m>
00016 #include <synaps/upol/UPOLDAR.m>
00017 #include <synaps/upol/rep.h>
00018 #include <synaps/upol/EUCLIDIAN.h>
00019 #include <synaps/base/shared_object.h>
00020 #include <synaps/base/type.h>
00021
00022 __BEGIN_NAMESPACE_SYNAPS
00023
00025
00061 template<class C, class R=upol::rep<C> >
00062 struct UPolDse {
00063
00064 #ifdef NOREFCOUNT
00065 R data;
00066 R & rep() {return data;}
00067 const R & rep() const {return data;}
00068 #else
00069 shared_object<R> data;
00070 R & rep() {return *data;}
00071 const R & rep() const {return *data;}
00072 #endif
00073 typedef C value_type;
00074 typedef C coeff_t;
00075 typedef typename R::size_type size_type;
00076 typedef R rep_type;
00077 typedef typename R::iterator iterator;
00078 typedef typename R::const_iterator const_iterator;
00079 typedef typename R::reverse_iterator reverse_iterator;
00080 typedef typename R::const_reverse_iterator const_reverse_iterator;
00081 typedef UPolDse<C,R> self_t;
00082
00083 static char* var_;
00084
00085 UPolDse() : data() {}
00086 UPolDse(const R & r) {data(r);}
00087 UPolDse(const int n);
00088
00089 UPolDse(size_type n, type::AsSize A)
00090 {rep().resize(n);VECTOR::init(rep(),(value_type)0);}
00091 UPolDse(value_type c, size_type n = 0 );
00092 UPolDse(size_type n, value_type * t);
00093 UPolDse(iterator b, iterator e);
00094
00095 UPolDse(const char *);
00096 UPolDse(const self_t & P) {data=P.data;}
00097
00098 template<class S>
00099 UPolDse(const VAL<S> & P) {let::assign(*this,P.rep());}
00100
00101 iterator begin() {return rep().begin();}
00102 const_iterator begin() const {return rep().begin();}
00103 iterator end() {return rep().end();}
00104 const_iterator end() const {return rep().end();}
00105 reverse_iterator rbegin() {return rep().rbegin();}
00106 const_reverse_iterator rbegin() const {return rep().rbegin();}
00107 reverse_iterator rend() {return rep().rend();}
00108 const_reverse_iterator rend() const {return rep().rend();}
00109
00110 self_t & operator=(const self_t & P)
00111 {
00112 data=P.data;
00113
00114 return *this;
00115 }
00116
00117 template<class S>
00118 self_t & operator =(const VAL<S> & M)
00119 {let::assign(*this,M.rep());return *this;}
00120
00121 bool operator==(int n) const;
00122 bool operator!=(int n) const {return !(*this==n);}
00123
00124 bool operator==(const self_t & p) const;
00125 bool operator!=(const self_t & p) const {return !(*this==p);}
00126
00127 self_t & operator+= (const self_t & P);
00128 self_t & operator+= (const value_type & c);
00129
00130 self_t & operator-= (const self_t & P);
00131 self_t & operator-= (const value_type & c);
00132
00133 self_t & operator*= (const self_t & P);
00134 self_t & operator*= (const value_type & c);
00135
00136 self_t & operator/= (const self_t & Q);
00137 self_t & operator/= (const value_type & c);
00138
00139 self_t & operator%= (const self_t & Q);
00140 self_t & operator%= ( const value_type & x );
00141 int get_degree() const
00142 {
00143 using UPOLDAR::degree; return degree(rep());
00144 }
00145 size_type size() const { return (rep().size()); }
00146 void resize(size_type i) { rep().resize(i); }
00147
00148 inline value_type & operator[] (size_type i)
00149 {
00150 assert(i<size()); return (rep())[i];
00151 }
00152 inline value_type operator[] (size_type i) const
00153 {
00154 if(i< std::max((size_type)(this->get_degree()+1),(size_type)0))
00155 return (rep())[i]; else return 0;
00156 }
00157
00158 template<class T> T operator()(const T & c) const;
00159
00160 bool operator<( const value_type & c ) { return false; };
00161 };
00162 template<class C, class R> inline bool adjust_denum( const UPolDse<C,R> & ) { return false; };
00163
00164 template<class C,class R> char* UPolDse<C,R>::var_="x";
00168 template<class P> char*& Variable(void) {return P::var_;}
00169
00172 template <class C, class R> inline
00173 int degree(const UPolDse<C,R>& p)
00174 {
00175 using UPOLDAR::degree; return degree(p.rep());
00176 }
00177
00179 template <class C, class R> inline
00180 UPolDse<C,R> const diff(const UPolDse<C,R>& p)
00181 {
00182 if(degree(p)>0)
00183 {
00184 UPolDse<C,R> r(degree(p),type::AsSize());
00185 using UPOLDAR::diff; diff(r.rep(),p.rep());
00186 return r;
00187 }
00188 else
00189 return 0;
00190 }
00191
00193 template <class C, class R> inline
00194 UPolDse<C,R> const diff(const UPolDse<C,R>& p, unsigned int k)
00195 {
00196 if(degree(p)>(int)k-1)
00197 {
00198 UPolDse<C,R> r(p);
00199 using UPOLDAR::diff;
00200 for(unsigned i=0; i<k;++i) diff(r.rep(),r.rep());
00201 return r;
00202 }
00203 else
00204 return 0;
00205 }
00206
00207
00208
00209 #ifndef UPOL_WITH_TEMP_EXP
00210
00212 template <class C, class R> inline
00213 UPolDse<C,R> operator+(const UPolDse<C,R> & a, const UPolDse<C,R> & b)
00214 {
00215 UPolDse<C,R> result(std::max(degree(a),degree(b))+1, type::AsSize());
00216 using UPOLDAR::add; add(result.rep(),a.rep(),b.rep());
00217 using UPOLDAR::checkdegree; checkdegree(result.rep());
00218 return result;
00219 }
00220
00222 template <class C, class R>
00223 inline UPolDse<C,R>
00224 operator-(const UPolDse<C,R> & a, const UPolDse<C,R> & b)
00225 {
00226
00227 UPolDse<C,R> result(std::max(degree(a),degree(b))+1,type::AsSize());
00228 using UPOLDAR::sub; sub(result.rep(),a.rep(),b.rep());
00229 using UPOLDAR::checkdegree; checkdegree(result.rep());
00230 return result;
00231 }
00232
00234 template <class C, class R>
00235 inline UPolDse<C,R> operator-(const UPolDse<C,R> & a)
00236 {
00237 UPolDse<C,R> result(degree(a)+1,type::AsSize());
00238 using UPOLDAR::mul_ext; mul_ext(result.rep(),a.rep(),-1);
00239 return result;
00240 }
00241
00243 template <class C, class R> inline
00244 UPolDse<C,R> operator*(const UPolDse<C,R> & a, const UPolDse<C,R> & b)
00245 {
00246 UPolDse<C,R> result(std::max(degree(a)+degree(b)+1,0),type::AsSize());
00247 using UPOLDAR::mul; mul(result.rep(),a.rep(),b.rep());
00248 using UPOLDAR::checkdegree; checkdegree(result.rep());
00249 return result;
00250 }
00251
00253 template <class C, class R> inline
00254 UPolDse<C,R> operator+(const UPolDse<C,R> & a,
00255 const typename UPolDse<C,R>::value_type & c)
00256 {
00257 if(degree(a) >= 0)
00258 {
00259 UPolDse<C,R> r(a);
00260 using UPOLDAR::add_cst; add_cst(r.rep(),c);
00261 return r;
00262 }
00263 else
00264 return UPolDse<C,R>(c,1);
00265 }
00266
00268 template <class C, class R> inline
00269 UPolDse<C,R> operator+(const typename UPolDse<C,R>::value_type & c,
00270 const UPolDse<C,R> & a)
00271 {
00272 return a+c;
00273 }
00274
00276 template <class C, class R> inline
00277 UPolDse<C,R> operator-(const UPolDse<C,R> & a,
00278 const typename UPolDse<C,R>::value_type & c)
00279 {
00280 if(degree(a) >= 0)
00281 {
00282 UPolDse<C,R> r(a);
00283 using UPOLDAR::add_cst; add_cst(r.rep(),-c);
00284 return r;
00285 }
00286 else
00287 return UPolDse<C,R>(-c,1);
00288 }
00289
00291 template <class C, class R> inline
00292 UPolDse<C,R> operator-(const typename UPolDse<C,R>::value_type & c,
00293 const UPolDse<C,R> & a)
00294 {
00295 return (-a)+c;
00296 }
00297
00299 template <class C, class R> inline
00300 UPolDse<C,R> operator*(const UPolDse<C,R> & a,
00301 const typename UPolDse<C,R>::value_type & c)
00302 {
00303
00304 UPolDse<C,R> result(degree(a)+1,type::AsSize());
00305 using UPOLDAR::mul_ext;
00306 mul_ext(result.rep(),a.rep(),c);
00307 checkdegree(result.rep());
00308 return result;
00309 }
00310
00311
00313 template <class C, class R> inline
00314 UPolDse<C,R> operator*(const typename UPolDse<C,R>::value_type & c,
00315 const UPolDse<C,R> & a)
00316 {
00317
00318 return a*c;
00319 }
00320
00321
00322
00324 template <class C, class R> inline
00325 UPolDse<C,R> operator/(const UPolDse<C,R> & a, const UPolDse<C,R> & b)
00326 {
00327 assert(b!=0);
00328 UPolDse<C,R> result(0), tmp(a);
00329 EUCLIDIAN::div_rem(result,tmp,b);
00330 return result;
00331 }
00333 template <class C, class R> inline
00334 UPolDse<C,R> operator/(const UPolDse<C,R> & a,
00335 const typename UPolDse<C,R>::value_type & c)
00336 {
00337 assert(c!=0);
00338 UPolDse<C,R> result(degree(a)+1,type::AsSize());
00339 using namespace UPOLDAR;
00340 div_ext(result.rep(),a.rep(),c);
00341 checkdegree(result.rep());
00342 return result;
00343
00344 }
00345
00346
00348 template <class C, class R> inline
00349 UPolDse<C,R> operator%(const UPolDse<C,R> & a, const UPolDse<C,R> & b)
00350 {
00351 assert(b!=0);
00352 UPolDse<C,R> result(a);
00353 result %= b;
00354 return result;
00355 }
00356
00357 template <class C, class R> inline
00358 UPolDse<C,R> operator%(const UPolDse<C,R> & a, const C & b)
00359 {
00360 assert(b!=0);
00361 UPolDse<C,R> result(a);
00362 result %= b;
00363 return result;
00364 }
00365
00367 template <class C, class R> inline
00368 UPolDse<C,R> prem(const UPolDse<C,R> & a, const UPolDse<C,R> & b)
00369 {
00370 assert(b!=0);
00371 UPolDse<C,R> r(a), q;
00372 EUCLIDIAN::pseudo_div_rem(q,r,b);
00373 return r;
00374 }
00375
00377 template <class C, class R> inline
00378 UPolDse<C,R> operator^(const UPolDse<C,R> & a, const unsigned int & n)
00379 {
00380 UPolDse<C,R> result(1);
00381
00382 for(unsigned int i=0; i< n; i++) result *= a;
00383 return result;
00384 }
00385 #else
00386
00388 template <class C, class R>
00389 inline VAL<OP<'+',UPolDse<C,R>,UPolDse<C,R> > >
00390 operator+(const UPolDse<C,R> & a, const UPolDse<C,R> & b)
00391 {
00392 return VAL<OP<'+',UPolDse<C,R>,UPolDse<C,R> > >
00393 (OP<'+',UPolDse<C,R>,UPolDse<C,R> >(a,b));
00394 }
00395
00397 template <class C, class R>
00398 inline VAL<OP<'-',UPolDse<C,R>,UPolDse<C,R> > >
00399 operator-(const UPolDse<C,R> & a, const UPolDse<C,R> & b)
00400 {
00401 return VAL<OP<'-',UPolDse<C,R>,UPolDse<C,R> > >
00402 (OP<'-',UPolDse<C,R>,UPolDse<C,R> >(a,b));
00403 }
00404
00406 template <class C, class R>
00407 inline VAL<OP<'-',UPolDse<C,R>,UPolDse<C,R> > >
00408 operator-(const UPolDse<C,R> & a)
00409 {
00410 return VAL<OP<'-',UPolDse<C,R>,UPolDse<C,R> > >
00411 (OP<'-',UPolDse<C,R>,UPolDse<C,R> >(UPolDse<C,R>(0),a));
00412 }
00413
00415 template <class C, class R> inline
00416 VAL<OP<'*',UPolDse<C,R>,UPolDse<C,R> > >
00417 operator*(const UPolDse<C,R> & a, const UPolDse<C,R> & b)
00418 {
00419 return VAL<OP<'*',UPolDse<C,R>,UPolDse<C,R> > >
00420 (OP<'*',UPolDse<C,R>,UPolDse<C,R> >(a,b));
00421 }
00422
00424 template <class C, class R> inline
00425 VAL<OP<'.',UPolDse<C,R>,typename UPolDse<C,R>::value_type> >
00426 operator*(const UPolDse<C,R> & a, const typename UPolDse<C,R>::value_type & c)
00427 {
00428 typedef typename UPolDse<C,R>::value_type C;
00429 return VAL<OP<'.',UPolDse<C,R>,C> >(OP<'.',UPolDse<C,R>,C>(a,c));
00430 }
00431
00433 template <class C, class R> inline
00434 VAL<OP<'/',UPolDse<C,R>,UPolDse<C,R> > >
00435 operator/(const UPolDse<C,R> & a, const UPolDse<C,R> & b)
00436 {
00437 return VAL<OP<'/',UPolDse<C,R>,UPolDse<C,R> > >
00438 (OP<'/',UPolDse<C,R>,UPolDse<C,R> >(a,b));
00439 }
00440
00442 template <class C, class R> inline
00443 VAL<OP<'%',UPolDse<C,R>,UPolDse<C,R> > >
00444 operator%(const UPolDse<C,R> & a, const UPolDse<C,R> & b)
00445 {
00446 return VAL<OP<'%',UPolDse<C,R>,UPolDse<C,R> > >
00447 (OP<'%',UPolDse<C,R>,UPolDse<C,R> >(a,b));
00448 }
00449
00451 template <class C, class R> inline
00452 VAL<OP<'^',UPolDse<C,R>,unsigned int> >
00453 operator^(const UPolDse<C,R> & a, const unsigned int & n)
00454 {
00455 return VAL<OP<'^',UPolDse<C,R>,unsigned int> >
00456 (OP<'^',UPolDse<C,R>,unsigned int>(a,n));
00457 }
00458
00459
00460
00461 namespace let {
00462 template<class C, class R> inline
00463 void assign(UPolDse<C,R> & p,
00464 const OP<'+',UPolDse<C,R>, UPolDse<C,R> >& M)
00465 {
00466 assert(&(p.rep())!=&(M.op1.rep()));
00467 assert(&(p.rep())!=&(M.op2.rep()));
00468 p.rep().resize(std::max(degree(M.op1),degree(M.op2))+1);
00469 using namespace UPOLDAR;
00470 init(p.rep(),0);
00471 add(p.rep(),M.op1.rep(),M.op2.rep());
00472 checkdegree(p.rep());
00473 }
00474
00475
00476 template<class C, class R,class X> inline
00477 void assign(UPolDse<C,R> & p,
00478 const OP<'+',UPolDse<C,R>, VAL<X> >& M)
00479 {
00480 assert(&(p.rep())!=&(M.op1.rep()));
00481
00482 UPolDse<C,R> tmp=M.op2;
00483 p.rep().resize(std::max(degree(M.op1),degree(tmp))+1);
00484 using namespace UPOLDAR;
00485 init(p.rep(),0);
00486 add(p.rep(),M.op1.rep(),tmp);
00487 checkdegree(p.rep());
00488 }
00489
00490 template<class C, class R,class X> inline
00491 void assign(UPolDse<C,R> & p,
00492 const OP<'+',VAL<X>,UPolDse<C,R> >& M)
00493 {
00494 assert(&(p.rep())!=&(M.op2.rep()));
00495 UPolDse<C,R> tmp=M.op2;
00496 p.rep().resize(std::max(degree(M.op2),degree(tmp))+1);
00497 using UPOLDAR::init; init(p.rep(),0);
00498 using UPOLDAR::add; add(p.rep(),tmp,M.op2.rep());
00499 using UPOLDAR::checkdegree; checkdegree(p.rep());
00500 }
00501
00502 template<class C, class R> inline
00503 void assign(UPolDse<C,R> & p,
00504 const OP<'-',UPolDse<C,R>, UPolDse<C,R> >& M)
00505 {
00506 assert(&(p.rep())!=&(M.op1.rep())); assert(&(p.rep())!=&(M.op2.rep()));
00507 p.rep().resize(std::max(degree(M.op1),degree(M.op2))+1);
00508 using namespace UPOLDAR;
00509 init(p.rep(),0);
00510 sub(p.rep(),M.op1.rep(),M.op2.rep());
00511 checkdegree(p.rep());
00512 }
00513
00514 template<class C, class R> inline
00515 void assign(UPolDse<C,R> & p,
00516 const OP<'*',UPolDse<C,R>, UPolDse<C,R> >& M)
00517 {
00518 using namespace UPOLDAR;
00519 if( &(p.rep())==&(M.op1.rep()) || &(p.rep())==&(M.op2.rep()) )
00520 {
00521 UPolDse<C,R> tmp;
00522 tmp.rep().resize(std::max(degree(M.op1)+degree(M.op2)+1,0));
00523 init(tmp.rep(),0);
00524 mul(tmp.rep(),M.op1.rep(),M.op2.rep());
00525 p=tmp;
00526 }
00527 else
00528 {
00529 p.rep().resize(std::max(degree(M.op1)+degree(M.op2)+1,0));
00530 init(p.rep(),0);
00531 mul(p.rep(),M.op1.rep(),M.op2.rep());
00532 }
00533 }
00534
00535 template<class C, class R> inline
00536 void assign(UPolDse<C,R> & p,
00537 const OP<'.',UPolDse<C,R>,typename R::value_type>& M)
00538 {
00539 p.rep().resize(degree(M.op1)+1);
00540 using namespace UPOLDAR;
00541 mul_scalar(p.rep(),M.op1.rep(),M.op2);
00542 }
00543
00544 template<class C, class R> inline
00545 void assign(UPolDse<C,R> & p,
00546 const OP<'/',UPolDse<C,R>,UPolDse<C,R> >& M)
00547 {
00548 assert(M.op2!=0);
00549 UPolDse<C,R> top1(M.op1);
00550 using namespace EUCLIDIAN; div_rem(p,top1,M.op2);
00551 }
00552
00553 template<class C, class R> inline
00554 void assign(UPolDse<C,R> & r,
00555 const OP<'%',UPolDse<C,R>,UPolDse<C,R> >& M)
00556 {
00557 assert(M.op2!=0);
00558 r= M.op1;
00559 UPolDse<C,R> tmp;
00560 using namespace EUCLIDIAN; div_rem(tmp,r,M.op2);
00561 }
00562
00563 template<class C, class R> inline
00564 void assign(UPolDse<C,R> & r,
00565 const OP<'^',UPolDse<C,R>,unsigned int> M)
00566 {
00567 r=M.op1;
00568 for(unsigned int i=1;i<M.op2;i++) r*=M.op1;
00569 }
00570
00571 }
00572
00573 #endif //UPOL_WITH_TEMP_EXP
00574
00575 namespace let
00576 {
00577
00582 template<class C, class R, class D, class S> inline
00583 void assign(UPolDse<C,R> & u, const UPolDse<D,S> & P)
00584 {
00585
00586 u.resize(degree(P)+1);
00587 for(int k=0; k< u.size();++k) let::assign(u[k],P[k]);
00588 }
00589
00593 template<class POL, class C, class S>
00594 POL convert(const UPolDse<C,S> & P, type::As<POL>)
00595 {
00596 using let::assign;
00597 POL u(degree(P)+1, type::AsSize());
00598 assign(u,P);
00599 return u;
00600 }
00601 }
00602
00603
00604
00606 template <class C, class R> inline
00607 std::ostream & operator<<(std::ostream & os, const UPolDse<C,R> & p)
00608 {
00609 using UPOLDAR::print;
00610 return print(os,p.rep(),UPolDse<C,R>::var_);
00611 }
00612
00614 template <class C, class R>
00615 std::istream & operator>>(std::istream & is, UPolDse<C,R> & P);
00616
00617 template <class C, class R, class X>
00618 int SignAt(const UPolDse<C,R>& p, const X& x)
00619 {
00620 return sign(p(x));
00621 }
00622
00623 template<class C, class R>
00624 UPolDse<C,R>::UPolDse(int n)
00625 {
00626 if(n==0)
00627 resize(0);
00628 else
00629 {
00630 rep().resize(1);
00631 rep()[0]=n;
00632 checkdegree(rep());
00633 }
00634 }
00635
00637 template<class C, class R>
00638 UPolDse<C,R>::UPolDse(value_type c, size_type n)
00639 {
00640 using UPOLDAR::set_monomial; set_monomial(rep(),c,n);
00641 }
00642
00646 template<class C, class R>
00647 UPolDse<C,R>::UPolDse(size_type n, value_type * v)
00648 {
00649 rep().resize(n);
00650 iterator it=rep().begin(), iv=v;
00651 for(unsigned int i=0;i<n;i++) *it++=*iv++;
00652 using UPOLDAR::checkdegree; checkdegree(rep());
00653 }
00654
00658 template<class C, class R>
00659 UPolDse<C,R>::UPolDse(iterator b, iterator e)
00660 {
00661 rep().resize(std::distance(b,e));
00662 iterator it=rep().begin(), iv=b;
00663 while(iv != e) *it++=*iv++;
00664 using UPOLDAR::checkdegree; checkdegree(rep());
00665 }
00666
00670 template <class C, class R>
00671 UPolDse<C,R>::UPolDse(const char * s) {
00672 rep().resize(0);
00673 VECTOR::init(rep(),0);
00674 int n = strlen(s);
00675 if(s[n-1]==';')
00676 {
00677 synaps_input = new char[n+1];
00678 memcpy(synaps_input,s,n); synaps_input[n]='\0';
00679 synaps_inputlim = synaps_input + n;
00680 }
00681 else
00682 {
00683 synaps_input = new char[n+2];
00684 memcpy(synaps_input,s,n); synaps_input[n]=';'; synaps_input[n+1]='\0';
00685 synaps_inputlim = synaps_input + n+1;
00686 }
00687 synaps_inputptr = synaps_input;
00688
00689 self_t m(1);
00690 bool sign = true;
00691 bool first = true;
00692 int Ask=0;
00693 for (;;) {
00694 Ask = yylex();
00695 if (Ask == COEF) {
00696 value_type c;
00697 let::assign(c,yylval);
00698 m *= c;
00699 }
00700 else if (Ask == XID) {
00701 char * p = strchr(yylval,'^');
00702 if (p == NULL){
00703 m *= self_t(value_type(1),1);
00704 } else {
00705 p++;
00706 m *= self_t(value_type(1),atoi(p));
00707 }
00708 }
00709 else if (Ask == MULT);
00710 else if (Ask == SUM) {
00711 if (sign) {
00712 *this += m;
00713 m = self_t(1);
00714 }
00715 else {
00716 *this -= m;
00717 sign = true;
00718 m = self_t(1);
00719 }
00720 }
00721 else if (Ask == MINUS) {
00722 if (first)
00723 sign = false;
00724 else if (sign) {
00725 *this += m;
00726 sign = false;
00727 m = self_t(1);
00728 }
00729 else {
00730 *this -= m;
00731 m = self_t(1);
00732 }
00733 }
00734 else if (Ask == TERMINATOR) {
00735 if (sign)
00736 *this += m;
00737 else
00738 *this -= m;
00739 break;
00740 }
00741 first = false;
00742 }
00743 delete[] synaps_input;
00744 }
00745
00747 template<class C, class R> inline
00748 bool UPolDse<C,R>::operator==(int n) const
00749 {
00750 if(n==0 && degree(*this)<0)
00751 return(true);
00752 else{
00753 return( (degree(*this)==0) && ((*this)[0]==n) );
00754 }
00755 }
00756
00758 template<class C, class R> inline
00759 bool UPolDse<C,R>::operator==(const UPolDse<C,R> & p) const
00760 {
00761 return &(rep())== &p.rep();
00762 }
00763
00764 template<class C, class R> inline
00765 UPolDse<C,R> & UPolDse<C,R>::operator+= (const UPolDse<C,R> & P)
00766 {
00767 using UPOLDAR::add; add(rep(),P.rep());
00768 using UPOLDAR::checkdegree; checkdegree(rep());
00769 return *this;
00770 }
00771
00772 template<class C, class R> inline
00773 UPolDse<C,R>& UPolDse<C,R>::operator+=(const C& c)
00774 {
00775 if(degree(*this) >= 0)
00776 {
00777 using UPOLDAR::add_cst; add_cst(rep(),c);
00778 }
00779 else
00780 *this=UPolDse<C,R>(c,1);
00781 return *this;
00782 }
00783
00784 template<class C, class R> inline
00785 UPolDse<C,R> & UPolDse<C,R>::operator-= (const UPolDse<C,R> & P)
00786 {
00787 rep().resize(std::max(degree(*this),degree(P))+1);
00788 using UPOLDAR::sub; sub(rep(),P.rep());
00789 using UPOLDAR::checkdegree; checkdegree(rep());
00790 return *this;
00791 }
00792
00793 template<class C, class R> inline
00794 UPolDse<C,R>& UPolDse<C,R>::operator-=(const C& c)
00795 {
00796 if(degree(*this) >= 0)
00797 {
00798 using UPOLDAR::add_cst; add_cst(rep(),-c);
00799 }
00800 else
00801 *this=UPolDse<C,R>(c,1);
00802 return *this;
00803 }
00804
00805 template<class C, class R> inline
00806 UPolDse<C,R> & UPolDse<C,R>::operator*= (const UPolDse<C,R> & P)
00807 {
00808
00809 (*this)= (*this) * P;
00810 return (*this);
00811 }
00812
00813 template<class C, class R> inline
00814 UPolDse<C,R> & UPolDse<C,R>::operator*= (const typename UPolDse<C,R>::value_type & c)
00815 {
00816 if (c != 0)
00817 {
00818 using UPOLDAR::mul_ext; mul_ext(rep(),rep(),c);
00819 }
00820 else
00821 {
00822 rep().resize(0);
00823 }
00824 return *this;
00825 }
00826
00828 template<class C, class R> inline
00829 UPolDse<C,R> & UPolDse<C,R>::operator/= (const typename UPolDse<C,R>::value_type & c)
00830 {
00831 using namespace VECTOR; div_ext(rep(),rep(),c);
00832 return *this;
00833 }
00834
00836 template <class C, class R> inline
00837 UPolDse<C,R> & UPolDse<C,R>::operator/= (const UPolDse<C,R> & Q) {
00838 using namespace UPOLDAR;
00839 assert(Q!=0);
00840 if (*this ==0) return *this;
00841 if (&rep()==&Q.rep()) {*this=1;return *this;}
00842 UPolDse<C,R> quo(0);
00843 div_rem(quo,*this,Q);
00844 *this=quo;
00845 return *this;
00846 }
00847
00849 template <class C, class R> inline
00850 UPolDse<C,R> & UPolDse<C,R>::operator%= (const UPolDse<C,R> & Q)
00851 {
00852 assert(Q!=0);
00853 if (*this ==0) return *this;
00854 if (&rep()==&Q.rep()) {*this=0;return *this;}
00855 UPolDse<C,R> quo;
00856 EUCLIDIAN::div_rem(quo,*this,Q);
00857 return *this;
00858 }
00859
00860 template<class C, class R> inline
00861 UPolDse<C,R> & UPolDse<C,R>::operator%=( const C & c )
00862 {
00863 using namespace UPOLDAR;
00864 coeff_modulo(rep(),c);
00865 checkdegree(rep());
00866 return *this;
00867 };
00868
00869
00872 template <class C, class R> template<class T> inline
00873 T UPolDse<C,R>::operator()(const T & c) const
00874 {
00875 using UPOLDAR::eval;
00876 return eval(rep(),c);
00877 }
00878
00879
00880 template <class C, class R> inline
00881 std::istream & operator>>(std::istream & is, UPolDse<C,R> & P)
00882 {
00883 std::string s, ss = "";
00884 int p;
00885 for (;;) {
00886 is >> s;
00887 p = s.find(';');
00888 if (p == -1)
00889 ss += s;
00890 else {
00891 ss += s.substr(0,p+1);
00892 break;
00893 }
00894 }
00895 P = UPolDse<C,R>(ss.c_str());
00896 return is;
00897 }
00898
00899 template <class C, class R>
00900 std::ostream & print_as_coeff(std::ostream & os, const UPolDse<C,R> & p)
00901 {
00902 return os<<"+("<<p<<")";
00903 }
00904
00905 template<class C, class R>
00906 void checkdegree( UPolDse<C,R> & p )
00907 {
00908 using namespace UPOLDAR;
00909 checkdegree(p);
00910 };
00911
00912
00913
00914
00915 __END_NAMESPACE_SYNAPS
00916
00917 #include "traits.h"
00918
00919
00920 #endif // SYNAPS_UPOL_UPOLDSE_H
00921