A library for working with phylogenetic and population genetic data.
v0.27.0
containers/matrix.hpp
Go to the documentation of this file.
1 #ifndef GENESIS_UTILS_CONTAINERS_MATRIX_H_
2 #define GENESIS_UTILS_CONTAINERS_MATRIX_H_
3 
4 /*
5  Genesis - A toolkit for working with phylogenetic data.
6  Copyright (C) 2014-2018 Lucas Czech and HITS gGmbH
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 
36 
37 #include <stdexcept>
38 #include <string>
39 #include <vector>
40 
41 namespace genesis {
42 namespace utils {
43 
44 // =================================================================================================
45 // Matrix
46 // =================================================================================================
47 
48 template <typename T>
49 class Matrix
50 {
51 public:
52 
53  // -------------------------------------------------------------
54  // Typedefs
55  // -------------------------------------------------------------
56 
58  using value_type = T;
59 
60  using container_type = std::vector<T>;
61  using iterator = typename container_type::iterator;
62  using const_iterator = typename container_type::const_iterator;
63 
64  // -------------------------------------------------------------
65  // Constructors and Rule of Five
66  // -------------------------------------------------------------
67 
69  : rows_(0)
70  , cols_(0)
71  , data_()
72  {}
73 
74  Matrix (size_t rows, size_t cols)
75  : rows_( rows )
76  , cols_( cols )
77  , data_( rows * cols )
78  {}
79 
80  Matrix (size_t rows, size_t cols, T init)
81  : rows_( rows )
82  , cols_( cols )
83  , data_( rows * cols, init )
84  {}
85 
86  Matrix( size_t rows, size_t cols, std::vector<T> const& data )
87  : rows_( rows )
88  , cols_( cols )
89  , data_( data )
90  {
91  if( rows * cols != data_.size() ) {
92  throw std::length_error(
93  std::string(__PRETTY_FUNCTION__) + ": length_error. Expecting " +
94  std::to_string( rows ) + " * " + std::to_string( cols ) + " = " +
95  std::to_string( rows * cols ) + " elements, but provided data contains " +
96  std::to_string( data_.size() ) + " elements."
97  );
98  }
99  }
100 
101  Matrix( size_t rows, size_t cols, std::vector<T>&& data )
102  : rows_( rows )
103  , cols_( cols )
104  , data_( std::move( data ))
105  {
106  if( rows * cols != data_.size() ) {
107  throw std::length_error(
108  std::string(__PRETTY_FUNCTION__) + ": length_error. Expecting " +
109  std::to_string( rows ) + " * " + std::to_string( cols ) + " = " +
110  std::to_string( rows * cols ) + " elements, but provided data contains " +
111  std::to_string( data_.size() ) + " elements."
112  );
113  }
114  }
115 
116  Matrix (size_t rows, size_t cols, std::initializer_list<T> const& init_list)
117  : rows_(rows)
118  , cols_(cols)
119  , data_(rows * cols)
120  {
121  if (init_list.size() != size()) {
122  throw std::length_error(
123  std::string(__PRETTY_FUNCTION__) + ": length_error. Expecting " +
124  std::to_string( rows ) + " * " + std::to_string( cols ) + " = " +
125  std::to_string( rows * cols ) + " elements, but provided data contains " +
126  std::to_string( init_list.size() ) + " elements."
127  );
128  }
129 
130  size_t i = 0;
131  for (T const& v : init_list) {
132  data_[i] = v;
133  ++i;
134  }
135  }
136 
137  ~Matrix() = default;
138 
139  Matrix(Matrix const&) = default;
140  Matrix(Matrix&&) = default;
141 
142  Matrix& operator= (Matrix const&) = default;
143  Matrix& operator= (Matrix&&) = default;
144 
145  void swap (Matrix& other)
146  {
147  using std::swap;
148  swap(rows_, other.rows_);
149  swap(cols_, other.cols_);
150  swap(data_, other.data_);
151  }
152 
153  friend void swap( Matrix& lhs, Matrix& rhs )
154  {
155  lhs.swap( rhs );
156  }
157 
158  // -------------------------------------------------------------
159  // Properties
160  // -------------------------------------------------------------
161 
162  size_t rows() const
163  {
164  return rows_;
165  }
166 
167  size_t cols() const
168  {
169  return cols_;
170  }
171 
172  size_t size() const
173  {
174  return rows_ * cols_;
175  }
176 
177  bool empty() const
178  {
179  return size() == 0;
180  }
181 
182  container_type const& data() const
183  {
184  return data_;
185  }
186 
187  // -------------------------------------------------------------
188  // Element Access
189  // -------------------------------------------------------------
190 
191  T& at (const size_t row, const size_t col)
192  {
193  if (row >= rows_ || col >= cols_) {
194  throw std::out_of_range( "Matrix index out of range." );
195  }
196  return data_[row * cols_ + col];
197  }
198 
199  T const& at (const size_t row, const size_t col) const
200  {
201  if (row >= rows_ || col >= cols_) {
202  throw std::out_of_range( "Matrix index out of range." );
203  }
204  return data_[row * cols_ + col];
205  }
206 
207  T& operator () (const size_t row, const size_t col)
208  {
209  return data_[row * cols_ + col];
210  }
211 
212  T const& operator () (const size_t row, const size_t col) const
213  {
214  return data_[row * cols_ + col];
215  }
216 
217  // -------------------------------------------------------------
218  // Slicing
219  // -------------------------------------------------------------
220 
222  {
223  if( row >= rows_ ) {
224  throw std::out_of_range( "Matrix row index out of range." );
225  }
226 
227  return MatrixRow<self_type, value_type>( *this, row );
228  }
229 
231  {
232  if( row >= rows_ ) {
233  throw std::out_of_range( "Matrix row index out of range." );
234  }
235 
237  }
238 
240  {
241  if( col >= cols_ ) {
242  throw std::out_of_range( "Matrix column index out of range." );
243  }
244 
245  return MatrixCol<self_type, value_type>( *this, col );
246  }
247 
249  {
250  if( col >= cols_ ) {
251  throw std::out_of_range( "Matrix column index out of range." );
252  }
253 
255  }
256 
257  // -------------------------------------------------------------
258  // Iterators
259  // -------------------------------------------------------------
260 
262  {
263  return data_.begin();
264  }
265 
267  {
268  return data_.end();
269  }
270 
272  {
273  return data_.begin();
274  }
275 
277  {
278  return data_.end();
279  }
280 
282  {
283  return data_.cbegin();
284  }
285 
287  {
288  return data_.cend();
289  }
290 
291  // -------------------------------------------------------------
292  // Operators
293  // -------------------------------------------------------------
294 
295  bool operator == ( Matrix<T> const& other ) const
296  {
297  return rows_ == other.rows_
298  && cols_ == other.cols_
299  && data_ == other.data_;
300  }
301 
302  bool operator != ( Matrix<T> const& other ) const
303  {
304  return !(*this == other);
305  }
306 
307  // -------------------------------------------------------------
308  // Data Members
309  // -------------------------------------------------------------
310 
311 private:
312 
313  size_t rows_;
314  size_t cols_;
315  container_type data_;
316 };
317 
318 } // namespace utils
319 } // namespace genesis
320 
321 #endif // include guard
genesis::placement::swap
void swap(Sample &lhs, Sample &rhs)
Definition: sample.cpp:104
genesis::utils::Matrix::empty
bool empty() const
Definition: containers/matrix.hpp:177
genesis::utils::Matrix::swap
friend void swap(Matrix &lhs, Matrix &rhs)
Definition: containers/matrix.hpp:153
genesis::utils::Matrix::end
const_iterator end() const
Definition: containers/matrix.hpp:276
genesis::utils::Matrix::operator!=
bool operator!=(Matrix< T > const &other) const
Definition: containers/matrix.hpp:302
genesis::utils::Matrix::cols
size_t cols() const
Definition: containers/matrix.hpp:167
genesis::utils::Matrix::~Matrix
~Matrix()=default
genesis::utils::Matrix::Matrix
Matrix(size_t rows, size_t cols, std::initializer_list< T > const &init_list)
Definition: containers/matrix.hpp:116
genesis::utils::Matrix::end
iterator end()
Definition: containers/matrix.hpp:266
genesis::utils::Matrix::swap
void swap(Matrix &other)
Definition: containers/matrix.hpp:145
genesis::utils::Matrix::col
MatrixCol< self_type, value_type > col(size_t col)
Definition: containers/matrix.hpp:239
genesis::utils::Matrix::Matrix
Matrix(size_t rows, size_t cols, std::vector< T > &&data)
Definition: containers/matrix.hpp:101
genesis::utils::Matrix::at
T const & at(const size_t row, const size_t col) const
Definition: containers/matrix.hpp:199
genesis::utils::Matrix< size_t >
genesis::population::to_string
std::string to_string(GenomeLocus const &locus)
Definition: functions/genome_locus.hpp:48
genesis::utils::Matrix::operator()
T & operator()(const size_t row, const size_t col)
Definition: containers/matrix.hpp:207
genesis::utils::Matrix::cend
const_iterator cend() const
Definition: containers/matrix.hpp:286
genesis::utils::Matrix::Matrix
Matrix(size_t rows, size_t cols, std::vector< T > const &data)
Definition: containers/matrix.hpp:86
genesis::utils::Matrix::operator==
bool operator==(Matrix< T > const &other) const
Definition: containers/matrix.hpp:295
genesis::utils::Matrix::at
T & at(const size_t row, const size_t col)
Definition: containers/matrix.hpp:191
genesis::utils::Matrix< size_t >::const_iterator
typename container_type::const_iterator const_iterator
Definition: containers/matrix.hpp:62
genesis::utils::Matrix::data
container_type const & data() const
Definition: containers/matrix.hpp:182
col.hpp
genesis::utils::MatrixCol
View into a Matrix column.
Definition: col.hpp:60
genesis::utils::Matrix::operator=
Matrix & operator=(Matrix const &)=default
genesis::utils::Matrix::col
MatrixCol< const self_type, const value_type > col(size_t col) const
Definition: containers/matrix.hpp:248
genesis::utils::Matrix::Matrix
Matrix(size_t rows, size_t cols)
Definition: containers/matrix.hpp:74
genesis
Container namespace for all symbols of genesis in order to keep them separate when used as a library.
Definition: placement/formats/edge_color.cpp:42
row.hpp
genesis::utils::Matrix< size_t >::value_type
size_t value_type
Definition: containers/matrix.hpp:58
genesis::utils::Matrix< size_t >::iterator
typename container_type::iterator iterator
Definition: containers/matrix.hpp:61
genesis::utils::Matrix::Matrix
Matrix(size_t rows, size_t cols, T init)
Definition: containers/matrix.hpp:80
genesis::utils::Matrix::Matrix
Matrix()
Definition: containers/matrix.hpp:68
genesis::utils::Matrix::begin
iterator begin()
Definition: containers/matrix.hpp:261
genesis::utils::Matrix::cbegin
const_iterator cbegin() const
Definition: containers/matrix.hpp:281
genesis::utils::Matrix< size_t >::container_type
std::vector< size_t > container_type
Definition: containers/matrix.hpp:60
genesis::utils::Matrix::row
MatrixRow< self_type, value_type > row(size_t row)
Definition: containers/matrix.hpp:221
genesis::utils::MatrixRow
View into a Matrix row.
Definition: row.hpp:60
genesis::utils::Matrix::row
MatrixRow< const self_type, const value_type > row(size_t row) const
Definition: containers/matrix.hpp:230
genesis::utils::Matrix::rows
size_t rows() const
Definition: containers/matrix.hpp:162
genesis::utils::Matrix::size
size_t size() const
Definition: containers/matrix.hpp:172
genesis::utils::Matrix::begin
const_iterator begin() const
Definition: containers/matrix.hpp:271