00001 #ifndef realroot_ARITHM_INTERVAL_C
00002 #define realroot_ARITHM_INTERVAL_C
00003
00004 #include <string.h>
00005 #include <string>
00006 #include <realroot/texp_sup.hpp>
00007 namespace mmx {
00008
00009 #ifndef MMX_SIGN_FCT
00010 #define MMX_SIGN_FCT
00011 template<typename T> inline
00012 int sign(const T& x) {return ( x < T(0) ? -1 : (T(0) < x ? 1 : 0) ); }
00013 #endif
00014
00015 template<class C, int r> inline bool
00016 with_plus_sign(const Interval<C,r> & I) { return true;}
00017
00018 namespace numerics
00019 {
00020 template<class T, int r>
00021 struct interval_base
00022 {
00023 struct rnd{};
00024 inline static T dwmul( const T& a, const T& b ) { return a*b; };
00025 inline static T upmul( const T& a, const T& b ) { return a*b; };
00026 inline static T dwdiv( const T& a, const T& b ) { return a/b; };
00027 inline static T updiv( const T& a, const T& b ) { return a/b; };
00028 inline static T dwadd( const T& a, const T& b ) { return a+b; };
00029 inline static T upadd( const T& a, const T& b ) { return a+b; };
00030 inline static T dwsub( const T& a, const T& b ) { return a-b; };
00031 inline static T upsub( const T& a, const T& b ) { return a-b; };
00032 };
00033
00034 template<class T>
00035 struct interval_base<T,2> : interval_base<T,0>
00036 {
00037 struct rnd{};
00038 inline static T dwmul( const T& a, const T& b ) { return rup::dwmul(a,b); };
00039 inline static T dwdiv( const T& a, const T& b ) { return rup::dwdiv(a,b); };
00040 inline static T dwadd( const T& a, const T& b ) { return rup::dwadd(a,b); };
00041 inline static T dwsub( const T& a, const T& b ) { return rup::dwsub(a,b); };
00042 };
00043
00044 template<class T>
00045 struct interval_base<T,1> : interval_base<T,0>
00046 {
00047 struct rnd{};
00048 inline static T upmul( const T& a, const T& b ) { return rdw::upmul(a,b); };
00049 inline static T updiv( const T& a, const T& b ) { return rdw::updiv(a,b); };
00050 inline static T upadd( const T& a, const T& b ) { return rdw::upadd(a,b); };
00051 inline static T upsub( const T& a, const T& b ) { return rdw::upsub(a,b); };
00052 };
00053
00054 template<class T>
00055 struct interval_base<T,3> : interval_base<T,1>
00056 {
00057 struct rnd : numerics::rounding<T>
00058 {
00059 rnd() : numerics::rounding<T>( numerics::rounding<T>::rnd_dw() ) {};
00060 };
00061 };
00062 };
00063
00064 template<class T, int r> struct Interval;
00065 namespace let
00066 {
00067 template<class T, int r>
00068 void assign( Interval<T,r>& i, const char * s );
00069 };
00070
00071 template<class C, int r> inline
00072 Interval<C,r>::Interval() : m(0), M(0) {};
00073 template<class C, int r> inline
00074 Interval<C,r>::Interval( int n ) :m(n), M(n) {};
00075 template<class C, int r> inline
00076 Interval<C,r>::Interval( unsigned n ) :m(n), M(n) {};
00077 template<class C, int r> inline
00078 Interval<C,r>::Interval( const C& x ): m(x), M(x) {};
00079 template<class C, int r> inline
00080 Interval<C,r>::Interval( const C& a, const C& b ) {
00081 if ( a > b ) m = b, M = a;
00082 else m = a, M = b;
00083 };
00084 template<class C, int r> inline
00085 Interval<C,r>::Interval( const char * s ) { let::assign(*this,s); };
00086 template<class T, int r> inline
00087 T lower ( const Interval<T,r>& x ) { return x.lower(); };
00088 template<class T, int r> inline
00089 T upper ( const Interval<T,r>& x ) { return x.upper(); };
00090 template<class T, int r> inline
00091 T median( const Interval<T,r>& x ) { return (lower(x)+upper(x))/T(2); };
00092 template<class T, int r> inline
00093 T width( const Interval<T,r>& x ) { return x.width(); };
00094 template<class T, int r> inline
00095 bool singleton( const Interval<T,r>& x ) { return x.lower() == x.upper(); };
00096 template<class T, int r> inline
00097 bool contain_zero( const Interval<T,r>& x )
00098 { return x.lower() <= static_cast<T>(0) && x.upper() >= static_cast<T>(0); };
00099 template<class T, int r> inline
00100 bool in( const T& x, const Interval<T,r>& y )
00101 { return y.lower() <= x && x <= y.upper(); };
00102 template<class T, int r> inline
00103 std::pair< Interval<T,r>, Interval<T,r> >
00104 bissect(const Interval<T,r>& x)
00105 {
00106 typedef Interval<T,r> I;
00107 const T m(median(x));
00108 return std::pair<I,I>(I(x.lower(), m), I(m, x.upper()));
00109 }
00110
00111 template<class T, int r> inline void
00112 bissect( Interval<T,r>& g, Interval<T,r>& d, const Interval<T,r>& x )
00113 {
00114 const T m(median(x));
00115 g.define( x.lower(), m );
00116 d.define( m, x.upper() );
00117 };
00118
00119 template<class T, int r> inline void
00120 hull( Interval<T,r>& v, const Interval<T,r>& a, const Interval<T,r>& b ) {
00121 v.define( std::min( a.lower(), b.lower() ), std::max( a.upper(), b.upper() ) );
00122 };
00123
00124 template<class T, int r> inline Interval<T,r>
00125 hull( const Interval<T,r>& a, const Interval<T,r>& b ) {
00126 return Interval<T,r>( std::min(a.lower(),b.lower()), std::max(a.upper(),b.upper()) );
00127 };
00128
00129 template<class T, int r> inline bool
00130 intersectp( const Interval<T,r>& a, const Interval<T,r>& b ) {
00131 return lower(a) <= upper(b) && lower(b) <= upper(a);
00132 };
00133
00134 template<class T, int r > inline Interval<T,r>
00135 intersection( const Interval<T,r>& a, const Interval<T,r>& b ) {
00136 return Interval<T,r>(std::max(lower(a),lower(b)),std::min(upper(a),upper(b)));
00137 };
00138
00139 template<class T, int r> inline bool
00140 intersect( Interval<T,r>& result,
00141 const Interval<T,r>& a, const Interval<T,r>& b ) {
00142 if ( intersectp( a, b ) )
00143 {
00144 result.define(std::max(lower(a),lower(b)),std::min(upper(a),upper(b)));
00145 return true;
00146 };
00147 return false;
00148 };
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163 template<class T, int r>
00164
00165 T size( const Interval<T,r>& i ) { return i.size(); };
00166
00167 template<class T, int r>
00168 std::ostream& operator<<( std::ostream& o, const Interval<T,r>& i )
00169 {
00170 o << "[" << (i.lower()) << ", " << (i.upper()) << "]";
00171 return o;
00172 };
00173
00174 template<class C, int r >
00175 void abs( Interval<C,r>& x, const Interval<C,r>& a )
00176 {
00177 if ( a.upper() > -a.lower() )
00178 {
00179 x.upper() = a.upper();
00180 x.lower() = std::max(-a.lower(),0);
00181 }
00182 else
00183 {
00184 x.upper() = -a.lower();
00185 x.lower() = a.upper();
00186 };
00187 };
00188
00189 template<class C, int r> inline void
00190 neg( Interval<C,r>& a )
00191 {
00192 C sv(a.M);
00193 a.M = -a.m;
00194 a.m = -sv;
00195 };
00196
00197 template<class C, int r> inline void
00198 neg( Interval<C,r>& a, const Interval<C,r>& b )
00199 {
00200 a.M = -b.m;
00201 a.m = -b.M;
00202 };
00203
00204 template<class C, int r> inline void
00205 add( Interval<C,r>& a, const C& x )
00206 {
00207 a.m = a.dwadd(a.m,x);
00208 a.M = a.upadd(a.M,x);
00209 };
00210
00211
00212 template<class C, int r> inline void
00213 add( Interval<C,r>& a, const Interval<C,r>& b, const C& x ) {
00214 a.m = a.dwadd(b.m,x); a.M = a.upadd(b.M,x); };
00215
00216 template<class C, int r> inline void
00217 add( Interval<C,r>& a , const C& x , const Interval<C,r>& b ) {
00218 add(a,b,x); };
00219
00220 template<class C, int r> inline void
00221 sub( Interval<C,r>& a, const C& x ) {
00222 a.m = a.dwsub(a.m,x); a.M = a.upsub(a.M,x); };
00223
00224 template<class C, int r> inline void
00225 sub( Interval<C,r>& a, const Interval<C,r>& b, const C& x ) {
00226 a.m = a.dwsub(b.m,x); a.M = a.upsub(b.M,x); };
00227
00228 template<class C, int r> inline void
00229 sub( Interval<C,r>& a, const C& x , const Interval<C,r>& b ) {
00230 a.m = a.dwsub(x,b.M); a.M = a.upsub(x,b.m); };
00231
00232 template<class C, int r> inline void
00233 add( Interval<C,r>& a, const Interval<C,r>& x ) {
00234 a.m = a.dwadd(a.m,x.m); a.M = a.upadd(a.M,x.M); };
00235
00236 template<class C, int r> inline void
00237 add( Interval<C,r>& a, const Interval<C,r>& b, const Interval<C,r>& x ) {
00238 a.m = a.dwadd(b.m,x.m); a.M = a.upadd(b.M,x.M); };
00239
00240 template<class C, int r> inline void
00241 sub( Interval<C,r>& a, const Interval<C,r>& x ) {
00242 a.m = a.dwsub(a.m,x.M); a.M = a.upsub(a.M,x.m); };
00243
00244 template<class C, int r> inline void
00245 sub( Interval<C,r>& a, const Interval<C,r>& b, const Interval<C,r>& x ) {
00246 a.m = a.dwsub(b.m,x.M); a.M = a.upsub(b.M,x.m); };
00247
00248 template<class C, int r> inline void
00249 mul( Interval<C,r>& a, const C& x ) {
00250 if ( x > 0 )
00251 {
00252 a.m = a.dwmul(a.m,x);
00253 a.M = a.upmul(a.M,x); }
00254 else
00255 {
00256 C sv(a.m);
00257 a.m = a.dwmul(a.M,x);
00258 a.M = a.dwmul(sv,x);
00259 };
00260 };
00261
00262
00263 template<class C, int r> inline void
00264 mul( Interval<C,r>& a, const Interval<C,r>& b, const C& x ) {
00265 if ( &a == &b ) { mul(a,x); return; };
00266 if ( x > 0 )
00267 {
00268 a.m = a.dwmul(b.m,x);
00269 a.M = a.upmul(b.M,x);
00270 }
00271 else
00272 {
00273 a.m = a.dwmul(b.M,x);
00274 a.M = a.dwmul(b.m,x);
00275 };
00276 };
00277
00278 template<class C, int r> inline void
00279 mul( Interval<C,r>& a, const C& x, const Interval<C,r>& b ) {
00280 mul(a,b,x); };
00281
00282
00283 template<class C, int r> inline void
00284 mul( Interval<C,r>& a, const Interval<C,r>& b ) {
00285 if ( a.m > 0 )
00286 {
00287 if ( b.m > 0 )
00288 {
00289 a.m = a.dwmul(a.m,b.m);
00290 a.M = a.upmul(a.M,b.M);
00291 return;
00292 };
00293 if ( b.M < 0 )
00294 {
00295 C sv(a.m);
00296 a.m = a.dwmul(a.M,b.m);
00297 a.M = a.upmul(sv,b.M);
00298 return;
00299 };
00300 a.m = a.dwmul(a.M,b.m);
00301 a.M = a.upmul(a.M,b.M);
00302 return;
00303 };
00304
00305 if ( a.M < 0 )
00306 {
00307 if ( b.m > 0 )
00308 {
00309 a.m = a.dwmul(b.M,a.m);
00310 a.M = a.upmul(b.m,a.M);
00311 return;
00312 };
00313 if ( b.M < 0 )
00314 {
00315 C sv(a.m);
00316 a.m = a.dwmul(a.M,b.M);
00317 a.M = a.upmul(sv,b.m);
00318 return;
00319 };
00320 C sv(a.m);
00321 a.m = a.dwmul(a.m,b.M);
00322 a.M = a.upmul(sv,b.m);
00323 return;
00324 };
00325
00326 if ( b.m > 0 )
00327 {
00328 a.m = a.dwmul(a.m,b.M);
00329 a.M = a.upmul(a.M,b.M);
00330 return;
00331 }
00332 if ( b.M < 0 )
00333 {
00334 C sv(a.m);
00335 a.m = a.dwmul(a.M,b.m);
00336 a.M = a.upmul(sv,b.m);
00337 return;
00338 };
00339
00340 C m0(a.dwmul(a.M,b.m));
00341 C m1(a.dwmul(a.m,b.M));
00342 if ( m0 > m1 ) m0 = m1;
00343 C M0(a.upmul(a.M,b.M));
00344 C M1(a.upmul(a.m,b.m));
00345 if ( M0 < M1 ) M0 = M1;
00346 a.m = m0;
00347 a.M = M0;
00348
00349 };
00350
00351 template<class C, int r> inline void
00352 mul( Interval<C,r>& x, const Interval<C,r>& a, const Interval<C,r>& b ) {
00353 if ( &x == &a ) { mul(x,b); return; };
00354 if ( &x == &b ) { mul(x,a); return; };
00355
00356 if ( a.m > 0 )
00357 {
00358 if ( b.m > 0 )
00359 {
00360 x.m = a.dwmul(a.m,b.m);
00361 x.M = a.upmul(a.M,b.M);
00362 return;
00363 };
00364 if ( b.M < 0 )
00365 {
00366 x.m = a.dwmul(a.M,b.m);
00367 x.M = a.upmul(a.m,b.M);
00368 return;
00369 };
00370 x.m = a.dwmul(a.M,b.m);
00371 x.M = a.upmul(a.M,b.M);
00372 return;
00373 };
00374
00375 if ( a.M < 0 )
00376 {
00377 if ( b.m > 0 )
00378 {
00379 x.m = a.dwmul(b.M,a.m);
00380 x.M = a.upmul(b.m,a.M);
00381 return;
00382 };
00383 if ( b.M < 0 )
00384 {
00385 x.m = a.dwmul(a.M,b.M);
00386 x.M = a.upmul(a.m,b.m);
00387 return;
00388 };
00389 x.m = a.dwmul(a.m,b.M);
00390 x.M = a.upmul(a.m,b.m);
00391 return;
00392 };
00393
00394 if ( b.m > 0 )
00395 {
00396 x.m = a.dwmul(a.m,b.M);
00397 x.M = a.upmul(a.M,b.M);
00398 return;
00399 }
00400 if ( b.M < 0 )
00401 {
00402 x.m = a.dwmul(a.M,b.m);
00403 x.M = a.upmul(a.m,b.m);
00404 return;
00405 };
00406
00407 C m0(a.dwmul(a.M,b.m));
00408 C m1(a.dwmul(a.m,b.M));
00409 if ( m0 > m1 ) m0 = m1;
00410
00411 C M0(a.upmul(a.M,b.M));
00412 C M1(a.upmul(a.m,b.m));
00413 if ( M0 < M1 ) M0 = M1;
00414
00415 x.m = m0;
00416 x.M = M0;
00417 };
00418
00419 template<class C, int r> inline void
00420 div( Interval<C,r>& a, const C& x ) {
00421 if ( x > 0 )
00422 {
00423 a.m = a.dwdiv(a.m,x);
00424 a.M = a.updiv(a.M,x);
00425 }
00426 else
00427 {
00428 C sv(a.m);
00429 a.m = a.dwdiv(a.M,x);
00430 a.M = a.updiv(sv,x);
00431 };
00432 };
00433
00434 template<class C, int r> inline void
00435 div( Interval<C,r>& a, const Interval<C,r>& b, const C& x ) {
00436 if ( &a == &b ) { div(a,x); return; };
00437 if ( x > 0 )
00438 {
00439 a.m = a.dwdiv(b.m,x);
00440 a.M = a.updiv(b.M,x);
00441 }
00442 else
00443 {
00444 a.m = a.dwdiv(b.M,x);
00445 a.M = a.updiv(b.m,x);
00446 };
00447 };
00448
00449 template<class C, int r> inline void
00450 div( Interval<C,r>& a, const C& x, const Interval<C,r>& b ) {
00451 if ( x > 0 )
00452 {
00453 a.m = a.dwdiv(x,b.M);
00454 a.M = a.updiv(x,b.m);
00455 }
00456 else
00457 {
00458 a.m = a.dwdiv(x,b.m);
00459 a.M = a.updiv(x,b.M);
00460 };
00461 };
00462
00463 template<class C, int r> inline void
00464 div( Interval<C,r>& a, const Interval<C,r>& b ) {
00465 if ( a.m > 0 )
00466 {
00467 if ( b.m > 0 )
00468 {
00469 a.m = a.dwdiv(a.m,b.M);
00470 a.M = a.updiv(a.M,b.m);
00471 return;
00472 };
00473 if ( b.M < 0 )
00474 {
00475 C sv(a.m);
00476 a.m = a.dwdiv(a.M,b.M);
00477 a.M = a.updiv(sv,b.m);
00478 return;
00479 };
00480 if ( r == 3 )
00481 {
00482 throw typename Interval<C,r>::extended(a.updiv(a.m,b.m),a.dwdiv(a.M,b.M));
00483 };
00484 };
00485
00486 if ( a.M < 0 )
00487 {
00488 if ( b.m > 0 )
00489 {
00490 a.m = a.dwdiv(a.m,b.m);
00491 a.M = a.updiv(a.M,b.M);
00492 return;
00493 };
00494
00495 if ( b.M < 0 )
00496 {
00497 C sv(a.m);
00498 a.m = a.dwdiv(a.M,b.m);
00499 a.M = a.updiv(sv,b.M);
00500 return;
00501 };
00502
00503 if ( r == 3 )
00504 {
00505 throw typename Interval<C,r>::extended(a.updiv(a.m,b.M),a.dwdiv(a.M,b.m));
00506 };
00507 }
00508
00509 if ( b.m > 0 )
00510 {
00511 a.m = a.dwdiv(a.m,b.m);
00512 a.M = a.updiv(a.M,b.m);
00513 return ;
00514 };
00515
00516 if ( b.M < 0 )
00517 {
00518 C sv(a.m);
00519 a.m = a.dwdiv(a.M,b.m);
00520 a.M = a.updiv(sv,b.m);
00521 return;
00522 };
00523 if ( r == 3 ) throw typename Interval<C,r>::extended(0,0);
00524 };
00525
00526 template<class C, int r> inline void
00527 div( Interval<C,r>& x, const Interval<C,r>& a, const Interval<C,r>& b ) {
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544 switch( sign(a.m) )
00545 {
00546 case 1:
00547 if ( b.m > 0 )
00548 {
00549 x.m = a.dwdiv(a.m,b.M);
00550 x.M = a.updiv(a.M,b.m);
00551 } else
00552 if ( b.M < 0 )
00553 {
00554 x.m = a.dwdiv(a.M,b.M);
00555 x.M = a.updiv(a.m,b.m);
00556 }
00557 else throw typename Interval<C,r>::extended(a.updiv(a.m,b.m),a.dwdiv(a.M,b.M));
00558 break;
00559 case -1:
00560 if ( b.m > 0 )
00561 {
00562 x.m = a.dwdiv(a.m,b.m);
00563 x.M = a.updiv(a.M,b.M);
00564 }else
00565 if ( b.M < 0 )
00566 {
00567
00568 x.m = a.dwdiv(a.M,b.m);
00569 x.M = a.updiv(a.m,b.M);
00570 }
00571 else throw typename Interval<C,r>::extended(a.updiv(a.m,b.M),a.dwdiv(a.M,b.m));
00572 break;
00573 case 0:
00574 if ( b.m > 0 )
00575 {
00576 x.m = 0;
00577 x.M = a.updiv(a.M,b.m);
00578 }
00579 else
00580 if ( b.M < 0 )
00581 {
00582 x.m = a.dwdiv(a.M,b.m);
00583 x.M = a.updiv(a.m,b.m);
00584 }
00585 else throw typename Interval<C,r>::extended(0,0);
00586 break;
00587 };
00588 };
00589
00590
00591
00592
00593 template<class C>
00594 struct Intervals
00595 {
00596 typedef Interval<C,0> simple_t;
00597 typedef Interval<C,1> rdw_t;
00598 typedef Interval<C,2> rup_t;
00599 typedef Interval<C,3> autoround_t;
00600 };
00601
00602 namespace let
00603 {
00604 template<class T, int r> void
00605 assign( Interval<T,r>& i, const char * s ) {
00606 int n = strlen(s)+1;
00607 if ( *s == '[' )
00608 {
00609 char _s[ n ];
00610 std::copy(s,s+n,_s);
00611 char * sm = _s+1;
00612 char * sM = _s+1;
00613 while ( *sM != ',' ) sM++;
00614 *sM = 0;
00615 sM++;
00616 char * e = sM;
00617 while ( *e && *e != ']' ) e++;
00618 *e = 0;
00619 let::assign(i.m,(char*)sm);
00620 let::assign(i.M,(char*)sM);
00621 }
00622 else
00623 {
00624 T tmp;
00625 let::assign(tmp,(char*)s);
00626 i.m = i.M = tmp;
00627 };
00628 };
00629 }
00630
00631 template<class C, int R> void
00632 split( Interval<C,R>& l, Interval<C,R>& r ) {
00633 r.M = l.M;
00634 r.m = (l.M+l.m)/C(2);
00635 l.M = r.m;
00636 };
00637
00638 template<class C, int R> Interval<C,R>
00639 operator-(const Interval<C,R>& I) {
00640 Interval<C,R> res; neg(res,I); return res;
00641 }
00642 #define TMPL template<class Ca, int Na, class Cb, int Nb>
00643 #define ARG0 Interval<Ca,Na>
00644 #define ARG1 Interval<Cb,Nb>
00645 TMPL typename texp::sup<ARG0,ARG1>::T operator+(const ARG0& Ia, const ARG1& Ib) {
00646 typename texp::sup<ARG0,ARG1>::T res; add(res,Ia,Ib); return res;
00647 }
00648 TMPL typename texp::sup<ARG0,ARG1>::T operator-(const ARG0& Ia, const ARG1& Ib) {
00649 typename texp::sup<ARG0,ARG1>::T res; sub(res,Ia,Ib); return res;
00650 }
00651 TMPL typename texp::sup<ARG0,ARG1>::T operator*(const ARG0& Ia, const ARG1& Ib) {
00652 typename texp::sup<ARG0,ARG1>::T res; mul(res,Ia,Ib); return res;
00653 }
00654 TMPL typename texp::sup<ARG0,ARG1>::T operator/(const ARG0& Ia, const ARG1& Ib) {
00655 typename texp::sup<ARG0,ARG1>::T res; div(res,Ia,Ib); return res;
00656 }
00657
00658 #undef ARG1
00659 #undef TMPL
00660 #define TMPL template<class Ca, int Na, class Cb>
00661 #define ARG1 Cb
00662
00663 TMPL typename texp::sup<ARG0,ARG1>::T operator+(const ARG0& Ia, const ARG1& Ib) {
00664 typename texp::sup<ARG0,ARG1>::T res; add(res,Ia,(typename texp::sup<Ca,Cb>::T)Ib); return res;
00665 }
00666 TMPL typename texp::sup<ARG0,ARG1>::T operator-(const ARG0& Ia, const ARG1& Ib) {
00667 typename texp::sup<ARG0,ARG1>::T res; sub(res,Ia,(typename texp::sup<Ca,Cb>::T)Ib); return res;
00668 }
00669 TMPL typename texp::sup<ARG0,ARG1>::T operator*(const ARG0& Ia, const ARG1& Ib) {
00670 typename texp::sup<ARG0,ARG1>::T res; mul(res,Ia,(typename texp::sup<Ca,Cb>::T)Ib); return res;
00671 }
00672 TMPL typename texp::sup<ARG0,ARG1>::T operator/(const ARG0& Ia, const ARG1& Ib) {
00673 typename texp::sup<ARG0,ARG1>::T res; div(res,Ia,(typename texp::sup<Ca,Cb>::T)Ib); return res;
00674 }
00675
00676 TMPL typename texp::sup<ARG0,ARG1>::T operator+(const ARG1& Ia, const ARG0& Ib) {
00677 typename texp::sup<ARG0,ARG1>::T res; add(res,Ib,(typename texp::sup<Ca,Cb>::T)Ia); return res;
00678 }
00679 TMPL typename texp::sup<ARG0,ARG1>::T operator-(const ARG1& Ia, const ARG0& Ib) {
00680 typename texp::sup<ARG0,ARG1>::T res; add(res,-Ib,(typename texp::sup<Ca,Cb>::T)Ia); return res;
00681 }
00682 TMPL typename texp::sup<ARG0,ARG1>::T operator*(const ARG1& Ia, const ARG0& Ib) {
00683 typename texp::sup<ARG0,ARG1>::T res; mul(res,Ib,(typename texp::sup<Ca,Cb>::T)Ia); return res;
00684 }
00685 TMPL typename texp::sup<ARG0,ARG1>::T operator/(const ARG1& Ia, const ARG0& Ib) {
00686 typename texp::sup<ARG0,ARG1>::T res; div(res,Ib,(typename texp::sup<Ca,Cb>::T)Ia); return res;
00687 }
00688
00689
00690
00691
00692
00693 #undef TMPL
00694 #undef ARG1
00695 #define TMPL template<class Ca, int Na, class K>
00696 #define ARG1 typename K::integer
00697 TMPL typename texp::sup<ARG0,ARG1>::T operator+(const ARG0& Ia, const ARG1& Ib) {
00698 typename texp::sup<ARG0,ARG1>::T res; add(res,Ia,(Ca)Ib); return res;
00699 }
00700 TMPL typename texp::sup<ARG0,ARG1>::T operator-(const ARG0& Ia, const ARG1& Ib) {
00701 typename texp::sup<ARG0,ARG1>::T res; sub(res,Ia,(Ca)Ib); return res;
00702 }
00703 TMPL typename texp::sup<ARG0,ARG1>::T operator*(const ARG0& Ia, const ARG1& Ib) {
00704 typename texp::sup<ARG0,ARG1>::T res; mul(res,Ia,Ib); return res;
00705 }
00706 TMPL typename texp::sup<ARG0,ARG1>::T operator/(const ARG0& Ia, const ARG1& Ib) {
00707 typename texp::sup<ARG0,ARG1>::T res; div(res,Ia,Ib); return res;
00708 }
00709
00710
00711
00712
00713
00714 declare_binary_operator(TMPL,ARG1,ARG0,_add_,operator+);
00715 declare_binary_operator(TMPL,ARG1,ARG0,_sub_,operator-);
00716 declare_binary_operator(TMPL,ARG1,ARG0,_mul_,operator*);
00717 declare_binary_operator(TMPL,ARG1,ARG0,_div_,operator/);
00718 #undef ARG1
00719 #undef TMPL
00720 #define TMPL template<class Ca, int Na, class K>
00721 #define ARG1 typename K::floating
00722 declare_binary_operator(TMPL,ARG0,ARG1,_add_,operator+);
00723 declare_binary_operator(TMPL,ARG0,ARG1,_sub_,operator-);
00724 declare_binary_operator(TMPL,ARG0,ARG1,_mul_,operator*);
00725 declare_binary_operator(TMPL,ARG0,ARG1,_div_,operator/);
00726 declare_binary_operator(TMPL,ARG1,ARG0,_add_,operator+);
00727 declare_binary_operator(TMPL,ARG1,ARG0,_sub_,operator-);
00728 declare_binary_operator(TMPL,ARG1,ARG0,_mul_,operator*);
00729 declare_binary_operator(TMPL,ARG1,ARG0,_div_,operator/);
00730 #undef ARG1
00731 #undef TMPL
00732 #define TMPL template<class Ca, int Na, class K>
00733 #define ARG1 typename K::rational
00734 declare_binary_operator(TMPL,ARG0,ARG1,_add_,operator+);
00735 declare_binary_operator(TMPL,ARG0,ARG1,_sub_,operator-);
00736 declare_binary_operator(TMPL,ARG0,ARG1,_mul_,operator*);
00737 declare_binary_operator(TMPL,ARG0,ARG1,_div_,operator/);
00738 declare_binary_operator(TMPL,ARG1,ARG0,_add_,operator+);
00739 declare_binary_operator(TMPL,ARG1,ARG0,_sub_,operator-);
00740 declare_binary_operator(TMPL,ARG1,ARG0,_mul_,operator*);
00741 declare_binary_operator(TMPL,ARG1,ARG0,_div_,operator/);
00742 #undef ARG1
00743 #undef ARG0
00744 #undef TMPL
00745
00746
00747 }
00748 #endif