realroot_doc 0.1.1
/Users/mourrain/Devel/mmx/realroot/include/realroot/Interval.hpp
Go to the documentation of this file.
00001 #ifndef mmx_interval_hpp
00002 #define mmx_interval_hpp
00003 
00004 #include <cassert>
00005 #include <realroot/texp.hpp>
00006 #include <realroot/texp_expression.hpp>
00007 #include <realroot/rounding_mode.hpp>
00008 
00009 namespace mmx {
00010 
00011   using namespace texp;
00012 
00039 namespace  numerics { template<class T, int r> struct interval_base; }
00040 
00042 template<class T, int r = 3 >
00043 struct Interval : numerics::interval_base<T,((unsigned)r)%4> {
00044     typedef T value_type;
00045     typedef T coeff_t;
00046     typedef T boundary_type;
00047     typedef numerics::interval_base<T,((unsigned)r)%4> base_t;
00048     typedef typename base_t::rnd rnd_t;
00049     typedef Interval<T,r> self_t;
00050     struct extended { T a,b; extended( const T& c, const T& d ) { a = c; b = d; }; };
00051     T m, M;
00052     template<class S> Interval( const texp::template_expression<S>& e );
00054     Interval();    
00056     Interval( int n );
00058     Interval( unsigned n );
00060     Interval( const T& x );
00062     Interval( const T& a, const T& b );
00064     Interval( const char * s );
00065     //Interval& operator=( const char * s ){ let::assign(*this,s); return *this; }
00066     Interval& operator=( const Interval & i )
00067     {
00068       m = i.m;
00069       M = i.M;
00070       return *this;
00071     };
00072     
00073     template<class X>
00074     Interval & operator=( const texp::template_expression<X> & x ) ;
00075     
00076     void define( const T& m, const T& M ) { this->m = m; this->M = M; };
00077     void assign( const T& m, const T& M ) { define(m,M); };
00078     void assign( const Interval& b ) { *this = b; };
00079 
00081     template<class X> bool operator==( const X& k) const { return m == M && M == k ; };
00082     template<class X, int r_> bool operator==( const Interval<X,r_> & b ) const 
00083     { return b.m == m && b.M == M ; };
00085     template<class X> inline bool operator>( const X& x ) const { return m > x; };
00087     template<class X> inline bool operator>=( const X& x ) const { return  m >= x; };
00089     template<class X> inline bool operator<( const X& x ) const { return M < x; };
00091     template<class X> inline bool operator<=( const X& x ) const { return M <= x; };
00093     template<class X> inline bool operator!=(const X& x ) const { return !(*this == x); };
00094     template<class X, int _r> bool operator<( const Interval<X,_r>& i ) const { return M < i.m; };
00095     template<class X, int _r> bool operator>( const Interval<X,_r>& i ) const { return m > i.M; };
00096     
00097     const T& lower() const { return m; };
00098     const T& upper() const { return M; };
00099     T& lower() { return m; };
00100     T& upper() { return M; };
00101     const T& inf() const { return lower(); };
00102     const T& sup() const { return upper(); };
00103     T& inf() { return m; };
00104     T& sup() { return M; };
00105     
00106     Interval& operator=( const T& x ) { m = M = x; return *this; };
00107     template<class X, int R>
00108     Interval& operator=( const Interval<X,R> & x );
00109     //    template<class X>
00110     //    Interval& operator+=( const X & x ) { *this = *this + x; return *this; };
00111     //    template<class X>
00112     //    Interval& operator-=( const X & x ) { *this = *this - x; return *this; };
00113     //    template<class X>
00114     //    Interval& operator*=( const X & x ) { *this = *this * x; return *this; };
00115     //    template<class X>
00116     //    Interval& operator/=( const X & x ) { *this = *this / x; return *this; };
00117 
00118     Interval& operator+=( const Interval & x ) { add(*this,x); return *this; };
00119     Interval& operator-=( const Interval & x ) { sub(*this,x); return *this; };
00120     Interval& operator*=( const Interval & x ) { mul(*this,x); return *this; };
00121     Interval& operator/=( const Interval & x ) { div(*this,x); return *this; };
00122 
00124   T width() const { return M-m; };
00126   T size() const { return width(); };
00127   operator T() const  {return (lower()+upper())/2; };
00129   T center() const { return (M+m)/T(2); };
00130   };
00131 
00132 
00133 template<class OSTREAM, class T, int r> inline void
00134 print(OSTREAM& os, const Interval<T,r>& a) {
00135   os<<"[";print(os,a.lower());os<<",";print(os,a.upper());os<<"]";
00136 }
00137 
00138 template<class T, int r>
00139 void hull( Interval<T,r>& v, const Interval<T,r>& a, const Interval<T,r>& b );
00140 template<class T,  int r> inline
00141 bool intersect( Interval<T,r>& result, 
00142                 const Interval<T,r>& a, const Interval<T,r>& b );
00143 
00144 } //end namespace mmx
00145 
00146 #include <realroot/Interval_fcts.hpp>
00147 
00148 namespace mmx {
00149 
00150 namespace texp {
00151 
00152   template<class X, int r>  struct kernelof_< Interval<X,r> >  {
00153     typedef typename kernelof<X>::T T; };
00154 }
00155 
00156 namespace let {
00157 
00158   template<class X, class Y, int r0, int r1> inline void 
00159   assign( Interval<X,r0>& a, const Interval<Y,r1> & b )
00160   {
00161     assign(a.m,b.m);
00162     assign(a.M,b.M);
00163   };
00164 };
00165 
00166 template<class C,int R>
00167 template<class X> inline
00168 Interval<C,R> & Interval<C,R>::operator=( const texp::template_expression<X> & x ) {
00169   rnd_t rnd;        // rounding mode verification
00170   let::assign(*this,x);  // evaluation of template expression
00171   return *this;
00172 }
00173 
00174 template<class C,int R>
00175 template<class X> inline
00176 Interval<C,R>::Interval( const texp::template_expression<X> & x ) {
00177   rnd_t rnd;        // rounding mode verification
00178   std::cout<<"assign "<<x<<std::endl;
00179   let::assign(*this,x);  // evaluation of template expression
00180 }
00181 
00182 template<class C, int mode>
00183 template<class X, int R>
00184 Interval<C,mode>& Interval<C,mode>::operator=( const Interval<X,R> & x )
00185 {
00186   let::assign(*this,x);
00187   return *this;
00188 };
00189 
00190   namespace let {
00191     template<class A,class B> void assign(A& a, const B&b);
00192     
00193     template<class C, class T> inline void 
00194     assign( Interval<C>& a, const T & b ) {
00195       C mn,mx;
00196       {
00197         numerics::rounding<C> rnd( numerics::rounding<C>::rnd_up() );
00198          assign(mx,b);
00199       }
00200       
00201       {
00202         numerics::rounding<C> rhd( numerics::rounding<C>::rnd_dw() );
00203         assign(mn,b);
00204       }
00205       if( mx < mn ) std::swap(mn,mx);
00206       new (&a) Interval<C>(mn,mx);
00207     };
00208   }
00209 
00210 
00211 
00212 
00213 
00214 } //end namespace mmx
00215     
00216 #endif