Libbarrett  1.2.4
include/barrett/math/detail/matrix-inl.h
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Defines