Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_MATH_OPTIMIZATION_BOUNDS2CONSTRAINTS_H
00002 #define OPENTISSUE_CORE_MATH_OPTIMIZATION_BOUNDS2CONSTRAINTS_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/core/math/math_value_traits.h>
00013 #include <cassert>
00014
00015 namespace OpenTissue
00016 {
00017 namespace math
00018 {
00019 namespace optimization
00020 {
00021
00022 namespace detail
00023 {
00048 template <typename T, typename bound_functor>
00049 class Bound2ConstraintFunctor
00050 {
00051 protected:
00052
00053 typedef T value_type;
00054 typedef OpenTissue::math::ValueTraits<T> value_traits;
00055 typedef typename bound_functor::vector_iterator bound_iterator;
00056
00057 bound_functor const & m_bounds;
00058 bool m_is_lower;
00059
00060 public:
00061
00062 Bound2ConstraintFunctor(
00063 bound_functor const & bounds
00064 , bool const & is_lower
00065 )
00066 : m_bounds(bounds)
00067 , m_is_lower(is_lower)
00068 {}
00069
00070 template<typename vector_type>
00071 T operator()(vector_type const & x, size_t const & i) const
00072 {
00073 if (m_is_lower)
00074 return x(i) - m_bounds(x,i);
00075 return m_bounds(x,i) - x(i);
00076 }
00077
00078 size_t size() const { return m_bounds.size(); }
00079
00080 public:
00081
00082 class vector_iterator
00083 {
00084 protected:
00085
00086 size_t m_index;
00087 size_t m_end;
00088 bound_iterator m_pos;
00089 bool m_is_lower;
00090 size_t m_i;
00091
00092 public:
00093
00094 vector_iterator(
00095 size_t const & begin
00096 , size_t const & end
00097 , bound_iterator & pos
00098 , bool const & is_lower
00099 , size_t const & i
00100 )
00101 : m_index(begin)
00102 , m_end(end)
00103 , m_pos(pos)
00104 , m_is_lower(is_lower)
00105 , m_i(i)
00106 {
00107 assert(begin <= end || !"vector_iterator: begin must be before end iterator!");
00108 }
00109
00110 vector_iterator(vector_iterator const & i) { *this = i; }
00111
00112 bool const operator==(vector_iterator const & i) const
00113 {
00114 return this->m_index == i.m_index;
00115 }
00116
00117 bool const operator!=(vector_iterator const & i) const
00118 {
00119 return !( (*this) == i);
00120 }
00121
00122 size_t const index() const { return this->m_index; }
00123
00124 T operator*() const
00125 {
00126 assert(m_index < m_end || !"vector_iterator: can not iterate pass the end");
00127
00128 if (m_index == m_pos.index())
00129 {
00130 T const & bound = *(this->m_pos);
00131 if(m_index == m_i )
00132 return (m_is_lower) ? value_traits::one() - bound : bound - value_traits::one();
00133 else
00134 return (m_is_lower) ? - bound : bound;
00135 }
00136 if(m_index == m_i )
00137 return (m_is_lower) ? value_traits::one() : - value_traits::one();
00138
00139 return value_traits::zero() ;
00140 }
00141
00142 vector_iterator & operator=(vector_iterator const & i)
00143 {
00144 this->m_index = i.m_index;
00145 this->m_end = i.m_end;
00146 this->m_pos = i.m_pos;
00147 this->m_is_lower = i.m_is_lower;
00148 return *this;
00149 }
00150
00151 vector_iterator const & operator++()
00152 {
00153 assert(m_index < m_end || !"vector_iterator: cannot increment pass the end iterator");
00154 if(m_index==m_pos.index())
00155 ++m_pos;
00156 ++m_index;
00157 return *this;
00158 }
00159 };
00160
00161 vector_iterator partial_begin(size_t const & i) const
00162 {
00163 size_t const end = this->size();
00164 size_t const begin = 0u;
00165 size_t const cur = i;
00166 bound_iterator it = m_bounds.partial_begin(i);
00167 return vector_iterator(begin, end, it, m_is_lower, cur );
00168 }
00169
00170 vector_iterator partial_end(size_t const & i) const
00171 {
00172 size_t const end = this->size();
00173 size_t const cur = i;
00174 bound_iterator it = m_bounds.partial_end(i);
00175 return vector_iterator( end, end, it, m_is_lower, cur );
00176 }
00177
00178 };
00179
00180 }
00181
00182 template<typename bound_functor>
00183 inline detail::Bound2ConstraintFunctor<typename bound_functor::value_type,bound_functor>
00184 make_constraint_from_lower_bounds(bound_functor const & lower)
00185 {
00186 return detail::Bound2ConstraintFunctor<typename bound_functor::value_type,bound_functor>(lower,true);
00187 }
00188
00189 template<typename bound_functor>
00190 inline detail::Bound2ConstraintFunctor<typename bound_functor::value_type,bound_functor>
00191 make_constraint_from_upper_bounds(bound_functor const & upper)
00192 {
00193 return detail::Bound2ConstraintFunctor<typename bound_functor::value_type,bound_functor>(upper,false);
00194 }
00195
00196 }
00197 }
00198 }
00199
00200
00201 #endif