A toolkit for working with phylogenetic data.
v0.18.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
matrix.hpp
Go to the documentation of this file.
1 #ifndef GENESIS_UTILS_MATH_MATRIX_H_
2 #define GENESIS_UTILS_MATH_MATRIX_H_
3 
4 /*
5  Genesis - A toolkit for working with phylogenetic data.
6  Copyright (C) 2014-2017 Lucas Czech
7 
8  This program is free software: you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation, either version 3 of the License, or
11  (at your option) any later version.
12 
13  This program is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program. If not, see <http://www.gnu.org/licenses/>.
20 
21  Contact:
22  Lucas Czech <lucas.czech@h-its.org>
23  Exelixis Lab, Heidelberg Institute for Theoretical Studies
24  Schloss-Wolfsbrunnenweg 35, D-69118 Heidelberg, Germany
25 */
26 
34 #include <stdexcept>
35 #include <string>
36 #include <vector>
37 
38 namespace genesis {
39 namespace utils {
40 
41 // =================================================================================================
42 // Matrix
43 // =================================================================================================
44 
45 template <typename T>
46 class Matrix
47 {
48 public:
49 
50  // -------------------------------------------------------------
51  // Typedefs
52  // -------------------------------------------------------------
53 
54  typedef T value_type;
55  typedef typename std::vector<T>::iterator iterator;
56  typedef typename std::vector<T>::const_iterator const_iterator;
57 
58  // -------------------------------------------------------------
59  // Constructors and Rule of Five
60  // -------------------------------------------------------------
61 
63  : rows_(0)
64  , cols_(0)
65  , data_()
66  {}
67 
68  Matrix (size_t rows, size_t cols)
69  : rows_( rows )
70  , cols_( cols )
71  , data_( rows * cols )
72  {}
73 
74  Matrix (size_t rows, size_t cols, T init)
75  : rows_( rows )
76  , cols_( cols )
77  , data_( rows * cols, init )
78  {}
79 
80  Matrix( size_t rows, size_t cols, std::vector<T> const& data )
81  : rows_( rows )
82  , cols_( cols )
83  , data_( data )
84  {
85  if( rows * cols != data_.size() ) {
86  throw std::length_error(
87  std::string(__PRETTY_FUNCTION__) + ": length_error. Expecting " +
88  std::to_string( rows ) + " * " + std::to_string( cols ) + " = " +
89  std::to_string( rows * cols ) + " elements, but provided data contains " +
90  std::to_string( data_.size() ) + " elements."
91  );
92  }
93  }
94 
95  Matrix( size_t rows, size_t cols, std::vector<T>&& data )
96  : rows_( rows )
97  , cols_( cols )
98  , data_( std::move( data ))
99  {
100  if( rows * cols != data_.size() ) {
101  throw std::length_error(
102  std::string(__PRETTY_FUNCTION__) + ": length_error. Expecting " +
103  std::to_string( rows ) + " * " + std::to_string( cols ) + " = " +
104  std::to_string( rows * cols ) + " elements, but provided data contains " +
105  std::to_string( data_.size() ) + " elements."
106  );
107  }
108  }
109 
110  Matrix (size_t rows, size_t cols, std::initializer_list<T> const& init_list)
111  : rows_(rows)
112  , cols_(cols)
113  , data_(rows * cols)
114  {
115  if (init_list.size() != size()) {
116  throw std::length_error(
117  std::string(__PRETTY_FUNCTION__) + ": length_error. Expecting " +
118  std::to_string( rows ) + " * " + std::to_string( cols ) + " = " +
119  std::to_string( rows * cols ) + " elements, but provided data contains " +
120  std::to_string( init_list.size() ) + " elements."
121  );
122  }
123 
124  size_t i = 0;
125  for (T const& v : init_list) {
126  data_[i] = v;
127  ++i;
128  }
129  }
130 
131  ~Matrix() = default;
132 
133  Matrix(Matrix const&) = default;
134  Matrix(Matrix&&) = default;
135 
136  Matrix& operator= (Matrix const&) = default;
137  Matrix& operator= (Matrix&&) = default;
138 
139  void swap (Matrix& other)
140  {
141  using std::swap;
142  swap(rows_, other.rows_);
143  swap(cols_, other.cols_);
144  swap(data_, other.data_);
145  }
146 
147  // -------------------------------------------------------------
148  // Properties
149  // -------------------------------------------------------------
150 
151  size_t rows() const
152  {
153  return rows_;
154  }
155 
156  size_t cols() const
157  {
158  return cols_;
159  }
160 
161  size_t size() const
162  {
163  return rows_ * cols_;
164  }
165 
166  std::vector<T> const& data() const
167  {
168  return data_;
169  }
170 
171  // -------------------------------------------------------------
172  // Element Access
173  // -------------------------------------------------------------
174 
175  T& at (const size_t row, const size_t col)
176  {
177  if (row >= rows_ || col >= cols_) {
178  throw std::out_of_range("__FUNCTION__: out_of_range");
179  }
180  return data_[row * cols_ + col];
181  }
182 
183  const T at (const size_t row, const size_t col) const
184  {
185  if (row >= rows_ || col >= cols_) {
186  throw std::out_of_range("__FUNCTION__: out_of_range");
187  }
188  return data_[row * cols_ + col];
189  }
190 
191  T& operator () (const size_t row, const size_t col)
192  {
193  return data_[row * cols_ + col];
194  }
195 
196  const T operator () (const size_t row, const size_t col) const
197  {
198  return data_[row * cols_ + col];
199  }
200 
201  // -------------------------------------------------------------
202  // Slicing
203  // -------------------------------------------------------------
204 
205  std::vector<T> row( size_t index ) const
206  {
207  if( index >= rows_ ) {
208  throw std::out_of_range("__FUNCTION__: out_of_range");
209  }
210 
211  auto result = std::vector<T>( cols() );
212  for( size_t i = 0; i < cols(); ++i ) {
213  result[i] = operator()( index, i );
214  }
215  return result;
216  }
217 
218  std::vector<T> col( size_t index ) const
219  {
220  if( index >= cols_ ) {
221  throw std::out_of_range("__FUNCTION__: out_of_range");
222  }
223 
224  auto result = std::vector<T>( rows() );
225  for( size_t i = 0; i < rows(); ++i ) {
226  result[i] = operator()( i, index );
227  }
228  return result;
229  }
230 
231  // -------------------------------------------------------------
232  // Iterators
233  // -------------------------------------------------------------
234 
236  {
237  return data_.begin();
238  }
239 
241  {
242  return data_.end();
243  }
244 
246  {
247  return data_.begin();
248  }
249 
251  {
252  return data_.end();
253  }
254 
256  {
257  return data_.cbegin();
258  }
259 
261  {
262  return data_.cend();
263  }
264 
265  // -------------------------------------------------------------
266  // Operators
267  // -------------------------------------------------------------
268 
269  bool operator == (const Matrix<T>& rhs) const
270  {
271  return rows_ == rhs.rows_
272  && cols_ == rhs.cols_
273  && data_ == rhs.data_;
274  }
275 
276  bool operator != (const Matrix<T>& rhs) const
277  {
278  return !(*this == rhs);
279  }
280 
281  // -------------------------------------------------------------
282  // Data Members
283  // -------------------------------------------------------------
284 
285 private:
286 
287  size_t rows_;
288  size_t cols_;
289  std::vector<T> data_;
290 };
291 
292 } // namespace utils
293 } // namespace genesis
294 
295 // =================================================================================================
296 // Namespace std Extension
297 // =================================================================================================
298 
299 /*
300 namespace std {
301 
302 template<typename T>
303 inline void swap (genesis::utils::Matrix<T>& lhs, genesis::utils::Matrix<T>& rhs) noexcept
304 {
305  lhs.swap(rhs);
306 }
307 
308 } // namespace std
309 */
310 
311 #endif // include guard
size_t cols() const
Definition: matrix.hpp:156
const_iterator cbegin() const
Definition: matrix.hpp:255
void swap(SequenceSet &lhs, SequenceSet &rhs)
std::vector< T > const & data() const
Definition: matrix.hpp:166
Matrix(size_t rows, size_t cols, std::initializer_list< T > const &init_list)
Definition: matrix.hpp:110
T & at(const size_t row, const size_t col)
Definition: matrix.hpp:175
Matrix(size_t rows, size_t cols, T init)
Definition: matrix.hpp:74
std::string to_string(T const &v)
Return a string representation of a given value.
Definition: string.hpp:300
void swap(Matrix &other)
Definition: matrix.hpp:139
size_t size() const
Definition: matrix.hpp:161
const_iterator end() const
Definition: matrix.hpp:250
std::vector< T > row(size_t index) const
Definition: matrix.hpp:205
const_iterator cend() const
Definition: matrix.hpp:260
Matrix(size_t rows, size_t cols, std::vector< T > const &data)
Definition: matrix.hpp:80
bool operator==(const Matrix< T > &rhs) const
Definition: matrix.hpp:269
Matrix(size_t rows, size_t cols)
Definition: matrix.hpp:68
Matrix(size_t rows, size_t cols, std::vector< T > &&data)
Definition: matrix.hpp:95
size_t rows() const
Definition: matrix.hpp:151
const_iterator begin() const
Definition: matrix.hpp:245
std::vector< T > col(size_t index) const
Definition: matrix.hpp:218
std::vector< T >::iterator iterator
Definition: matrix.hpp:55
Matrix & operator=(Matrix const &)=default
std::vector< T >::const_iterator const_iterator
Definition: matrix.hpp:56
const T at(const size_t row, const size_t col) const
Definition: matrix.hpp:183
bool operator!=(const Matrix< T > &rhs) const
Definition: matrix.hpp:276
T & operator()(const size_t row, const size_t col)
Definition: matrix.hpp:191