snark
interval.h
1 // This file is part of snark, a generic and flexible library
2 // for robotics research.
3 //
4 // Copyright (C) 2011 The University of Sydney
5 //
6 // snark is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 3 of the License, or (at your option) any later version.
10 //
11 // snark is distributed in the hope that it will be useful, but WITHOUT ANY
12 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
14 // for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with snark. If not, see <http://www.gnu.org/licenses/>.
18 
20 
21 #ifndef SNARK_MATH_INTERVAL_H_
22 #define SNARK_MATH_INTERVAL_H_
23 
24 #include <boost/optional.hpp>
25 #include <comma/base/exception.h>
26 #include <comma/math/compare.h>
27 #include <Eigen/Core>
28 
29 namespace snark { namespace math {
30 
32 template < typename T, int N >
34 {
35  public:
36  typedef Eigen::Matrix< T, N, 1 > vector_type;
37 
39  closed_interval( const vector_type& min, const vector_type& max ) : m_interval( std::make_pair( get_min( min, max ), get_max( min, max ) ) ) { if( !less_or_equal( min, max ) ) { COMMA_THROW( comma::exception, "invalid interval" ); } }
40 
42  closed_interval( const vector_type& rhs ) : m_interval( std::make_pair( rhs, rhs ) ) {}
43 
45  closed_interval() {} //interval(): m_interval( std::make_pair( vector_type::Zero(), vector_type::Zero() ) ) {}
46 
48  const std::pair< vector_type, vector_type >& operator()() const { assert( m_interval ); return m_interval; }
49 
51  const vector_type& min() const { assert( m_interval ); return m_interval->first; }
52 
54  const vector_type& max() const { assert( m_interval ); return m_interval->second; }
55 
57  bool contains( const vector_type& rhs ) const { assert( m_interval ); return less_or_equal( m_interval->first, rhs ) && less_or_equal( rhs, m_interval->second ); }
58 
60  bool contains( const closed_interval& rhs ) const { assert( m_interval && rhs ); return contains( rhs.min() ) && contains( rhs.max() ); }
61 
63  closed_interval< T, N > hull( const vector_type& rhs ) const { return closed_interval( get_min( m_interval->first, rhs ), get_max( m_interval->second, rhs ) ); }
64 
66  closed_interval< T, N > hull( const closed_interval& rhs ) const { return closed_interval( get_min( m_interval->first, rhs.min() ), get_max( m_interval->second, rhs.max() ) ); }
67 
69  const closed_interval< T, N >& set_hull( const vector_type& rhs ) { *this = m_interval ? hull( rhs ) : closed_interval( rhs ); return *this; }
70 
72  const closed_interval< T, N >& set_hull( const closed_interval& rhs ) { *this = m_interval ? hull( rhs ) : closed_interval( rhs ); return *this; }
73 
75  bool operator==( const closed_interval& rhs ) const { assert( m_interval && rhs ); return m_interval->first.isApprox( rhs().first ) && m_interval->second.isApprox( rhs().second ); }
76 
78  bool operator!=( const closed_interval& rhs ) const { assert( m_interval && rhs ); return !operator==( rhs ); }
79 
80  private:
81  // todo: use epsilon from <limits> for comparison
82  static bool less_or_equal( const vector_type& lhs, const vector_type& rhs ) { return ( ( lhs.array() <= rhs.array() ).all() ); }
83  static vector_type get_min( const vector_type& lhs, const vector_type& rhs ) { return rhs.array().min( lhs.array() ); }
84  static vector_type get_max( const vector_type& lhs, const vector_type& rhs ) { return rhs.array().max( lhs.array() ); }
85 
86  boost::optional< std::pair< vector_type, vector_type > > m_interval;
87 };
88 
89 } } // namespace snark { namespace math {
90 
91 #endif // SNARK_MATH_INTERVAL_H_