Libbarrett
1.2.4
|
00001 /* 00002 * matrix-inl.h 00003 * 00004 * Created on: Jan 13, 2010 00005 * Author: dc 00006 */ 00007 00008 #include <stdexcept> 00009 #include <cstring> 00010 #include <sstream> 00011 00012 #include <boost/static_assert.hpp> 00013 #include <libconfig.h++> 00014 00015 #include <gsl/gsl_vector.h> 00016 #include <gsl/gsl_matrix.h> 00017 00018 #include <barrett/detail/libconfig_utils.h> 00019 00020 00021 namespace barrett { 00022 namespace math { 00023 00024 00025 //template<int R, int C, typename Units> 00026 //inline Matrix<R,C, Units>::Matrix() : 00027 // Base(), gsl() 00028 //{ 00029 // initGslType(&gsl); 00030 //} 00031 // 00032 //template<int R, int C, typename Units> 00033 //inline Matrix<R,C, Units>::Matrix(int dim) : 00034 // Base(dim), gsl() 00035 //{ 00036 // initGslType(&gsl); 00037 //} 00038 // 00039 //template<int R, int C, typename Units> 00040 //inline Matrix<R,C, Units>::Matrix(int r, int c) : 00041 // Base(r, c), gsl() 00042 //{ 00043 // initGslType(&gsl); 00044 //} 00045 00046 template<int R, int C, typename Units> 00047 inline Matrix<R,C, Units>::Matrix(double x, double y) : 00048 Base(x, y), gsl() 00049 { 00050 initGslType(&gsl); 00051 } 00052 00053 template<int R, int C, typename Units> 00054 inline Matrix<R,C, Units>::Matrix(double x, double y, double z) : 00055 Base(x, y, z), gsl() 00056 { 00057 initGslType(&gsl); 00058 } 00059 00060 template<int R, int C, typename Units> 00061 inline Matrix<R,C, Units>::Matrix(double x, double y, double z, double w) : 00062 Base(x, y, z, w), gsl() 00063 { 00064 initGslType(&gsl); 00065 } 00066 00067 template<int R, int C, typename Units> 00068 inline Matrix<R,C, Units>::Matrix(const double* data) : 00069 Base(data), gsl() 00070 { 00071 initGslType(&gsl); 00072 } 00073 00074 template<int R, int C, typename Units> 00075 template<typename OtherDerived> 00076 inline Matrix<R,C, Units>::Matrix(const Eigen::MatrixBase<OtherDerived>& other) : 00077 Base(other), gsl() 00078 { 00079 initGslType(&gsl); 00080 } 00081 00082 template<int R, int C, typename Units> 00083 template<typename OtherDerived> 00084 inline Matrix<R,C, Units>::Matrix(const Eigen::RotationBase<OtherDerived,Base::ColsAtCompileTime>& r) : 00085 Base(r), gsl() 00086 { 00087 initGslType(&gsl); 00088 } 00089 00090 //template<int R, int C, typename Units> 00091 //template<typename OtherDerived> 00092 //inline Matrix& Matrix<R,C, Units>::operator=(const Eigen::RotationBase<OtherDerived,Base::ColsAtCompileTime>& r) 00093 //{ 00094 // Base::operator=(r); 00095 // return *this; 00096 //} 00097 00098 00099 template<int R, int C, typename Units> 00100 inline Matrix<R,C, Units>::Matrix(double d) : 00101 Base(), gsl() 00102 { 00103 initGslType(&gsl); 00104 this->setConstant(d); 00105 } 00106 00107 template<int R, int C, typename Units> 00108 inline Matrix<R,C, Units>::Matrix(int r, double d) : 00109 Base(r), gsl() 00110 { 00111 initGslType(&gsl); 00112 this->setConstant(d); 00113 } 00114 00115 template<int R, int C, typename Units> 00116 inline Matrix<R,C, Units>::Matrix(int r, int c, double d) : 00117 Base(r,c), gsl() 00118 { 00119 initGslType(&gsl); 00120 this->setConstant(d); 00121 } 00122 00123 template<int R, int C, typename Units> 00124 inline Matrix<R,C, Units>::Matrix(const gsl_type* gslType) : 00125 Base(), gsl() 00126 { 00127 resizeToMatchIfDynamic(gslType); 00128 initGslType(&gsl); 00129 copyFrom(gslType); 00130 } 00131 00132 template<int R, int C, typename Units> 00133 inline Matrix<R,C, Units>::Matrix(const libconfig::Setting& setting) : 00134 Base(), gsl() 00135 { 00136 resizeIfDynamic(setting.getLength(), setting[0].isNumber() ? 1 : setting[0].getLength()); 00137 initGslType(&gsl); 00138 copyFrom(setting); 00139 } 00140 00141 00142 00143 template<int R, int C, typename Units> 00144 inline Matrix<R,C, Units>::Matrix(const Matrix& a) : 00145 Base(a), gsl(a.gsl) 00146 { 00147 initGslType(&gsl); 00148 } 00149 00150 template<int R, int C, typename Units> 00151 inline Matrix<R,C, Units>::~Matrix() 00152 { 00153 } 00154 00155 00156 template<int R, int C, typename Units> 00157 inline size_t Matrix<R,C, Units>::serializedLength() 00158 { 00159 // This method assumes a fixed-size Matrix. 00160 BOOST_STATIC_ASSERT( !Traits<type>::IsDynamic ); 00161 return sizeof(double) * SIZE; 00162 } 00163 00164 template<int R, int C, typename Units> 00165 inline void Matrix<R,C, Units>::serialize(char* dest) const 00166 { 00167 std::memcpy(dest, this->data(), serializedLength()); 00168 } 00169 00170 template<int R, int C, typename Units> 00171 inline Matrix<R,C, Units> Matrix<R,C, Units>::unserialize(char* source) 00172 { 00173 Matrix<R,C, Units> a; 00174 std::memcpy(a.data(), source, serializedLength()); 00175 return a; 00176 } 00177 00178 00179 template<int R, int C, typename Units> 00180 inline void Matrix<R,C, Units>::copyTo(gsl_type* gslType) const 00181 throw(std::logic_error) 00182 { 00183 checkSize(gslType); 00184 copyToHelper(gslType); 00185 } 00186 00187 template<int R, int C, typename Units> 00188 inline void Matrix<R,C, Units>::copyFrom(const gsl_type* gslType) 00189 throw(std::logic_error) 00190 { 00191 checkSize(gslType); 00192 copyFromHelper(gslType); 00193 } 00194 00195 template<int R, int C, typename Units> 00196 inline void Matrix<R,C, Units>::copyFrom(const libconfig::Setting& setting) 00197 { 00198 // special case: both column and row vectors can be initialized by a config row vector 00199 if (this->isVector()) { 00200 if (setting.getLength() != this->size()) { 00201 std::stringstream ss; 00202 ss << "(math::Matrix<>::copyFrom(libconfig::Setting)): The size of " 00203 "the configuration list must match the size of the Matrix. " 00204 "Expected size " << this->size() << ", got size " << setting.getLength() << 00205 ". Path: \"" << setting.getPath() << "\", Line: " << 00206 setting.getSourceLine(); 00207 throw std::runtime_error(ss.str()); 00208 } 00209 00210 if (setting[0].isNumber()) { // if setting is a row vector 00211 for (int i = 0; i < this->size(); ++i) { 00212 (*this)[i] = barrett::detail::numericToDouble(setting[i]); 00213 } 00214 return; 00215 } // else setting is a column vector or a matrix 00216 } 00217 00218 00219 // column vectors and matrices 00220 if (setting.getLength() != this->rows()) { 00221 std::stringstream ss; 00222 ss << "(math::Matrix<>::copyFrom(libconfig::Setting)): Wrong number of " 00223 "rows. Expected " << this->rows() << ", got " << 00224 setting.getLength() << ". Path: \"" << 00225 setting.getPath() << "\", Line: " << setting.getSourceLine(); 00226 throw std::runtime_error(ss.str()); 00227 } 00228 for (int i = 0; i < this->rows(); ++i) { 00229 if (setting[i].getLength() != this->cols()) { 00230 std::stringstream ss; 00231 ss << "(math::Matrix<>::copyFrom(libconfig::Setting)): Wrong number of " 00232 "columns. Expected " << this->cols() << ", got " << 00233 setting[i].getLength() << ". Path: \"" << 00234 setting[i].getPath() << "\", Line: " << setting[i].getSourceLine(); 00235 throw std::runtime_error(ss.str()); 00236 } 00237 for (int j = 0; j < this->cols(); ++j) { 00238 (*this)(i,j) = barrett::detail::numericToDouble(setting[i][j]); 00239 } 00240 } 00241 } 00242 00243 template<int R, int C, typename Units> 00244 inline typename Matrix<R,C, Units>::gsl_type* Matrix<R,C, Units>::asGslType() 00245 { 00246 return &(this->gsl); 00247 } 00248 00249 template<int R, int C, typename Units> 00250 inline const typename Matrix<R,C, Units>::gsl_type* Matrix<R,C, Units>::asGslType() const 00251 { 00252 return &(this->gsl); 00253 } 00254 00255 template<int R, int C, typename Units> 00256 inline void Matrix<R,C, Units>::resizeIfDynamic(int r, int c) 00257 { 00258 if (Traits<type>::IsDynamic) { 00259 this->resize(r,c); 00260 } 00261 } 00262 00263 template<int R, int C, typename Units> 00264 inline void Matrix<R,C, Units>::initGslType(gsl_vector* g) 00265 { 00266 g->size = this->size(); 00267 g->stride = 1; 00268 g->data = this->data(); 00269 g->block = NULL; 00270 g->owner = 0; 00271 } 00272 template<int R, int C, typename Units> 00273 inline void Matrix<R,C, Units>::initGslType(gsl_matrix* g) 00274 { 00275 g->size1 = this->rows(); 00276 g->size2 = this->cols(); 00277 g->tda = this->cols(); 00278 g->data = this->data(); 00279 g->block = NULL; 00280 g->owner = 0; 00281 } 00282 00283 template<int R, int C, typename Units> 00284 inline void Matrix<R,C, Units>::resizeToMatchIfDynamic(const gsl_vector* g) 00285 { 00286 resizeIfDynamic(g->size); 00287 } 00288 template<int R, int C, typename Units> 00289 inline void Matrix<R,C, Units>::resizeToMatchIfDynamic(const gsl_matrix* g) 00290 { 00291 resizeIfDynamic(g->size1, g->size2); 00292 } 00293 00294 template<int R, int C, typename Units> 00295 void Matrix<R,C, Units>::checkSize(const gsl_vector* g) const 00296 { 00297 if (g->size != static_cast<size_t>(this->size())) { 00298 std::stringstream ss; 00299 ss << "(math::Matrix<>::checkSize(gsl_vector*)): The size of the " 00300 "gsl_vector must match the size of the Matrix. Expected size " 00301 << this->size() << ", got size " << g->size; 00302 throw std::logic_error(ss.str()); 00303 } 00304 } 00305 template<int R, int C, typename Units> 00306 void Matrix<R,C, Units>::checkSize(const gsl_matrix* g) const 00307 { 00308 if (g->size1 != static_cast<size_t>(this->rows()) 00309 || g->size2 != static_cast<size_t>(this->cols())) { 00310 std::stringstream ss; 00311 ss << "(math::Matrix<>::checkSize(gsl_matrix*)): The size of the " 00312 "gsl_matrix must match the size of the Matrix. Expected size " 00313 << this->rows() << "x" << this->cols() << ", got size " 00314 << g->size1 << "x" << g->size2; 00315 throw std::logic_error(ss.str()); 00316 } 00317 } 00318 00319 template<int R, int C, typename Units> 00320 void Matrix<R,C, Units>::copyToHelper(gsl_vector* g) const 00321 { 00322 for (int i = 0; i < this->size(); ++i) { 00323 gsl_vector_set(g, i, (*this)[i]); 00324 } 00325 } 00326 template<int R, int C, typename Units> 00327 void Matrix<R,C, Units>::copyToHelper(gsl_matrix* g) const 00328 { 00329 for (int i = 0; i < this->rows(); ++i) { 00330 for (int j = 0; j < this->cols(); ++j) { 00331 gsl_matrix_set(g, i,j, (*this)(i,j)); 00332 } 00333 } 00334 } 00335 00336 template<int R, int C, typename Units> 00337 void Matrix<R,C, Units>::copyFromHelper(const gsl_vector* g) 00338 { 00339 for (int i = 0; i < this->size(); ++i) { 00340 (*this)[i] = gsl_vector_get(g, i); 00341 } 00342 } 00343 template<int R, int C, typename Units> 00344 void Matrix<R,C, Units>::copyFromHelper(const gsl_matrix* g) 00345 { 00346 for (int i = 0; i < this->rows(); ++i) { 00347 for (int j = 0; j < this->cols(); ++j) { 00348 (*this)(i,j) = gsl_matrix_get(g, i,j); 00349 } 00350 } 00351 } 00352 00353 00354 template<int R, int C, typename Units> 00355 std::ostream& operator<< (std::ostream& os, const Matrix<R,C, Units>& a) { 00356 bool isVector = a.isVector(); 00357 int maxRowIndex = a.rows() - 1; 00358 int maxColIndex = a.cols() - 1; 00359 00360 os << "["; 00361 for (int i = 0; i < a.rows(); ++i) { 00362 for (int j = 0; j < a.cols(); ++j) { 00363 os << a(i,j); 00364 if ((isVector && i != maxRowIndex) || j != maxColIndex) { 00365 os << ", "; 00366 } 00367 } 00368 if (!isVector && i != maxRowIndex) { 00369 os << "\n "; 00370 } 00371 } 00372 os << "]"; 00373 00374 return os; 00375 } 00376 00377 00378 } 00379 }