realroot_doc 0.1.1
|
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 template<typename T,class X> inline 00152 void distance( T& dmin, T& dmax, const X& x, const Interval<T,r>& i ) 00153 { 00154 if ( x < i.min() ) { dmin = i.min()-x; dmax = i.max()-x; return; }; 00155 if ( x > i.max() ) { dmin = x-i.max(); dmax = x-i.min(); return; }; 00156 dmin = x-i.min(); 00157 dmax = i.max()-x; 00158 if ( dmax < dmin ) dmax = dmin; 00159 dmin = 0; 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 // std::cout << "last case X\n"; 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 //std::cout << "popo\n"; 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 if ( b.m > 0 ) 00530 { 00531 if ( a.m > 0 ) { 00532 x.m = a.dwdiv(a.m,b.M); 00533 x.M = a.updiv(a.M,b.m); 00534 } 00535 else x.m = a.dwdiv(a.m,b.m); 00536 return; 00537 } 00538 if ( b.M < 0 ) 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 // C sv(a.M); 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 // declare_binary_operator(TMPL,ARG1,ARG0,_add_,operator+); 00690 // declare_binary_operator(TMPL,ARG1,ARG0,_sub_,operator-); 00691 // declare_binary_operator(TMPL,ARG1,ARG0,_mul_,operator*); 00692 // declare_binary_operator(TMPL,ARG1,ARG0,_div_,operator/); 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 // declare_binary_operator(TMPL,ARG0,ARG1,_add_,operator+); 00710 // declare_binary_operator(TMPL,ARG0,ARG1,_sub_,operator-); 00711 // declare_binary_operator(TMPL,ARG0,ARG1,_mul_,operator*); 00712 // declare_binary_operator(TMPL,ARG0,ARG1,_div_,operator/); 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 } //end namespace mmx 00748 #endif