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