00001 #ifndef SYNAPS_ARITHM_INTERVAL_H
00002 #define SYNAPS_ARITHM_INTERVAL_H
00003
00004 #include <cassert>
00005 #include <synaps/init.h>
00006 #include <synaps/base/type.h>
00007 #include <synaps/arithm/traits.h>
00008 #include <synaps/arithm/texp.h>
00009 #include <synaps/arithm/let.h>
00010 #include <synaps/arithm/rounding.h>
00011 #include <synaps/arithm/rdw.h>
00012
00013 __BEGIN_NAMESPACE_SYNAPS
00014
00030 namespace numerics { template<class T, int r> struct interval_base; }
00031 template<class T, int r = 3 >
00032 struct Interval : numerics::interval_base<T,((unsigned)r)%4>
00033 {
00034 typedef T value_type;
00035 typedef T coeff_t;
00036 typedef numerics::interval_base<T,((unsigned)r)%4> base_t;
00037 typedef typename base_t::rnd rnd_t;
00038 typedef Interval<T,r> self_t;
00039 struct extended { T a,b; extended( const T& c, const T& d ) { a = c; b = d; }; };
00040 T m, M;
00041 template<class S> Interval( const arithm::template_expression<S>& e );
00043 Interval();
00045 Interval( int n );
00047 Interval( const T& x );
00049 Interval( const T& a, const T& b );
00051 Interval( const char * s );
00052 Interval& operator=( const char * s ){ let::assign(*this,s); return *this; }
00053 Interval & operator=( const Interval & i )
00054 {
00055 m = i.m;
00056 M = i.M;
00057 };
00058
00059 template<class X>
00060 Interval & operator=( const arithm::template_expression<X> & x ) ;
00061
00062 void define( const T& m, const T& M ) { this->m = m; this->M = M; };
00063 void assign( const T& m, const T& M ) { define(m,M); };
00064 void assign( const Interval& b ) { *this = b; };
00066
00067 template<class X> bool operator==( const X& k) const { return m == M && M == k ; };
00068 template<class X, int r_> bool operator==( const Interval<X,r_> & b ) const
00069 { return b.m == m && b.M == M ; };
00071 template<class X> inline bool operator>( const X& x ) const { return m > x; };
00073 template<class X> inline bool operator>=( const X& x ) const { return m >= x; };
00075 template<class X> inline bool operator<( const X& x ) const { return M < x; };
00077 template<class X> inline bool operator<=( const X& x ) const { return M <= x; };
00079 template<class X> inline bool operator!=(const X& x ) const { return !(*this == x); };
00080 template<class X, int _r> bool operator<( const Interval<X,_r>& i ) const { return M < i.m; };
00081 template<class X, int _r> bool operator>( const Interval<X,_r>& i ) const { return m > i.M; };
00082
00083 const T& lower() const { return m; };
00084 const T& upper() const { return M; };
00085 T& lower() { return m; };
00086 T& upper() { return M; };
00087 const T& inf() const { return lower(); };
00088 const T& sup() const { return upper(); };
00089 T& inf() { return m; };
00090 T& sup() { return M; };
00091
00092 Interval& operator=( const T& x ) { m = M = x; return *this; };
00093 template<class X, int R>
00094 Interval& operator=( const Interval<X,R> & x );
00095 template<class X>
00096 Interval& operator+=( const X & x ) { *this = *this + x; return *this; };
00097 template<class X>
00098 Interval& operator-=( const X & x ) { *this = *this - x; return *this; };
00099 template<class X>
00100 Interval& operator*=( const X & x ) { *this = *this * x; return *this; };
00101 template<class X>
00102 Interval& operator/=( const X & x ) { *this = *this / x; return *this; };
00103
00105 T width() const { return M-m; };
00107 T size() const { return width(); };
00108 operator T()const { return (lower()+upper())/2.0; };
00109 };
00110
00111
00112
00113
00114 template<class T, int r>
00115 void hull( Interval<T,r>& v, const Interval<T,r>& a, const Interval<T,r>& b );
00116 template<class T, int r> inline
00117 bool intersect( Interval<T,r>& result,
00118 const Interval<T,r>& a, const Interval<T,r>& b );
00119
00120 __END_NAMESPACE_SYNAPS
00121
00122 #include "Interval.C"
00123
00124 __BEGIN_NAMESPACE_SYNAPS
00125
00126 namespace let {
00127 template<class X, class Y, int r0, int r1> inline void
00128 assign( Interval<X,r0>& a, const Interval<Y,r1> & b )
00129 {
00130 assign(a.m,b.m);
00131 assign(a.M,b.M);
00132 };
00133 };
00134
00135 template<class C,int R>
00136 template<class X> inline
00137 Interval<C,R> & Interval<C,R>::operator=( const arithm::template_expression<X> & x )
00138 {
00139 rnd_t rnd;
00140 let::assign(*this,x);
00141 return *this;
00142 };
00143
00144 template<class C,int R>
00145 template<class X> inline
00146 Interval<C,R>::Interval( const arithm::template_expression<X> & x )
00147 {
00148 rnd_t rnd;
00149 let::assign(*this,x);
00150 };
00151
00152 template<class C, int mode>
00153 template<class X, int R>
00154 Interval<C,mode>& Interval<C,mode>::operator=( const Interval<X,R> & x )
00155 {
00156 let::assign(*this,x);
00157 return *this;
00158 };
00159
00160
00161
00162 __END_NAMESPACE_SYNAPS
00163
00164 #endif