00001 #ifndef realroot_MPOLDSE_MONOMIAL_C
00002 #define realroot_MPOLDSE_MONOMIAL_C
00003
00004 #include <realroot/monomial.hpp>
00005 #include <realroot/tensor_monomials.hpp>
00006 #include <realroot/tensor_convert.hpp>
00007 #include <iostream>
00008 namespace mmx {
00009
00010 #ifndef MMX_WITH_PLUS_SIGN
00011 #define MMX_WITH_PLUS_SIGN
00012 template<class X> inline bool with_plus_sign(const X& x) {return x>0;}
00013
00014 template<class C> inline bool with_plus_sign(const tensor::monomials<C>& x) {
00015 return true;
00016 }
00017 #endif //MMX_WITH_PLUS_SIGN
00018
00019 namespace tensor
00020 {
00021 template < class C > inline
00022 monomials < C >::monomials () {
00023
00024 int *szs = new int, *vrs= new int;
00025 szs[0] = 1;
00026 vrs[0] = 0;
00027 env = eenv(1, szs, vrs);
00028 data = vector_type (env.sz(),(C)0);
00029 data[0] = (C)0;
00030 }
00031 template < class C > inline
00032 monomials < C >::monomials (const eenv & e)
00033 {
00034 env = e;
00035 data = vector_type (e.sz());
00036 };
00037 template < class C > inline
00038 monomials < C >::monomials (const eenv & e, const C & c)
00039 {
00040 env = e;
00041 data = vector_type (e.sz(),c);
00042 };
00043 template < class C > inline
00044 monomials < C >::monomials (int v, int d)
00045 {
00046 int *szs = new int, *vrs= new int;
00047 szs[0] = d+1;
00048 vrs[0] = v;
00049 env = eenv(1, szs, vrs);
00050 data = vector_type (env.sz(),(C)0);
00051 data[env.sz()-1]= 1;
00052 }
00053
00054 template < class C > inline
00055 monomials < C >::monomials (const C& c, int d, unsigned v)
00056 {
00057 assert(d>=0);
00058 int *szs = new int, *vrs= new int;
00059 szs[0] = d+1;
00060 vrs[0] = v;
00061 env = eenv(1, szs, vrs);
00062 data = vector_type (env.sz(),(C)0);
00063 data[env.sz()-1]= c;
00064 }
00065
00066 template < class C > inline
00067 monomials < C >::monomials (int nvr, const int *szs, const int *vrs)
00068 {
00069 env = eenv(nvr, szs, vrs);
00070 data = vector_type (env.sz(),(C)0);
00071 };
00072 template < class C > inline
00073 monomials < C >::monomials (const C & x)
00074 { int szs = 1; new (this) monomials (1, &szs); data[0] = x; }
00075
00076 template < class C >
00077 void realloc (monomials < C > &mpl, const eenv & nenv)
00078 {
00079 if (!eenv::equal (mpl.env, nenv ))
00080 {
00081 monomials< C > tmp (nenv);
00082 mpl.swap (tmp);
00083 };
00084 };
00085
00086 template < class C > inline
00087 void clear ( monomials < C >& monoms ) { std::fill(monoms.begin(),monoms.end(),C(0)); };
00088 template < class C > inline
00089 void clear ( monomials < C > &mpl, const eenv & nenv)
00090 {
00091 if (mpl.env != nenv) {
00092 monomials < C > tmp (nenv, C (0));
00093 mpl.swap (tmp);
00094 } else
00095 clear(mpl);
00096 };
00097
00098 template < class C >
00099 bool varindex (int &lv, const monomials<C>& mpl, int gv)
00100 {
00101 return mpl.env.hasvar (lv, gv);
00102 }
00103
00104 template < class C > bool monomials < C >::operator== (const monomials & mpl) const
00105 {
00106 if (!eenv::equal (env, mpl.env))
00107 return false;
00108 unsigned *oadd = new unsigned[esz ()];
00109 eenv::oaddress (env, oadd, mpl.env, 0, 0);
00110 for (int i = 0; i < esz (); i++)
00111 if (data[i] != mpl[oadd[i]])
00112 {
00113 delete[]oadd;
00114 return false;
00115 };
00116 delete[]oadd;
00117 return true;
00118 };
00119
00120 template < class C >
00121 std::ostream & operator<< (std::ostream & o, const monomials < C > &mpl)
00122 {
00123 o << "monomials object:\n";
00124 o << "\t(addresses) o: " << &mpl << " e: " << mpl.env.data << "d: " << mpl.
00125 begin () << std::endl;
00126 o << "\t(eenv)" << mpl.env << std::endl;
00127 o << "\t(data)";
00128 array::print (o, mpl.data);
00129 o << std::endl;
00130 o << ":object monomials\n";
00131 return o;
00132 };
00133 template < class Result, class Coeff, class Parameters > inline
00134 void eval (Result & result, const monomials < Coeff > & monoms , const Parameters & parameters )
00135 {
00136
00137 vct::horner(result, monoms.begin (), monoms.size(), parameters, 1);
00138
00139 };
00140 template < class Result, class Coeff, class Parameters > inline
00141 void eval (Result & result, const monomials < Coeff > & monoms , const Parameters & parameters , unsigned n)
00142 {
00143
00144 levalm( result, monoms.begin (), monoms.env, parameters );
00145 };
00146
00147 template < class Result, class Coeff, class Parameters > inline
00148 void heval (Result & result, const monomials < Coeff > & monoms , const Parameters & parameters)
00149 {
00150 hevalm( result, monoms.begin (), monoms.env, parameters );
00151 };
00152
00153 template < class Result, class Coeff, class Parameters > inline
00154 void subs0 (Result *result, const monomials < Coeff > & monoms , const Parameters & parameters )
00155 {
00156 subs0m( result, monoms.begin (), monoms.env, parameters );
00157 };
00158
00159 template < class C >
00160 void extend (monomials < C > &mpl, const eenv & nenv)
00161 {
00162 if ( mpl.env != nenv )
00163 {
00164 unsigned *oadd = new unsigned[mpl.esz ()];
00165 eenv::oaddress (nenv, oadd, mpl.env, 0, 0);
00166 monomials < C > tmp (nenv);
00167 vct::icopy (tmp.begin (), oadd, mpl.esz (), mpl.begin ());
00168 delete[]oadd;
00169 mpl.swap (tmp);
00170 };
00171 };
00172
00173
00174 template < class X, class Y >
00175 void waddm (monomials < X > &mpla, const monomials < Y > &mplb)
00176 {
00177 assert (eenv::subset (mplb.env, mpla.env));
00178 unsigned *oadd = new unsigned[mplb.esz ()];
00179 eenv::oaddress (mpla.env, oadd, mplb.env, 0, 0);
00180 vct::ipadd (mpla.begin (), oadd, mplb.esz (), mplb.begin ());
00181 delete[]oadd;
00182 };
00183
00184 template < class X, class C > inline void
00185 add (monomials < X > &r, const monomials < X > &a, const C& c ) {
00186 add(r=a,c);
00187 }
00188
00189 template < class C > inline void
00190 add (monomials < C > &a, const C & x) {
00191 a[0] += x;
00192 }
00193
00194 template < class C > void
00195 add (monomials < C > &r, const C & c, const monomials < C > &a) {
00196 add(r,a,c);
00197 }
00198
00199 template < class C > inline
00200 void add (monomials < C > &r, const monomials < C > &a)
00201 {
00202 extend (r, eenv::common (r.env, a.env));
00203 waddm (r, a);
00204 }
00205
00206 template < class C > inline
00207 void add (monomials < C > &r, const monomials < C > &a, const monomials < C > &b)
00208 {
00209 if ( &r == &a ) { add(r,b); return; };
00210 if ( &r == &b ) { add(r,a); return; };
00211 realloc(r,eenv::common(a.env,b.env));
00212 unsigned *oadd = new unsigned[std::max(a.esz (),b.esz())];
00213 eenv::oaddress (r.env, oadd,a.env, 0, 0);
00214 vct::icopy(r.begin(),oadd,a.esz(),a.begin());
00215 eenv::oaddress(r.env,oadd,b.env,0,0);
00216 vct::ipadd (r.begin (), oadd,b.esz (), b.begin ());
00217 };
00218
00219 template < class C > inline
00220 void sub (monomials < C > &r, const monomials < C > &a, const monomials < C > &b)
00221 {
00222 if ( &r == &a ) { sub(r,b); return; };
00223 if ( &r == &b ) { monomials<C> tmp = b; sub(r,a,tmp); return; };
00224
00225 realloc(r,eenv::common(a.env,b.env));
00226 unsigned *oadd = new unsigned[std::max(a.esz (),b.esz())];
00227 eenv::oaddress (r.env, oadd,a.env, 0, 0);
00228 vct::icopy(r.begin(),oadd,a.esz(),a.begin());
00229 eenv::oaddress(r.env,oadd,b.env,0,0);
00230 vct::ipsub (r.begin (), oadd,b.esz (), b.begin ());
00231 };
00232
00233 template < class C > inline void
00234 sub (monomials < C > &mpl, const C & c, const monomials < C > &a) {
00235 add(mpl,a,-c);
00236 }
00237 template < class X, class Y >
00238 void wsubm (monomials < X > &mpla, const monomials < Y > &mplb)
00239 {
00240 assert (eenv::subset (mplb.env, mpla.env));
00241 unsigned *oadd = new unsigned[mplb.esz ()];
00242 eenv::oaddress (mpla.env, oadd, mplb.env, 0, 0);
00243 vct::ipsub (mpla.begin (), oadd, mplb.esz (), mplb.begin ());
00244 delete[]oadd;
00245 };
00246
00247 template < class X, class Y > inline
00248 void sub (monomials < X > &r, const monomials < Y > &a)
00249 {
00250 extend (r, eenv::common (r.env, a.env)), wsubm (r, a);
00251 }
00252
00253
00254 template < class X, class C > inline void
00255 sub (monomials < X > &r, const monomials < X > &a, const C& c )
00256 {
00257 r=a;sub(r,c);
00258 }
00259 template < class C , class X> inline
00260 void sub (monomials < C > &a, const X & x)
00261 {
00262 a[0] -= (C)x;
00263 }
00264
00265 template < class C > void mul (monomials < C > &r, const C & c)
00266 {
00267 vct::scmul (r.begin (), c, r.esz (), 1);
00268 };
00269
00270 template < class C > void div (monomials < C > &r, const C & c)
00271 {
00272 vct::scdiv (r.begin (), c, r.esz (), 1);
00273 };
00274
00275 template < class C > void mul (monomials < C > &r, const monomials < C > &a)
00276 {
00277
00278 conv(r,a);
00279 };
00280
00281
00282 template < class X, class Y, class Z > inline
00283 void mul (monomials < X > &r, const monomials < Y > &a, const monomials < Z > &b)
00284 {
00285 conv(r,a,b);
00286 };
00287
00288 template < class C > inline
00289 void mul (monomials < C > &a, const monomials < C > &b, const C & c)
00290 {
00291 mul (a = b, c);
00292 };
00293
00294 template < class C > inline void
00295 mul (monomials < C > &r, const C &c, const monomials < C > &a) {
00296 mul(r=a,c);
00297 };
00298
00299 template < class C > inline void
00300 div (monomials < C > &r, const monomials < C > &a, const C &c) {
00301 div(r=a,c);
00302 }
00303
00304 template<class OSTREAM, class C> OSTREAM&
00305 print( OSTREAM& os, const monomials<C>& mpl, const variables& Var = monom<C>::var) {
00306 typedef monom<C> monom_t;
00307 typedef typename monom<C>::container_t exponent_t;
00308 exponent_t tmp (mpl.env.mxvr()+1);
00309 const int *szs = mpl.szs ();
00310 const int *vrs = mpl.vrs ();
00311 bool notfirst = false;
00312 for (int i = 0; i < mpl.size(); i++)
00313 if (mpl[i] != 0)
00314 {
00315 int a, v;
00316 for (a = i, v = mpl.nvr () - 1; a; a /= szs[v], v--)
00317 tmp[vrs[v]] = a % szs[v];
00318 std::ostringstream sm;
00319 print(sm, monom_t (mpl[i], tmp), Var);
00320
00321 if ( sm.str()[0]!='-' && sm.str()[0]!='+' && notfirst) {
00322 os <<'+';
00323 }
00324 os<<sm.str().c_str();
00325 notfirst=true;
00326 };
00327 if(!notfirst) os << "0";
00328 return os;
00329 }
00330
00331 template<class SYNTAX, class C> void
00332 print_flatten( SYNTAX& out, const monomials<C>& mpl, const variables& Var = monom<C>::var) {
00333 typedef monom<C> monom_t;
00334 typedef typename monom<C>::container_t exponent_t;
00335 exponent_t tmp (mpl.env.mxvr()+1);
00336 const int *szs = mpl.szs ();
00337 const int *vrs = mpl.vrs ();
00338 for (int i = 0; i < mpl.size(); i++)
00339 if (mpl[i] != 0)
00340 {
00341 int a, v;
00342 for (a = i, v = mpl.nvr () - 1; a; a /= szs[v], v--)
00343 tmp[vrs[v]] = a % szs[v];
00344
00345 SYNTAX m = flatten(mpl[i]);
00346 for(int i=0;i<mpl.env.mxvr()+1;i++)
00347 m = m * pow(SYNTAX(Var[i].data()),flatten(tmp[i]));
00348 out+=m;
00349 }
00350 }
00351
00352
00353 template<class Coeff> inline int
00354 degree(const monomials<Coeff>& p) {
00355 int d=0;
00356 for(int i=0;i<p.nbvar();i++) d+= *(p.env.szs()+i)-1;
00357 return d;
00358 }
00359
00360 template<class Coeff> inline int
00361 degree(const monomials<Coeff>& p, int v) {
00362 return p.env.sz(v)-1;
00363 }
00364
00365
00366 template<class Coeff> inline int
00367 leading_variable(const monomials<Coeff>& p) {
00368 return 0;
00369 }
00370
00371 template<class Coeff> inline void
00372 diff( monomials<Coeff>& res, const monomials<Coeff>& src, int v ) {
00373 clear( res, eenv::diff(src.env,v));
00374
00375 mdiff( res.begin(), res.env, src.begin(), src.env, v );
00376 }
00377
00378 template < class C >
00379 template < class X, class O>
00380 monomials < C >::monomials (const sparse::monomial_seq< X, O > &imp)
00381 {
00382 env= eenv(imp);
00383 data= vector_type(env.sz (), (C)0);
00384
00385
00386
00387
00388 mpolfill(this->begin(),imp,env);
00389 };
00390
00391 template < class C, class O>
00392 void convert (monomials < C > &mpl, const sparse::monomial_seq< C, O> &imp)
00393 {
00394 mpl. ~ monomials < C > ();
00395 new (&mpl) monomials<C>(imp);
00396 };
00397
00398 template < class C, class O> void
00399 convert (sparse::monomial_seq< C, O> &pol, const monomials < C > &mpl) {
00400 typedef typename sparse::monomial_seq< C, O>::monom_t monom_t;
00401 typedef typename monom_t::container_t container_t;
00402 add(pol,C(0));
00403 container_t tmp (mpl.env.mxvr()+1);
00404 const int *szs = mpl.szs ();
00405 const int *vrs = mpl.vrs ();
00406 for (int i = 0; i < mpl.size(); i++)
00407 if (mpl[i] != 0)
00408 {
00409 int a, v;
00410 for (a = i, v = mpl.nvr () - 1; a; a /= szs[v], v--)
00411 tmp[vrs[v]] = a % szs[v];
00412 add(pol, monom_t (mpl[i], tmp));
00413 };
00414 }
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428 inline eenv face_env( const eenv& e, int lv ) {
00429 const int * eszs = e.szs();
00430 const int * evrs = e.vrs();
00431 const int envr = e.nvr();
00432 int szs[ envr ];
00433 int vrs[ envr ];
00434 int c = 0;
00435 for ( int v = 0; v < envr; v ++ ) if ( v != lv ) { szs[c] = eszs[v]; vrs[c++] = evrs[v]; };
00436 return eenv(c,szs,vrs);
00437 }
00438
00439 template<class C> inline
00440 void lface ( monomials<C>& f, const monomials<C>& src, int v )
00441 {
00442 lface( f.begin(), src.env, src.begin(), v );
00443 };
00444
00445 template<class C> inline
00446 void rface ( monomials<C>& f, const monomials<C>& src, int v )
00447 {
00448 rface( f.begin(), src.env, src.begin(), v );
00449 };
00450
00451
00452 template<class C> inline
00453 void face ( monomials<C>& f, const monomials<C>& src, int v, int n )
00454 {
00455 assert(n==0||n==1);
00456 eenv fenv(face_env(src.env,src.env.localv(v)));
00457 if ( f.env != fenv ) realloc( f, fenv );
00458 if ( n ) rface( f, src, src.env.localv(v) );
00459 else lface( f, src, src.env.localv(v) );
00460 };
00461
00462
00463 template<class C> inline
00464 void islice( monomials<C>& f, const monomials<C>& src, int v, int i )
00465 {
00466 slice( f.begin(), src.env, src.begin(), v );
00467 }
00468
00469 template<class C> inline
00470 void slice( monomials<C>& f, const monomials<C>& src, int v, int n )
00471 {
00472 assert(n==0||n==1);
00473 eenv fenv(slice(src.env,src.env.localv(v)));
00474 if ( f.env != fenv ) realloc( f, fenv );
00475 islice( f, src, src.env.localv(v),n);
00476 }
00477
00478 template<class C> inline
00479 const C monomials<C>::entry(std::vector<int> deg)
00480 {
00481 int * vvrs = vrs();
00482 int * sstr = str();
00483 int * sszs = szs() ;
00484
00485 int i,pos=0;
00486 for (i = 0; i < nvr() ; ++i)
00487 {
00488 std::cout<<"entry:" <<deg[i] << std::endl;
00489 if (deg[i] >= sszs[ vvrs[i] ] || deg[i]<0 ) return C(0);
00490 pos += deg[i]*sstr[ vvrs[i] ];
00491 }
00492 return data[pos];
00493 }
00494
00496 template<class C>
00497 void shift( monomials<C> & f, const C & t, const int & v )
00498 {
00499 std::vector<int> ind = std::vector<int>( f.nvr() );
00500 int s,k,j, i,pos =0;
00501
00502 int * vars = f.vrs();
00503 int * sstr = f.str();
00504 int * sszs = f.szs() ;
00505
00506 for (;;)
00507 {
00508 for ( s = sszs[v], j = 0; j <= s-2; j++ )
00509 for( k = s-2; k >= j; k-- )
00510 f.data[sstr[v]*k+ pos ] +=
00511 t*f.data[ sstr[v]*(1+k)+ pos ];
00512
00513
00514 for (i = 0; i < f.nvr() ; ++i)
00515 {
00516 if ( vars[i] != v )
00517 {
00518 ind[i] += 1;
00519 pos += sstr[i];
00520 } else continue;
00521
00522 if (ind[i] < sszs[i])
00523 break;
00524 ind[i] = 0;
00525 pos -= sszs[i]*sstr[i];
00526 }
00527 if (i == f.nvr() )
00528 break;
00529 }
00530 }
00531
00533 template<class C>
00534 void set_variable(monomials<C> & f, C t, int v )
00535 {
00536 std::vector<int> ind = std::vector<int>( f.nvr() );
00537 int k, i, pos =0;
00538
00539 int * vars = f.vrs();
00540 int * sstr = f.str();
00541 int * sszs = f.szs() ;
00542 C tmp;
00543
00544 for (;;)
00545 {
00546 tmp=0;
00547 for( k = sszs[v]-1; k !=-1; --k )
00548 {
00549 tmp *= t;
00550 tmp += f.data[sstr[v]*k + pos];
00551 f.data[sstr[v]*k + pos] = 0 ;
00552 }
00553 f.data[pos]=tmp;
00554
00555
00556 for (i = 0; i < f.nvr() ; ++i)
00557 {
00558 if ( vars[i] != v )
00559 {
00560 ind[i] += 1;
00561 pos += sstr[i];
00562 } else continue;
00563
00564 if (ind[i] < sszs[i])
00565 break;
00566 ind[i] = 0;
00567 pos -= sszs[i]*sstr[i];
00568 }
00569 if (i == f.nvr() )
00570 break;
00571 }
00572 }
00573
00574
00576 template<class C>
00577 void reciprocal( monomials<C> & f, const int & v)
00578 {
00579 std::vector<int> ind = std::vector<int>( f.nvr() );
00580 int s,i,pos =0;
00581
00582 int * vars = f.vrs();
00583 int * sstr = f.str();
00584 int * sszs = f.szs();
00585 int l= sszs[v]-1;
00586
00587 for (;;)
00588 {
00589 for ( s = 0 ; s <= l/2; s++ )
00590 std::swap(f.data[sstr[v]*s+pos], f.data[sstr[v]*(l-s)+pos] );
00591
00592
00593 for (i = 0; i < f.nvr() ; ++i)
00594 {
00595 if ( vars[i] != v )
00596 {
00597 ind[i] += 1;
00598 pos += sstr[i];
00599 } else continue;
00600
00601 if (ind[i] < sszs[i])
00602 break;
00603 ind[i] = 0;
00604 pos -= sszs[i]*sstr[i];
00605 }
00606 if (i == f.nvr() )
00607 break;
00608 }
00609 }
00610
00612 template<class C>
00613 void contraction( monomials<C> & f, const C & t, const int & v )
00614 {
00615 std::vector<int> ind = std::vector<int>( f.nvr() );
00616 int s,i,pos =0;
00617
00618 int * vars = f.vrs();
00619 int * sstr = f.str();
00620 int * sszs = f.szs();
00621
00622 for (;;)
00623 {
00624 for ( s = 0 ; s < sszs[v]; ++s )
00625 f.data[sstr[v]*s+pos] *= pow(t,s) ;
00626
00627
00628 for (i = 0; i < f.nvr() ; ++i)
00629 {
00630 if ( vars[i] != v )
00631 {
00632 ind[i] += 1;
00633 pos += sstr[i];
00634 } else continue;
00635
00636 if (ind[i] < sszs[i])
00637 break;
00638 ind[i] = 0;
00639 pos -= sszs[i]*sstr[i];
00640 }
00641 if (i == f.nvr() )
00642 break;
00643 }
00644 };
00645
00646 template<class C>
00647 void mins( monomials<C> & mm, monomials<C> & f, int v )
00648 {
00649 int p,k,i,j;
00650 int * sszs = f.szs() ;
00651 int * sstr = f.str() ;
00652
00653 for ( p = 0, k = 0; k < sszs[v]; k++, p += sstr[v] )
00654 {
00655 mm.data[k] = f.data[p];
00656 for ( i = 0; i < f.size(); i += sstr[v-1] )
00657 for ( j = i; j < i + sstr[v]; j ++ )
00658 if ( f.data[j+p] < mm[k] ) mm[k] = f.data[j+p];
00659 }
00660 }
00661
00662 template<class C>
00663 void maxs( monomials<C> & mm, monomials<C> & f, int v )
00664 {
00665
00666 int p,k,i,j;
00667 int * sszs = f.szs() ;
00668 int * sstr = f.str() ;
00669
00670 for ( p = 0, k = 0; k < sszs[v]; k++, p += sstr[v] )
00671 {
00672 mm.data[k] = f.data[p];
00673 for ( i = 0; i < f.size(); i += sstr[v-1] )
00674 for ( j = i; j < i + sstr[v]; j ++ )
00675 if ( f.data[j+p] > mm[k] ) mm[k] = f.data[j+p];
00676 }
00677 }
00678
00679
00680 template<class C>
00681 void rename_var(monomials<C> & f, const int & v, const int & n )
00682 {
00683 int * vr = f.vrs();
00684
00685 for (int i=0; i< f.nvr(); ++i)
00686 if (vr[i]==v) {
00687 vr[i]=n;
00688 break; }
00689 }
00690
00691 };
00692 }
00693 #endif