Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_MATH_OPTIMIZATION_PROJECT_H
00002 #define OPENTISSUE_CORE_MATH_OPTIMIZATION_PROJECT_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 <OpenTissue/core/math/math_is_number.h>
00014 #include <stdexcept>
00015 #include <cassert>
00016
00017 namespace OpenTissue
00018 {
00019 namespace math
00020 {
00021 namespace optimization
00022 {
00023
00024
00042 template < typename T >
00043 inline bool project(
00044 boost::numeric::ublas::vector<T> const & x
00045 , boost::numeric::ublas::vector<T> const & l
00046 , boost::numeric::ublas::vector<T> const & u
00047 , boost::numeric::ublas::vector<T> & new_x
00048 )
00049 {
00050 size_t const m = x.size();
00051
00052 if(x.size()<=0)
00053 throw std::invalid_argument("size of x-vector were zero");
00054
00055 if(new_x.size()!=m)
00056 throw std::invalid_argument("size of new_x-vector were incompatible");
00057
00058 if(l.size()!=m)
00059 throw std::invalid_argument("size of the x-vectors and lower bound were incompatible");
00060
00061 if(u.size()!=m)
00062 throw std::invalid_argument("size of the x-vectors and upper bound were incompatible");
00063
00064 bool changed = false;
00065
00066
00067 for (size_t i = 0; i < m; ++ i)
00068 {
00069 T const l_i = l(i);
00070 T const u_i = u(i);
00071
00072 assert( is_number( l_i ) || !"project: l_i was not a number");
00073 assert( is_number( u_i ) || !"project: u_i was not a number");
00074 assert( l_i <= u_i || !"project(): inconsistent l and u values");
00075 T const x_i = x(i);
00076 assert( is_number( x_i ) || !"project: x_i was not a number");
00077 T const new_x_i = (x_i < l_i) ? l_i : ( ( x_i > u_i) ? u_i : x_i );
00078 assert( is_number( new_x_i ) || !"project: new_x_i was not a number");
00079 changed = changed || new_x_i > x_i || new_x_i < x_i;
00080 new_x(i) = new_x_i;
00081 }
00082 return changed;
00083 }
00084
00089 template < typename T >
00090 inline bool project(
00091 boost::numeric::ublas::vector<T> & x
00092 , boost::numeric::ublas::vector<T> const & l
00093 , boost::numeric::ublas::vector<T> const & u
00094 )
00095 {
00096 return OpenTissue::math::optimization::project(x,l,u,x);
00097 }
00098
00144 template < typename T, typename bound_function_type>
00145 inline bool project(
00146 boost::numeric::ublas::vector<T> const & x
00147 , bound_function_type const & l
00148 , bound_function_type const & u
00149 , boost::numeric::ublas::vector<T> & new_x
00150 )
00151 {
00152 size_t const m = x.size();
00153
00154 if(x.size()<=0)
00155 throw std::invalid_argument("size of x-vector were zero");
00156
00157 if(new_x.size()!=m)
00158 throw std::invalid_argument("size of new_x-vector were incompatible");
00159
00160 bool changed = false;
00161
00162
00163 for (size_t i = 0; i < m; ++ i)
00164 {
00165 T const l_i = l(x,i);
00166 T const u_i = u(x,i);
00167
00168 assert( is_number( l_i ) || !"project: l_i was not a number");
00169 assert( is_number( u_i ) || !"project: u_i was not a number");
00170 assert( l_i <= u_i || !"project(): inconsistent l and u values");
00171 T const x_i = x(i);
00172 assert( is_number( x_i ) || !"project: x_i was not a number");
00173 T const new_x_i = (x_i < l_i) ? l_i : ( ( x_i > u_i) ? u_i : x_i );
00174 assert( is_number( new_x_i ) || !"project: new_x_i was not a number");
00175 changed = changed || new_x_i > x_i || new_x_i < x_i;
00176 new_x(i) = new_x_i;
00177 }
00178 return changed;
00179 }
00180
00185 template < typename T, typename bound_function_type>
00186 inline bool project(
00187 boost::numeric::ublas::vector<T> & x
00188 , bound_function_type const & l
00189 , bound_function_type const & u
00190 )
00191 {
00192
00193
00194
00195
00196
00197 return OpenTissue::math::optimization::project(x,l,u,x);
00198 }
00199
00216 template < typename T, typename bound_function_type>
00217 class Projection
00218 {
00219 public:
00220
00221 bound_function_type const & m_l;
00222 bound_function_type const & m_u;
00223
00224 Projection(
00225 bound_function_type const & l
00226 , bound_function_type const & u
00227 )
00228 : m_l(l)
00229 , m_u(u)
00230 {}
00231
00232 bool operator()(boost::numeric::ublas::vector<T> & x) const
00233 {
00234 return OpenTissue::math::optimization::project(x,m_l,m_u);
00235 }
00236
00237 bool operator()(boost::numeric::ublas::vector<T> const & x, boost::numeric::ublas::vector<T> & x_new) const
00238 {
00239 return OpenTissue::math::optimization::project(x,m_l,m_u,x_new);
00240 }
00241
00242 };
00243
00250 template < typename T >
00251 class NoProjection
00252 {
00253 public:
00254 bool operator()(boost::numeric::ublas::vector<T> &) const {return false;}
00255 bool operator()(boost::numeric::ublas::vector<T> const &,boost::numeric::ublas::vector<T> &) const { return false;}
00256 };
00257
00258
00259 }
00260 }
00261 }
00262
00263
00264 #endif