00001 #ifndef OPENTISSUE_DYNAMICS_MBD_UTIL_MATH_MBD_OPTIMIZED_UBLAS_MATH_POLICY_H
00002 #define OPENTISSUE_DYNAMICS_MBD_UTIL_MATH_MBD_OPTIMIZED_UBLAS_MATH_POLICY_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/big/big_prod.h>
00014 #include <OpenTissue/core/math/big/big_prod_row.h>
00015 #include <OpenTissue/core/math/big/big_prod_add_rhs.h>
00016 #include <OpenTissue/core/math/big/big_prod_sub_rhs.h>
00017 #include <OpenTissue/core/math/big/big_prod_sub.h>
00018 #include <OpenTissue/core/math/big/big_prod_add.h>
00019 #include <OpenTissue/core/math/big/big_prod_trans.h>
00020
00021 #include <OpenTissue/core/math/big/io/big_matlab_write.h>
00022
00023 #include <OpenTissue/dynamics/mbd/math/mbd_math_update_f.h>
00024 #include <OpenTissue/dynamics/mbd/math/mbd_math_compute_f.h>
00025 #include <OpenTissue/dynamics/mbd/math/mbd_math_compute_diagonal.h>
00026 #include <OpenTissue/dynamics/mbd/math/mbd_math_compute_WJT.h>
00027
00028 #include <OpenTissue/core/math/math_basic_types.h>
00029
00030 namespace OpenTissue
00031 {
00032 namespace mbd
00033 {
00034
00042 template< typename real_type_>
00043 class optimized_ublas_math_policy
00044 : public OpenTissue::math::BasicMathTypes<real_type_,size_t>
00045 {
00046 public:
00047 typedef typename OpenTissue::math::BasicMathTypes<real_type_,size_t> basic_math_types;
00048 typedef typename basic_math_types::index_type index_type;
00049 typedef typename basic_math_types::real_type real_type;
00050
00051 public:
00052
00053 typedef ublas::compressed_matrix<real_type_> matrix_type;
00054 typedef ublas::vector<real_type_> vector_type;
00055 typedef typename vector_type::size_type size_type;
00056 typedef ublas::vector<index_type> idx_vector_type;
00057 typedef ublas::vector_range< vector_type > vector_range;
00058 typedef ublas::matrix_range< matrix_type > matrix_range;
00059 typedef ublas::vector_range< idx_vector_type > idx_vector_range;
00060
00061 public:
00062
00063 class system_matrix_type
00064 {
00065 public:
00066
00067 matrix_type m_J;
00068 matrix_type m_WJT;
00069 vector_type m_f;
00070 vector_type m_d;
00071
00072 real_type operator() (size_type const & i, size_type const & j)const
00073 {
00074 assert(i==j || !"system_matrix_type::operator(i,j): i was not equal to j");
00075 assert(i<m_d.size() || !"system_matrix_type::operator(i,j): i out of bound");
00076 return m_d(i);
00077 }
00078
00079 };
00080
00081 public:
00082
00083
00084 static matrix_range subrange(
00085 matrix_type & M
00086 , size_type start1
00087 , size_type stop1
00088 , size_type start2
00089 , size_type stop2
00090 )
00091 {
00092 return ublas::subrange(M,start1,stop1,start2,stop2);
00093 }
00094
00095 static vector_range subrange(vector_type & v, size_type start, size_type stop )
00096 {
00097 return ublas::subrange(v,start,stop);
00098 }
00099
00100 static idx_vector_range subrange(idx_vector_type & v, size_type start, size_type stop )
00101 {
00102 return ublas::subrange(v,start,stop);
00103 }
00104
00105 static void get_dimension(vector_type const & v, size_type & n)
00106 {
00107 n = v.size();
00108 }
00109
00110 static void get_dimensions(matrix_type const & A,size_type & m, size_type & n)
00111 {
00112 m = A.size1();
00113 n = A.size2();
00114 }
00115
00116 static void resize(vector_type & x,size_type n)
00117 {
00118 x.resize(n,false);
00119 x.clear();
00120 }
00121
00122 static void resize(idx_vector_type & x,size_type n)
00123 {
00124 x.resize(n,false);
00125 x.clear();
00126 }
00127
00128 static void resize(matrix_type & A,size_type m,size_type n)
00129 {
00130 A.resize(m,n,false);
00131 A.clear();
00132 }
00133
00137 static void prod(matrix_type const & A,vector_type const & x, vector_type const & b, vector_type & y)
00138 {
00139 y.resize(A.size1(),false);
00140 OpenTissue::math::big::prod_add_rhs(A,x,b,y);
00141 }
00142
00146 static void prod_minus(matrix_type const & A,vector_type const & x, vector_type const & b, vector_type & y)
00147 {
00148 y.resize(A.size1(),false);
00149 OpenTissue::math::big::prod_sub_rhs(A,x,b,y);
00150 }
00151
00155 static void prod(matrix_type const & A,vector_type const & x, vector_type & y)
00156 {
00157 y.resize(A.size1(),false);
00158 OpenTissue::math::big::prod(A,x,y);
00159 }
00160
00164 static void prod_add(matrix_type const & A,vector_type const & x, vector_type & y)
00165 {
00166 y.resize(A.size1(),false);
00167 OpenTissue::math::big::prod_add(A,x,y);
00168 }
00169
00173 static void prod(matrix_type const & A,vector_type const & x, vector_type & y, real_type const & s)
00174 {
00175 y.resize(A.size1(),false);
00176 OpenTissue::math::big::prod(A,x,s,y);
00177 }
00178
00182 static void prod_add(matrix_type const & A,vector_type const & x, vector_type & y, real_type const & s)
00183 {
00184 y.resize(A.size1(),false);
00185 OpenTissue::math::big::prod_add(A,x,s,y);
00186 }
00187
00191 static void prod_trans(matrix_type const & A,vector_type const & x, vector_type & y)
00192 {
00193 y.resize(A.size2(),false);
00194 OpenTissue::math::big::prod_trans(A,x,y);
00195 }
00196
00200 static void prod_trans(matrix_type const & A,vector_type const & x, vector_type const & b, vector_type & y)
00201 {
00202 y.resize(A.size2(),false);
00203 OpenTissue::math::big::prod_trans(A,x,b,y);
00204 }
00205
00209 static void prod(vector_type & x, real_type const & s )
00210 {
00211 x *= s;
00212 }
00213
00217 static void assign_minus(vector_type const & y, vector_type & x)
00218 {
00219 x = -y;
00220 }
00221
00222 static void compute_system_matrix(matrix_type const & invM, matrix_type const & J, system_matrix_type & A)
00223 {
00224 A.m_J.resize(J.size1(),J.size2(),false);
00225 A.m_WJT.resize(J.size1(),J.size2(),false);
00226 A.m_f.resize(invM.size1(),false);
00227 A.m_f.clear();
00228 A.m_d.resize(J.size1(),false);
00229
00230 A.m_J.assign(J);
00231
00232 math::compute_WJT(invM,J,A.m_WJT);
00233 math::compute_diagonal(J,A.m_WJT,A.m_d);
00234 }
00235
00236
00237 public:
00238
00240
00241 static real_type row_prod(system_matrix_type const & A,size_type i,vector_type const & x)
00242 {
00243 return OpenTissue::math::big::prod_row(A.m_J,A.m_f,i);
00244 }
00245
00246 static void prod(system_matrix_type const & A,vector_type const & x, vector_type const & b, vector_type & y)
00247 {
00248 y.resize(A.m_WJT.size1(),false);
00249
00250
00251 OpenTissue::math::big::prod_add_rhs(A.m_J, A.m_f, b, y);
00252 }
00253
00257 static void init_system_matrix(system_matrix_type & A, vector_type const & x)
00258 {
00259 math::compute_f(A.m_WJT,x,A.m_f);
00260 }
00261
00265 static void update_system_matrix(system_matrix_type & A, size_type i, real_type const & dx)
00266 {
00267 math::update_f(A.m_WJT,i,dx,A.m_f);
00268 }
00269
00270 };
00271
00272 }
00273 }
00274
00275 #endif