realroot_doc 0.1.1
/Users/mourrain/Devel/mmx/realroot/include/realroot/Interval_fcts.hpp
Go to the documentation of this file.
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