• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • Examples
  • File List
  • File Members

/home/hauberg/Dokumenter/Capture/humim-tracker-0.1/src/OpenTissue/OpenTissue/core/math/interval/interval.h

Go to the documentation of this file.
00001 #ifndef OPENTISSUE_CORE_MATH_INTERVAL_H
00002 #define OPENTISSUE_CORE_MATH_INTERVAL_H
00003 //
00004 // OpenTissue Template Library
00005 // - A generic toolbox for physics-based modeling and simulation.
00006 // Copyright (C) 2008 Department of Computer Science, University of Copenhagen.
00007 //
00008 // OTTL is licensed under zlib: http://opensource.org/licenses/zlib-license.php
00009 //
00010 #include <OpenTissue/configuration.h>
00011 
00012 #include <OpenTissue/core/math/interval/io/interval_io.h>
00013 #include <OpenTissue/core/math/interval/interval_vector.h>
00014 #include <OpenTissue/core/math/interval/interval_matrix.h>
00015 #include <OpenTissue/core/math/interval/interval_intersect.h>
00016 #include <OpenTissue/core/math/interval/interval_empty.h>
00017 
00018 #include <OpenTissue/core/math/math_value_traits.h>
00019 
00020 
00021 #include <cassert>
00022 
00023 namespace OpenTissue
00024 {
00025   namespace math
00026   {
00027     namespace interval
00028     {
00029 
00057       template <typename value_type_>
00058       class Interval
00059       {
00060       public:
00061 
00062         typedef value_type_                    T;
00063         typedef typename math::ValueTraits<T>  value_traits;
00064         typedef T                              value_type;
00065         typedef T                              base_type;   //--- boost::interval interface compatibility
00066         typedef size_t                         index_type;
00067 
00068       protected:
00069 
00070         T m_lower;  
00071         T m_upper;  
00072 
00073       public:
00074 
00075         T       & lower()       { return m_lower; }
00076         T const & lower() const { return m_lower; }
00077         T       & upper()       { return m_upper; }
00078         T const & upper() const { return m_upper; }
00079 
00088         T & operator() (index_type index) 
00089         {
00090           assert(index==0u || index==1u || !"interval::operator(): index must be zero or one");
00091           return (!index) ? m_lower : m_upper;
00092         }
00093 
00102         T const & operator() (index_type index) const
00103         {
00104           assert(index==0u || index==1u || !"interval::operator() const : index must be zero or one");
00105           return (!index) ? m_lower : m_upper;
00106         }
00107 
00116         T & operator[] (index_type index)
00117         {
00118           assert(index==0u || index==1u || !"interval::operator[]: index must be zero or one");
00119           return (!index) ? m_lower : m_upper;
00120         }
00121 
00130         T const & operator[] (index_type index) const
00131         {
00132           assert(index==0u || index==1u || !"interval::operator[] const : index must be zero or one");
00133           return (!index) ? m_lower : m_upper;
00134         }
00135 
00136       public:
00137 
00138         Interval()
00139           : m_lower()
00140           , m_upper()
00141         {}
00142 
00143         Interval(Interval const &i)
00144           : m_lower( i.m_lower )
00145           , m_upper( i.m_upper )
00146         {}
00147 
00148         explicit Interval(T const & value)
00149           : m_lower( value )
00150           , m_upper( value ) 
00151         {}
00152 
00153         explicit Interval(T const & l, T const & u)
00154           : m_lower( l )
00155           , m_upper( u ) 
00156         {
00157           //assert(lower_val <= upper_val || !"interval(lower_val,upper_val): lower bound must be less than or equal to upper bound");
00158         }
00159 
00160         ~Interval() {}
00161 
00162       public:
00163 
00174         Interval & operator=(Interval const &rhs) 
00175         {
00176           m_lower =  rhs.m_lower;
00177           m_upper =  rhs.m_upper;
00178           return (*this);
00179         }
00180 
00181         //--- boost::interval interface compatibility
00182         void assign(T const &l, T const &u)
00183         {
00184           m_lower = l;
00185           m_upper = u;
00186         }
00187 
00193         void clear()
00194         {
00195           m_lower = m_upper = value_traits::zero();
00196         }
00197 
00203         bool is_valid() const     {      return !is_empty();    }
00204 
00211         bool is_empty() const     {      return m_lower > m_upper;    }
00212 
00213         //--- boost::interval interface compatibility
00214         static Interval const & empty() 
00215         { 
00216           static Interval const empty_value(value_traits::one(),-value_traits::one()); 
00217           return empty_value;
00218         };
00219 
00220       public:
00221 
00239         bool operator< (Interval const & i) const { return m_upper < i.m_lower;                  }
00240         bool operator> (Interval const & i) const { return m_lower > i.m_upper;                  }
00241         bool operator<=(Interval const & i) const { return m_upper <= i.m_lower;                 }
00242         bool operator>=(Interval const & i) const { return m_lower >= i.m_upper;                 }
00243         bool operator==(Interval const & i) const { return m_lower == i.m_lower && m_upper == i.m_upper; }
00244         bool operator!=(Interval const & i) const { return m_lower != i.m_lower || m_upper != i.m_upper; }
00245 
00246       public:
00247 
00255         Interval & operator+=(Interval const & i)
00256         {
00257           m_lower += i.m_lower;
00258           m_upper += i.m_upper;
00259           return (*this);
00260         }
00261 
00270         Interval operator+(Interval const &i ) const { return Interval(m_lower+i.m_lower, m_upper+i.m_upper); }
00271 
00279         Interval & operator-=(Interval const & i)
00280         {
00281           m_lower -= i.m_upper;
00282           m_upper -= i.m_lower;
00283           return (*this);
00284         }
00285 
00294         Interval operator-(Interval const & i) const { return Interval(m_lower-i.m_upper, m_upper-i.m_lower); }
00295 
00302         Interval operator-() const {  return Interval(-m_upper, -m_lower); }
00303 
00311         Interval & operator*=(T const & val)
00312         {
00313           if (val < value_traits::zero() ) 
00314           {
00315             T x = m_lower;
00316             m_lower = m_upper * val;
00317             m_upper = x * val;
00318           }
00319           else 
00320           {
00321             m_upper *= val;
00322             m_lower *= val;
00323           }
00324           return (*this);
00325         }
00326 
00335         Interval operator*(T const & val) const
00336         {
00337           return (val < value_traits::zero()) ? Interval(m_upper*val, m_lower*val) : Interval(m_lower*val, m_upper*val);
00338         }
00339 
00347         Interval & operator*=(Interval const & i)
00348         {
00349           T tmp_lower;
00350           T tmp_upper;
00351 
00352           if (m_lower <= value_traits::zero() && i.m_upper >= value_traits::zero()) 
00353           {
00354             tmp_lower = m_lower * i.m_upper;
00355           }
00356           else if (m_upper >= value_traits::zero()) 
00357           {
00358             tmp_lower = (i.m_lower <= value_traits::zero()) ? m_upper*i.m_lower : m_lower*i.m_lower;
00359           }
00360           else 
00361           {
00362             tmp_lower = m_upper*i.m_upper;
00363           }
00364 
00365           if (m_lower <= value_traits::zero() && i.m_lower <= value_traits::zero()) 
00366           {
00367             tmp_upper = m_lower * i.m_lower;
00368           }
00369           else if (m_upper >= value_traits::zero()) 
00370           {
00371             tmp_upper = (i.m_upper >= value_traits::zero())  ? m_upper * i.m_upper : m_lower * i.m_upper;
00372           }
00373           else 
00374           {
00375             tmp_upper = m_upper * i.m_lower;
00376           }
00377 
00378           m_upper = tmp_upper;
00379           m_lower = tmp_lower;
00380 
00381           return *this;
00382         }
00383 
00384         /*
00385         * Interval Multiplication.
00386         * Performance Warning: Copy Constructor is invoked to create return value.
00387         *
00388         * Optimized version, more IFs, two less mul
00389         *
00390         * @param i  The interval to multiply with.
00391         *
00392         * @return   A new interval instance holding the result of the multiplication.
00393         */
00394         Interval operator*(Interval const & i) const   
00395         {    
00396           Interval tmp(i);
00397           tmp *= (*this);
00398           return tmp;
00399         }
00400 
00408         Interval & operator/=(Interval const & i)
00409         {
00410           assert(i.m_lower > value_traits::zero() || i.m_upper < value_traits::zero() || !"interval::operator/=(): lower must be positive or upper negative!");
00411           (*this) *= Interval(value_traits::one() / i.m_upper, value_traits::one() / i.m_lower);
00412           return (*this);
00413         }
00414 
00423         Interval operator/(Interval const & i) const
00424         {
00425           assert(i.m_lower > value_traits::zero() || i.m_upper < value_traits::zero() || !"interval::operator/=(): lower must be positive or upper negative!");
00426           return (*this) * Interval(value_traits::one() / i.m_upper, value_traits::one() / i.m_lower);
00427         }
00428 
00434         T get_abs_lower() const
00435         {
00436           // -------0-[   ]- <-R
00437           // -----[ 0 ]----- <-R
00438           // -[   ]-0------- <-R
00439           return (m_lower >= value_traits::zero()) ? m_lower  :  ( m_upper >= value_traits::zero() ? value_traits::zero() : -m_upper  );
00440         }
00441 
00447         T get_abs_upper() const
00448         {
00449           // -------0-[   ]- <-R
00450           // -----[ 0 ]----- <-R
00451           // -[   ]-0------- <-R
00452           return (m_lower+m_upper >= value_traits::zero()) ? m_upper : -m_lower;
00453         }
00454 
00455       };
00456 
00457     } // namespace interval
00458   } // namespace math
00459 } // namespace OpenTissue
00460 
00461 // OPENTISSUE_CORE_MATH_INTERVAL_H
00462 #endif 

Generated on Thu Dec 1 2011 12:52:05 for HUMIM Tracker by  doxygen 1.7.1