realroot_doc 0.1.1
|
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