00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifndef OPENMS_DATASTRUCTURES_MATRIX_H
00036 #define OPENMS_DATASTRUCTURES_MATRIX_H
00037
00038 #include <OpenMS/CONCEPT/Macros.h>
00039
00040 #include <cmath>
00041 #include <iomanip>
00042 #include <vector>
00043
00044 #include <gsl/gsl_matrix.h>
00045 #include <gsl/gsl_vector.h>
00046 #include <gsl/gsl_linalg.h>
00047
00048 namespace OpenMS
00049 {
00050
00078 template <typename Value>
00079 class Matrix :
00080 protected std::vector<Value>
00081 {
00082 protected:
00083 typedef std::vector<Value> Base;
00084
00085 public:
00086
00088
00089 typedef Base container_type;
00090
00091 typedef typename Base::difference_type difference_type;
00092 typedef typename Base::size_type size_type;
00093
00094 typedef typename Base::const_iterator const_iterator;
00095 typedef typename Base::const_reverse_iterator const_reverse_iterator;
00096 typedef typename Base::iterator iterator;
00097 typedef typename Base::reverse_iterator reverse_iterator;
00098
00099 typedef typename Base::const_reference const_reference;
00100 typedef typename Base::pointer pointer;
00101 typedef typename Base::reference reference;
00102 typedef typename Base::value_type value_type;
00103
00104 typedef typename Base::allocator_type allocator_type;
00106
00108
00109 typedef Base ContainerType;
00110 typedef difference_type DifferenceType;
00111 typedef size_type SizeType;
00112
00113 typedef const_iterator ConstIterator;
00114 typedef const_reverse_iterator ConstReverseIterator;
00115 typedef iterator Iterator;
00116 typedef reverse_iterator ReverseIterator;
00117
00118 typedef const_reference ConstReference;
00119 typedef pointer Pointer;
00120 typedef reference Reference;
00121 typedef value_type ValueType;
00122
00123 typedef allocator_type AllocatorType;
00125
00127
00128 Matrix() :
00129 Base(),
00130 rows_(0),
00131 cols_(0)
00132 {}
00133
00134 Matrix(const SizeType rows, const SizeType cols, ValueType value = ValueType()) :
00135 Base(rows * cols, value),
00136 rows_(rows),
00137 cols_(cols)
00138 {}
00139
00140 Matrix(const Matrix& source) :
00141 Base(source),
00142 rows_(source.rows_),
00143 cols_(source.cols_)
00144 {}
00145
00146 Matrix& operator=(const Matrix& rhs)
00147 {
00148 Base::operator=(rhs);
00149 rows_ = rhs.rows_;
00150 cols_ = rhs.cols_;
00151 return *this;
00152 }
00153
00154 ~Matrix() {}
00156
00158
00159 const_reference operator()(size_type const i, size_type const j) const
00160 {
00161 return getValue(i, j);
00162 }
00163
00164 reference operator()(size_type const i, size_type const j)
00165 {
00166 return getValue(i, j);
00167 }
00168
00169 const_reference getValue(size_type const i, size_type const j) const
00170 {
00171 return Base::operator[](index(i, j));
00172 }
00173
00174 reference getValue(size_type const i, size_type const j)
00175 {
00176 return Base::operator[](index(i, j));
00177 }
00178
00179 void setValue(size_type const i, size_type const j, value_type value)
00180 {
00181 Base::operator[](index(i, j)) = value;
00182 }
00183
00185 container_type row(size_type const i) const
00186 {
00187 #ifdef OPENMS_DEBUG
00188 if (i >= rows_) throw Exception::IndexOverflow(__FILE__, __LINE__, __PRETTY_FUNCTION__, i, rows_);
00189 #endif
00190 container_type values(cols_);
00191 for (size_type j = 0; j < cols_; j++)
00192 {
00193 values[j] = Base::operator[](index(i, j));
00194 }
00195 return values;
00196 }
00197
00199 container_type col(size_type const i) const
00200 {
00201 #ifdef OPENMS_DEBUG
00202 if (i >= cols_) throw Exception::IndexOverflow(__FILE__, __LINE__, __PRETTY_FUNCTION__, i, cols_);
00203 #endif
00204 container_type values(rows_);
00205 for (size_type j = 0; j < rows_; j++)
00206 {
00207 values[j] = Base::operator[](index(j, i));
00208 }
00209 return values;
00210 }
00211
00213
00214
00221 public:
00222
00223 using Base::begin;
00224 using Base::end;
00225 using Base::rbegin;
00226 using Base::rend;
00227
00228 using Base::front;
00229 using Base::back;
00230 using Base::assign;
00231
00232 using Base::empty;
00233 using Base::size;
00234
00235 using Base::capacity;
00236 using Base::max_size;
00237
00239
00240 void clear()
00241 {
00242 Base::clear();
00243 rows_ = 0;
00244 cols_ = 0;
00245 }
00246
00247 void resize(size_type i, size_type j, value_type value = value_type())
00248 {
00249 rows_ = i;
00250 cols_ = j;
00251 Base::resize(rows_ * cols_, value);
00252 }
00253
00254 void resize(std::pair<Size, Size> const& size_pair, value_type value = value_type())
00255 {
00256 rows_ = size_pair.first;
00257 cols_ = size_pair.second;
00258 Base::resize(rows_ * cols_, value);
00259 }
00260
00262 SizeType rows() const
00263 {
00264 return rows_;
00265 }
00266
00268 SizeType cols() const
00269 {
00270 return cols_;
00271 }
00272
00273 std::pair<Size, Size> sizePair() const
00274 {
00275 return std::pair<Size, Size>(rows_, cols_);
00276 }
00277
00282 SizeType const index(SizeType row, SizeType col) const
00283 {
00284 #ifdef OPENMS_DEBUG
00285 if (row >= rows_) throw Exception::IndexOverflow(__FILE__, __LINE__, __PRETTY_FUNCTION__, row, rows_);
00286 if (col >= cols_) throw Exception::IndexOverflow(__FILE__, __LINE__, __PRETTY_FUNCTION__, col, cols_);
00287 #endif
00288 return row * cols_ + col;
00289 }
00290
00295 std::pair<Size, Size> const indexPair(Size index) const
00296 {
00297 #ifdef OPENMS_DEBUG
00298 if (index >= size()) throw Exception::IndexOverflow(__FILE__, __LINE__, __PRETTY_FUNCTION__, index, size() - 1);
00299 #endif
00300 return std::pair<SizeType, SizeType>(index / cols_, index % cols_);
00301 }
00302
00307 SizeType colIndex(SizeType index) const
00308 {
00309 #ifdef OPENMS_DEBUG
00310 if (index >= size()) throw Exception::IndexOverflow(__FILE__, __LINE__, __PRETTY_FUNCTION__, index, size() - 1);
00311 #endif
00312 return index % cols_;
00313 }
00314
00319 SizeType rowIndex(SizeType index) const
00320 {
00321 #ifdef OPENMS_DEBUG
00322 if (index >= size()) throw Exception::IndexOverflow(__FILE__, __LINE__, __PRETTY_FUNCTION__, index, size() - 1);
00323 #endif
00324
00325 return index / cols_;
00326 }
00327
00333 bool operator==(Matrix const& rhs) const
00334 {
00335 OPENMS_PRECONDITION(cols_ == rhs.cols_,
00336 "Matrices have different row sizes.");
00337 OPENMS_PRECONDITION(rows_ == rhs.rows_,
00338 "Matrices have different column sizes.");
00339 return static_cast<typename Matrix<Value>::Base const&>(*this) == static_cast<typename Matrix<Value>::Base const&>(rhs);
00340 }
00341
00347 bool operator<(Matrix const& rhs) const
00348 {
00349 OPENMS_PRECONDITION(cols_ == rhs.cols_,
00350 "Matrices have different row sizes.");
00351 OPENMS_PRECONDITION(rows_ == rhs.rows_,
00352 "Matrices have different column sizes.");
00353 return static_cast<typename Matrix<Value>::Base const&>(*this) < static_cast<typename Matrix<Value>::Base const&>(rhs);
00354 }
00355
00357 template <int ROWS, int COLS>
00358 void setMatrix(const ValueType matrix[ROWS][COLS])
00359 {
00360 resize(ROWS, COLS);
00361 for (SizeType i = 0; i < this->rows_; ++i)
00362 {
00363 for (SizeType j = 0; j < this->cols_; ++j)
00364 {
00365 setValue(i, j, matrix[i][j]);
00366 }
00367 }
00368 }
00369
00377 gsl_matrix* toGslMatrix()
00378 {
00379 gsl_matrix* m_ptr = gsl_matrix_alloc(rows_, cols_);
00380
00381 for (size_type i = 0; i < this->rows_; ++i)
00382 {
00383 for (size_type j = 0; j < this->cols_; ++j)
00384 {
00385 gsl_matrix_set(m_ptr, i, j, (double) (*this)(i, j));
00386 }
00387 }
00388
00389 return m_ptr;
00390 }
00391
00392 protected:
00393
00395
00396
00397 SizeType rows_;
00399 SizeType cols_;
00401
00402 };
00403
00404
00405
00406
00412 template <typename Value>
00413 std::ostream& operator<<(std::ostream& os, const Matrix<Value>& matrix)
00414 {
00415 typedef typename Matrix<Value>::size_type size_type;
00416 for (size_type i = 0; i < matrix.rows(); ++i)
00417 {
00418 for (size_type j = 0; j < matrix.cols(); ++j)
00419 {
00420 os << std::setprecision(6) << std::setw(6) << matrix(i, j) << ' ';
00421 }
00422 os << std::endl;
00423 }
00424 return os;
00425 }
00426
00427 }
00428
00429 #endif // OPENMS_DATASTRUCTURES_MATRIX_H