Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_MATH_OPTIMIZATION_MAKE_MBD_BOUNDS_H
00002 #define OPENTISSUE_CORE_MATH_OPTIMIZATION_MAKE_MBD_BOUNDS_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/core/math/big/big_types.h>
00013 #include <OpenTissue/core/math/math_value_traits.h>
00014 #include <cmath>
00015
00016 namespace OpenTissue
00017 {
00018 namespace math
00019 {
00020 namespace optimization
00021 {
00022
00023 namespace detail
00024 {
00025
00026
00055 template <typename T>
00056 class MultibodyDynamicsBoundFunctor
00057 {
00058 public:
00059
00060 typedef T value_type;
00061 typedef OpenTissue::math::ValueTraits<T> value_traits;
00062
00063 protected:
00064
00065 bool m_is_lower;
00066 ublas::vector<size_t> const & m_pi;
00067 ublas::vector<T> const & m_mu;
00068 ublas::vector<T> const & m_val;
00069 size_t m_n;
00070
00071 public:
00072
00076 class vector_iterator
00077 {
00078 protected:
00079
00080 bool m_end;
00081 size_t m_idx;
00082 T m_mu;
00083
00084 public:
00085
00086 vector_iterator()
00087 : m_end(true)
00088 , m_idx(0)
00089 , m_mu(value_traits::zero())
00090 {}
00091
00092 vector_iterator(vector_iterator const & i) { *this = i; }
00093
00094 vector_iterator(size_t const & idx, T const & mu)
00095 : m_end(false)
00096 , m_idx(idx)
00097 , m_mu(mu)
00098 {}
00099
00100 bool const operator==(vector_iterator const & i) const { return this->m_end == i.m_end; }
00101 bool const operator!=(vector_iterator const & i) const { return !( (*this) == i); }
00102
00103 size_t const index() const { return m_idx; }
00104
00105 T operator*() const { return m_mu; }
00106
00107 vector_iterator & operator=(vector_iterator const & i)
00108 {
00109 this->m_end = i.m_end;
00110 this->m_idx = i.m_idx;
00111 this->m_mu = i.m_mu;
00112 return *this;
00113 }
00114
00115 vector_iterator const & operator++()
00116 {
00117 m_end = true;
00118 return *this;
00119 }
00120 };
00121
00122 public:
00123
00124 MultibodyDynamicsBoundFunctor(
00125 bool const & is_lower
00126 , ublas::vector<size_t> const & pi
00127 , ublas::vector<T> const & mu
00128 , ublas::vector<T> const & val
00129 )
00130 : m_is_lower(is_lower)
00131 , m_pi(pi)
00132 , m_mu(mu)
00133 , m_val(val)
00134 , m_n( pi.size() )
00135 {}
00136
00137 template<typename vector_type>
00138 T operator()(vector_type const & x, size_t const & i) const
00139 {
00140 size_t const j = m_pi(i);
00141
00142 if(j<m_n)
00143 {
00144 T const mu_i = m_mu(i);
00145 return m_is_lower ? -mu_i*x(j) : mu_i*x(j);
00146 }
00147
00148 return m_val(i);
00149 }
00150
00151 vector_iterator partial_begin(size_t const & i) const
00152 {
00153 size_t const j = m_pi(i);
00154 if(j<m_n)
00155 {
00156 T const mu_i = m_mu(i);
00157 return m_is_lower ? vector_iterator(j,-mu_i) : vector_iterator(j, mu_i);
00158 }
00159 return vector_iterator();
00160 }
00161
00162 vector_iterator partial_end(size_t const & i) const { return vector_iterator(); }
00163
00164 size_t size() const { return m_n; }
00165
00166 };
00167
00168 }
00169
00197 template<typename T>
00198 inline detail::MultibodyDynamicsBoundFunctor<T> make_lower_mbd_bounds(
00199 ublas::vector<size_t> const & pi
00200 , ublas::vector<T> const & mu
00201 , ublas::vector<T> const & val
00202 )
00203 {
00204 return detail::MultibodyDynamicsBoundFunctor<T>(true, pi, mu, val );
00205 }
00206
00233 template<typename T>
00234 inline detail::MultibodyDynamicsBoundFunctor<T> make_upper_mbd_bounds(
00235 ublas::vector<size_t> const & pi
00236 , ublas::vector<T> const & mu
00237 , ublas::vector<T> const & val
00238 )
00239 {
00240 return detail::MultibodyDynamicsBoundFunctor<T>(false, pi, mu, val );
00241 }
00242
00243 }
00244 }
00245 }
00246
00247
00248 #endif