00001
00002
00003
00004
00005
00006
00007 #ifndef SYNAPS_MPOL_MONOM_H
00008 #define SYNAPS_MPOL_MONOM_H
00009
00010 #include <assert.h>
00011 #include <map>
00012 #include <string>
00013 #include <synaps/init.h>
00014 #include <synaps/base/COUNT.h>
00015 #include <synaps/base/shared_object.h>
00016 #include <synaps/base/type.h>
00017 #include <synaps/linalg/VECTOR.m>
00018 #include <synaps/arithm/REF.h>
00019 #include <synaps/mpol/MONOMIAL.m>
00020 #include <synaps/mpol/dynamicexp.h>
00021 #include <synaps/mpol/Variables.h>
00022
00023 __BEGIN_NAMESPACE_SYNAPS
00024
00026
00032 template <class C, class R=dynamicexp<unsigned> >
00033 struct Monom {
00034
00035
00036 C _coef;
00037 #ifdef SHARED_MONOM
00038 shared_object<R> _expt;
00039 R & rep() {return (*_expt);}
00040 const R & rep() const {return (*_expt);}
00041 typedef shared_object<R> exp_t;
00042 #else
00043 R _expt;
00044 R & rep() {return (_expt);}
00045 const R & rep() const {return (_expt);}
00046 typedef R exp_t;
00047 #endif
00048
00049 static Variables var;
00050
00051
00052
00053
00054
00055
00056
00057 typedef int index_t;
00058 typedef R container_t;
00059 typedef typename R::exponent_t exponent_t;
00060 typedef typename R::size_type size_type;
00061 typedef C coeff_t;
00062 typedef Monom<C,R> self_t;
00063
00064
00065 Monom(): _coef(),_expt()
00066 {
00067 rep().resize(0);
00068 }
00069 Monom(const C & c, const exp_t & r):_coef(c), _expt(r){}
00070 Monom(const C & c): _coef(c),_expt()
00071 {
00072 rep().resize(0);
00073 }
00074 Monom(int i):_coef(i), _expt()
00075 {
00076 rep().resize(0);
00077 }
00078 Monom(int i, int d);
00079 Monom(const std::string & s, int d, Variables& vars = Variables::default_ );
00080 Monom(const C & c, unsigned s, const type::AsSize & S):_coef(c),_expt(s){}
00081 Monom(const C & c, int i, int d =1);
00082 Monom(const C & c, int s, int *t):_coef(c), _expt(s){
00083 for(int i=0;i<s;i++) rep()[i]= t[i];
00084 }
00085
00086
00087 Monom(const Monom & m):_coef(m._coef),_expt(m._expt)
00088 {
00089
00090 }
00091
00092 template<class S>
00093 Monom(const VAL<S> & M)
00094 {
00095 assign(*this,M.rep());
00096 }
00097
00098
00099
00100
00101
00102 self_t & operator = (const self_t & m)
00103 {
00104
00105 _coef = m.coeff();
00106 _expt = m._expt;
00107 return *this;
00108 };
00109 template<class S>
00110 self_t & operator = (const VAL<S> & M)
00111 {
00112 assign(*this,M.rep()); return *this;
00113 }
00114
00115
00116 const C & coeff () const { return _coef; }
00117 C& coeff () { return _coef; }
00118
00119 void setcoeff (const C & c) { _coef = c; }
00120
00121 unsigned size() const { return rep().size(); }
00122 int nvars() const { return lvar(rep()); }
00123 int nbvar() const { return lvar(rep())+1; }
00124
00125 exponent_t operator[] (size_type i) const { return rep()[i]; }
00126
00127 self_t & setexpt (size_type i, exponent_t d)
00128 {rep().setExponent(i,d);return *this; }
00129
00130
00131 bool operator==(int n) const;
00132 bool operator!=(int n) const {return !(*this==n);}
00133
00134
00135 friend bool operator == (const self_t & m1, const self_t & m2) {
00136 return m1._coef == m2._coef && m1.rep() == m2.rep();
00137 }
00138
00139 friend bool operator != (const self_t & m1, const self_t & m2) {
00140 return !(m1 == m2);
00141 }
00142
00143 friend bool IsComparable (const self_t & m1, const self_t & m2){
00144 return m1.rep() == m2.rep();
00145 }
00146
00147
00148 self_t operator - () const {return self_t(-_coef,rep());}
00149 self_t & operator += (const self_t &);
00150 self_t & operator -= (const self_t &);
00151 self_t & operator *= (const self_t &);
00152 self_t & operator *= (const C &);
00153 self_t & operator /= (const C &);
00154
00155 };
00156
00157 template<class R,class O> Variables Monom<R,O>::var;
00158
00159
00160
00161
00162
00163 template <class R,class O>
00164 inline VAL<OP<'*',Monom<R,O>,Monom<R,O> > >
00165 operator*(const Monom<R,O> & a, const Monom<R,O> & b)
00166 {
00167 return VAL<OP<'*',Monom<R,O>,Monom<R,O> > >
00168 (OP<'*',Monom<R,O>,Monom<R,O> >(a,b));
00169 }
00170
00171 template <class R,class O>
00172 inline VAL<OP<'/',Monom<R,O>,Monom<R,O> > >
00173 operator/(const Monom<R,O> & a, const Monom<R,O> & b)
00174 {
00175 return VAL<OP<'/',Monom<R,O>,Monom<R,O> > >
00176 (OP<'/',Monom<R,O>,Monom<R,O> >(a,b));
00177 }
00178
00179
00180 namespace let
00181 {
00182 template<class C, class R> inline
00183 void assign( C & r, const Monom<C,R>& m )
00184 {
00185 r = m.coeff();
00186 };
00187 template<class C, class R> inline
00188 const C& convert( const Monom<C,R> & m, const type::As<C>& ) { return m.coeff(); };
00189 };
00190
00191 template <class C,class R> inline
00192 void assign(Monom<C,R> & a, const OP<'*',Monom<C,R>,Monom<C,R> > & M)
00193 {
00194 a.coeff() = (M.op1.coeff()*M.op2.coeff());
00195 if (a.coeff() !=0)
00196 {
00197 a.rep().reserve(std::max(M.op1.rep().size(),M.op2.rep().size()));
00198 using namespace VECTOR; add(a.rep(),M.op1.rep(),M.op2.rep());
00199 }
00200 else
00201 {
00202 erase(a.rep());
00203 }
00204 }
00205
00206 template <class R,class O> inline
00207 void assign(Monom<R,O> & res, const OP<'/',Monom<R,O>,Monom<R,O> > & M)
00208 {
00209 typedef typename Monom<R,O>::exponent_t exponent_t;
00210 if(M.op1.nvars()< M.op2.nvars())
00211 res= Monom<R,O>(0);
00212 else {
00213 res= Monom<R,O>(M.op1);
00214 res.coeff() /=M.op2.coeff();
00215 for (int i = 0; i <= M.op1.nvars() && res.coeff() !=0 ; ++i)
00216 if(M.op1[i] <M.op2[i])
00217 {
00218 res= Monom<R,O>(0);
00219 }
00220 else
00221 res.rep().setExponent(i,exponent_t(M.op1[i] - M.op2[i]));
00222 }
00223 }
00224
00225 template <class C, class R> inline
00226 typename R::degree_t degree(const Monom<C,R> & m)
00227 {
00228 return degree(m.rep());
00229 }
00230
00231 template<class M>
00232 M MGcd(const M & m1, const M & m2) {
00233 int d = Gcd(m1.coeff(),m2.coeff());
00234 M res(d);
00235 int v = Min(m1.nvars(),m2.nvars());
00236 for (int i = 0; i <= v; ++i)
00237 res.rep().setExponent(i, Min(m1[i],m2[i]));
00238 return res;
00239 }
00240
00241 template <class M>
00242 M div(const M & m1, const M & m2) {
00243 M res(1); res*=(m1.coeff()/m2.coeff());
00244 for (int i = 0; i <= m1.nvars(); ++i)
00245 res.rep().setExponent(i,m1[i] - m2[i]);
00246 return res;
00247 }
00248
00249 template <class M>
00250 M div_quo(const M & m1, const M & m2) {
00251 M res(1); res*=(m1.coeff()/m2.coeff());
00252 for (int i = 0; i <= m1.nvars(); ++i)
00253 res.rep().setExponent(i,m1[i] - m2[i]);
00254 return res;
00255 }
00256
00257
00258
00260 template <class C, class R>
00261 Monom<C,R>::Monom(int i, int d):_coef(1)
00262 {
00263 if(d == 0)
00264 rep().resize(0);
00265 else
00266 {
00267 rep().reserve(i+1);
00268 for(int j=0;j<i;j++) rep().setExponent(j,0);
00269 rep().setExponent(i,d);
00270 }
00271 }
00272
00273
00275 template <class C, class R>
00276 Monom<C,R>::Monom(const std::string & s, int d,
00277 Variables& vars ):_coef(1)
00278 {
00279 if(d == 0)
00280 rep().resize(0);
00281 else
00282 {
00283 int i=vars[s];
00284
00285 rep().reserve(i+1);
00286 for(int j=0;j<i;j++) rep().setExponent(j,0);
00287 rep().setExponent(i,d);
00288 }
00289 }
00290
00291
00293 template <class C, class R>
00294 Monom<C,R>::Monom(const C & c, int i, int d ):_coef(c)
00295 {
00296 if(d == 0)
00297 rep().resize(0);
00298 else
00299 {
00300 rep().reserve(i+1);
00301 for(int j=0;j<i;j++) rep().setExponent(j,0);
00302 rep().setExponent(i,d);
00303 }
00304 }
00305
00306
00307
00308 template <class C, class R> inline
00309 bool Monom<C,R>::operator== (int n) const
00310 {
00311 return (coeff()==n);
00312 }
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357 template <class C, class R> inline
00358 Monom<C,R> & Monom<C,R>::operator += (const Monom<C,R> & m)
00359 {
00360 coeff() += m.coeff();
00361 if (coeff()==0) erase(rep());
00362 return *this;
00363 }
00364
00365 template <class C, class R> inline
00366 Monom<C,R> & Monom<C,R>::operator -= (const Monom<C,R> & m)
00367 {
00368 coeff() -= m.coeff();
00369 if (coeff()==0) erase(rep());
00370 return *this;
00371 }
00372
00373 template <class C, class R> inline
00374 Monom<C,R> operator + (const Monom<C,R> & m1, const Monom<C,R> & m2)
00375 {
00376 Monom<C,R> res(m1);
00377 res.coeff() += m2.coeff();
00378 return (*res);
00379 }
00380
00381 template <class C, class R> inline
00382 Monom<C,R> operator - (const Monom<C,R> & m1, const Monom<C,R> & m2)
00383 {
00384 Monom<C,R> res(m1);
00385 res.coeff() -= m2.coeff();
00386 return (res);
00387 }
00388
00389 template <class C, class R> inline
00390 Monom<C,R> & Monom<C,R>::operator *= (const Monom<C,R> & m)
00391 {
00392 using namespace VECTOR;
00393 coeff() *= m.coeff();
00394 if (coeff()!=0)
00395 add(rep(),m.rep());
00396 else
00397 erase(rep());
00398 return *this;
00399 }
00400
00401 template <class C, class R> inline
00402 Monom<C,R> & Monom<C,R>::operator *= (const C & c)
00403 {
00404 coeff() *= c;
00405 if (coeff()==0) erase(rep());
00406 return *this;
00407 }
00408
00409 template <class C, class R> inline
00410 Monom<C,R> & Monom<C,R>::operator /= (const C & c)
00411 {
00412 assert(c !=0);
00413 coeff() /= c;
00414 if (coeff()==0) erase(rep());
00415 return *this;
00416 }
00417
00418 template <class C, class R> inline
00419 Monom<C,R> operator * (const Monom<C,R> & m1, const C & c2)
00420 {
00421 Monom<C,R> res(m1);
00422 res.coeff() *= c2;
00423 if (res.coeff() ==0) erase(res.rep());
00424 return (res);
00425 }
00426 template <class C, class R> inline
00427 Monom<C,R> operator * (const C & c2, const Monom<C,R> & m1)
00428 {
00429 return(m1*c2);
00430 }
00431
00432 template <class C, class R> inline
00433 Monom<C,R> operator / (const Monom<C,R> & m1, const C & c2)
00434 {
00435 Monom<C,R> res(m1);
00436 res.coeff() /= c2;
00437 if (res.coeff() ==0) erase(res.rep());
00438 return (res);
00439 }
00440
00441
00442
00443
00444
00446 template <class C, class R> inline
00447 std::ostream & operator << (std::ostream & os, const Monom <C,R> & m)
00448 {
00449 if (m.coeff() ==0 ) os<<"(0)";
00450 else {
00451 MONOMIAL::print(os,m);
00452 }
00453 return os;
00454 }
00455
00456 __END_NAMESPACE_SYNAPS
00457
00458 #endif // SYNAPS_MPOL_MONOM_H
00459