SeqAn3  3.0.3
The Modern C++ library for sequence analysis.
two_dimensional_matrix.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2020, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2020, Knut Reinert & MPI für molekulare Genetik
4 // This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License
5 // shipped with this file and also available at: https://github.com/seqan/seqan3/blob/master/LICENSE.md
6 // -----------------------------------------------------------------------------------------------------
7 
13 #pragma once
14 
15 #include <seqan3/std/algorithm>
16 #include <memory>
17 #include <seqan3/std/ranges>
18 #include <vector>
19 
25 
26 namespace seqan3::detail
27 {
28 
31 struct number_cols : strong_type<size_t, number_cols>
32 {
35 };
36 
39 struct number_rows : strong_type<size_t, number_rows>
40 {
43 };
44 
61 template <typename value_t,
62  typename allocator_t = std::allocator<value_t>,
65 {
66 private:
67 
73 
74  // Forward declaration. For definition see below.
75  template <bool const_range>
76  class basic_iterator;
77 
78 public:
79 
83  using value_type = typename storage_type::value_type;
84  using reference = typename storage_type::reference;
85  using const_reference = typename storage_type::const_reference;
86  using pointer = typename storage_type::pointer;
87  using const_pointer = typename storage_type::const_pointer;
88  using difference_type = typename storage_type::difference_type;
89  using size_type = typename storage_type::size_type;
93 
97  two_dimensional_matrix() = default;
103 
110  {
111  storage.resize(row_dim.get() * col_dim.get());
112  }
113 
120  template <std::ranges::forward_range entries_t>
122  requires (std::convertible_to<std::ranges::range_value_t<entries_t>, value_type>)
124  two_dimensional_matrix(number_rows const row_dim, number_cols const col_dim, entries_t entries) :
125  row_dim{row_dim.get()},
126  col_dim{col_dim.get()}
127  {
128  static_assert(std::move_constructible<std::ranges::range_value_t<entries_t>>, "The value type must be moveable.");
129 
130  assert(static_cast<size_t>(std::ranges::distance(entries)) == (row_dim.get() * col_dim.get()));
131  storage.resize(row_dim.get() * col_dim.get());
132  std::ranges::move(entries, storage.begin());
133  }
134 
137  row_dim{row_dim.get()},
138  col_dim{col_dim.get()}
139  {
140  assert(static_cast<size_t>(std::ranges::distance(entries)) == (row_dim.get() * col_dim.get()));
141  storage = std::move(entries);
142  }
143 
169  template <typename other_value_t, typename other_allocator_t, matrix_major_order other_order>
171  requires std::assignable_from<other_value_t &, value_t &>
173  explicit constexpr two_dimensional_matrix(two_dimensional_matrix<other_value_t,
174  other_allocator_t,
175  other_order> const & matrix) :
177  {
178  for (size_t i = 0; i < cols(); ++i)
179  {
180  for (size_t j = 0; j < rows(); ++j)
181  {
182  matrix_coordinate coord{row_index_type{j}, column_index_type{i}};
183  (*this)[coord] = matrix[coord];
184  }
185  }
186  }
188 
192  constexpr reference operator[](matrix_coordinate const & coordinate) noexcept
193  {
194  assert(coordinate.col < cols());
195  assert(coordinate.row < rows());
196 
197  return *(begin() + matrix_offset{row_index_type{static_cast<std::ptrdiff_t>(coordinate.row)},
198  column_index_type{static_cast<std::ptrdiff_t>(coordinate.col)}});
199  }
200 
202  constexpr const_reference operator[](matrix_coordinate const & coordinate) const noexcept
203  {
204  assert(coordinate.col < cols());
205  assert(coordinate.row < rows());
206 
207  return *(begin() + matrix_offset{row_index_type{static_cast<std::ptrdiff_t>(coordinate.row)},
208  column_index_type{static_cast<std::ptrdiff_t>(coordinate.col)}});
209  }
210 
212  constexpr reference at(matrix_coordinate const & coordinate)
213  {
214  if (coordinate.col >= cols())
215  throw std::invalid_argument{"Column index is out of range. Please check the dimensions of the matrix."};
216  if (coordinate.row >= rows())
217  throw std::invalid_argument{"Row index is out of range. Please check the dimensions of the matrix."};
218 
219  return (*this)[coordinate];
220  }
221 
223  constexpr const_reference at(matrix_coordinate const & coordinate) const
224  {
225  if (coordinate.col >= cols())
226  throw std::invalid_argument{"Column index is out of range. Please check the dimensions of the matrix."};
227  if (coordinate.row >= rows())
228  throw std::invalid_argument{"Row index is out of range. Please check the dimensions of the matrix."};
229 
230  return (*this)[coordinate];
231  }
232 
239  {
240  this->row_dim = row_dim.get();
241  this->col_dim = col_dim.get();
242  storage.resize(this->row_dim * this->col_dim);
243  }
244 
246  size_t rows() const noexcept
247  {
248  return row_dim;
249  }
250 
252  size_t cols() const noexcept
253  {
254  return col_dim;
255  }
256 
258  constexpr pointer data() noexcept
259  {
260  return storage.data();
261  }
262 
264  constexpr const_pointer data() const noexcept
265  {
266  return storage.data();
267  }
268 
274  constexpr iterator begin() noexcept
275  {
276  return {*this, storage.begin()};
277  }
279  constexpr const_iterator begin() const noexcept
280  {
281  return {*this, storage.begin()};
282  }
283 
285  constexpr const_iterator cbegin() const noexcept
286  {
287  return begin();
288  }
289 
291  constexpr iterator end() noexcept
292  {
293  return {*this, storage.end()};
294  }
295 
297  constexpr const_iterator end() const noexcept
298  {
299  return {*this, storage.end()};
300  }
301 
303  constexpr const_iterator cend() const noexcept
304  {
305  return end();
306  }
308 
309 private:
310 
314 };
315 
324 template <typename value_t, typename allocator_t, matrix_major_order order>
325 template <bool const_range>
326 class two_dimensional_matrix<value_t, allocator_t, order>::basic_iterator :
327  public two_dimensional_matrix_iterator_base<basic_iterator<const_range>, order>
328 {
329 private:
332 
335 
337  template <typename derived_t, matrix_major_order other_order>
339  requires is_type_specialisation_of_v<derived_t, basic_iterator> && (other_order == order)
342 
344  template <bool other_const_range>
345  friend class basic_iterator;
346 
349 
350 public:
351 
360  using pointer = typename storage_iterator::pointer;
366 
370  constexpr basic_iterator() = default;
371  constexpr basic_iterator(basic_iterator const &) = default;
372  constexpr basic_iterator(basic_iterator &&) = default;
373  constexpr basic_iterator & operator=(basic_iterator const &) = default;
374  constexpr basic_iterator & operator=(basic_iterator &&) = default;
375  ~basic_iterator() = default;
376 
382  matrix_ptr{&matrix},
383  host_iter{iter}
384  {}
385 
387  constexpr basic_iterator(basic_iterator<!const_range> const & other) noexcept
389  requires const_range
391  : matrix_ptr{other.matrix_ptr},
392  host_iter{other.host_iter}
393  {}
395 
396  // Import advance operator from base class.
397  using base_t::operator+=;
398 
400  constexpr basic_iterator & operator+=(matrix_offset const & offset) noexcept
401  {
402  assert(matrix_ptr != nullptr);
403 
404  if constexpr (order == matrix_major_order::column)
405  {
406  host_iter += (offset.col * matrix_ptr->rows());
407  host_iter += offset.row;
408  }
409  else
410  {
411  host_iter += offset.col;
412  host_iter += (offset.row * matrix_ptr->cols());
413  }
414  return *this;
415  }
416 
418  matrix_coordinate coordinate() const noexcept
419  {
420  assert(matrix_ptr != nullptr);
421 
422  auto diff = *this - matrix_ptr->begin();
423  if constexpr (order == matrix_major_order::column)
424  return {row_index_type{diff % matrix_ptr->rows()}, column_index_type{diff / matrix_ptr->rows()}};
425  else
426  return {row_index_type{diff / matrix_ptr->cols()}, column_index_type{diff % matrix_ptr->cols()}};
427  }
428 
429 private:
430 
431  parent_t * matrix_ptr{nullptr};
432  storage_iterator host_iter{};
433 };
434 
435 } // namespace seqan3::detail
Adaptations of algorithms from the Ranges TS.
T begin(T... args)
CRTP base class to declare a strong typedef for a regular type to avoid ambiguous parameter settings ...
Definition: strong_type.hpp:182
A two-dimensional matrix iterator.
Definition: two_dimensional_matrix.hpp:328
constexpr basic_iterator(parent_t &matrix, storage_iterator iter)
Construction from the underlying matrix and the iterator over actual storage.
Definition: two_dimensional_matrix.hpp:381
constexpr basic_iterator(basic_iterator<!const_range > const &other) noexcept
Construction of cons-iterator from non-const-iterator.
Definition: two_dimensional_matrix.hpp:387
matrix_coordinate coordinate() const noexcept
Returns the current position of the iterator as a two-dimensional matrix coordinate.
Definition: two_dimensional_matrix.hpp:418
constexpr basic_iterator & operator=(basic_iterator const &)=default
Defaulted.
constexpr basic_iterator(basic_iterator &&)=default
Defaulted.
detail::maybe_const_iterator_t< const_range, storage_type > storage_iterator
The iterator of the underlying storage.
Definition: two_dimensional_matrix.hpp:348
typename storage_iterator::pointer pointer
The pointer type.
Definition: two_dimensional_matrix.hpp:360
constexpr basic_iterator & operator=(basic_iterator &&)=default
Defaulted.
constexpr basic_iterator & operator+=(matrix_offset const &offset) noexcept
Advances the iterator by the given offset.
Definition: two_dimensional_matrix.hpp:400
constexpr basic_iterator(basic_iterator const &)=default
Defaulted.
A crtp-base class for iterators over seqan3::detail::two_dimensional_matrix.
Definition: two_dimensional_matrix_iterator_base.hpp:77
A two dimensional matrix used inside of alignment algorithms.
Definition: two_dimensional_matrix.hpp:65
size_type row_dim
The number of rows in the matrix.
Definition: two_dimensional_matrix.hpp:312
two_dimensional_matrix(number_rows const row_dim, number_cols const col_dim)
Constructs the matrix by the given dimensions.
Definition: two_dimensional_matrix.hpp:108
constexpr iterator begin() noexcept
Returns an iterator pointing to the first element of the matrix.
Definition: two_dimensional_matrix.hpp:274
typename storage_type::reference reference
The reference type.
Definition: two_dimensional_matrix.hpp:84
typename storage_type::pointer pointer
The pointer type.
Definition: two_dimensional_matrix.hpp:86
constexpr const_reference operator[](matrix_coordinate const &coordinate) const noexcept
Returns a reference to the element at the given coordinate.
Definition: two_dimensional_matrix.hpp:202
constexpr const_iterator begin() const noexcept
Returns an iterator pointing to the first element of the matrix.
Definition: two_dimensional_matrix.hpp:279
two_dimensional_matrix()=default
Defaulted.
size_type col_dim
The number of columns in the matrix.
Definition: two_dimensional_matrix.hpp:313
two_dimensional_matrix & operator=(two_dimensional_matrix const &)=default
Defaulted.
void resize(number_rows const row_dim, number_cols const col_dim)
Resizes the underlying matrix storage to the given matrix dimensions.
Definition: two_dimensional_matrix.hpp:238
constexpr const_pointer data() const noexcept
Returns a pointer to the data.
Definition: two_dimensional_matrix.hpp:264
typename storage_type::const_reference const_reference
The const reference type.
Definition: two_dimensional_matrix.hpp:85
constexpr const_iterator cbegin() const noexcept
Returns an iterator pointing to the first element of the matrix.
Definition: two_dimensional_matrix.hpp:285
two_dimensional_matrix(two_dimensional_matrix const &)=default
Defaulted.
constexpr pointer data() noexcept
Returns a pointer to the data.
Definition: two_dimensional_matrix.hpp:258
constexpr reference operator[](matrix_coordinate const &coordinate) noexcept
Returns a reference to the element at the given coordinate.
Definition: two_dimensional_matrix.hpp:192
storage_type storage
The matrix as a one-dimensional (flattened) vector of entries.
Definition: two_dimensional_matrix.hpp:311
~two_dimensional_matrix()=default
Defaulted.
constexpr const_iterator cend() const noexcept
Returns an iterator pointing behind-the-end of the matrix.
Definition: two_dimensional_matrix.hpp:303
size_t cols() const noexcept
The number of columns in the matrix.
Definition: two_dimensional_matrix.hpp:252
constexpr two_dimensional_matrix(two_dimensional_matrix< other_value_t, other_allocator_t, other_order > const &matrix)
Explicit construction from the other major-order.
Definition: two_dimensional_matrix.hpp:173
constexpr const_reference at(matrix_coordinate const &coordinate) const
A reference to the entry of the matrix at the given coordinate.
Definition: two_dimensional_matrix.hpp:223
typename storage_type::value_type value_type
The value type.
Definition: two_dimensional_matrix.hpp:83
two_dimensional_matrix & operator=(two_dimensional_matrix &&)=default
Defaulted.
two_dimensional_matrix(number_rows const row_dim, number_cols const col_dim, storage_type entries)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: two_dimensional_matrix.hpp:136
typename storage_type::const_pointer const_pointer
The pointer type.
Definition: two_dimensional_matrix.hpp:87
constexpr iterator end() noexcept
Returns an iterator pointing behind-the-end of the matrix.
Definition: two_dimensional_matrix.hpp:291
constexpr reference at(matrix_coordinate const &coordinate)
A reference to the entry of the matrix at the given coordinate.
Definition: two_dimensional_matrix.hpp:212
two_dimensional_matrix(two_dimensional_matrix &&)=default
Defaulted.
constexpr const_iterator end() const noexcept
Returns an iterator pointing behind-the-end of the matrix.
Definition: two_dimensional_matrix.hpp:297
typename storage_type::size_type size_type
The difference type.
Definition: two_dimensional_matrix.hpp:89
size_t rows() const noexcept
The number of rows in the matrix.
Definition: two_dimensional_matrix.hpp:246
typename storage_type::difference_type difference_type
The difference type.
Definition: two_dimensional_matrix.hpp:88
Provides various transformation traits used by the range module.
T data(T... args)
Provides seqan3::detail::deferred_crtp_base.
Provides type traits for working with templates.
T end(T... args)
matrix_major_order
Selects the major order of the matrix.
Definition: two_dimensional_matrix_iterator_base.hpp:39
@ column
Accesses matrix in column major order.
@ row
Accesses matrix in row major order.
std::ranges::iterator_t< maybe_const_range_t< const_range, range_t > > maybe_const_iterator_t
Returns the const iterator of range_t if const_range is true; otherwise the non-const iterator.
Definition: type_traits.hpp:45
@ offset
Sequence (seqan3::field::seq) relative start position (0-based), unsigned value.
auto const move
A view that turns lvalue-references into rvalue-references.
Definition: move.hpp:70
Defines the requirements of a matrix (e.g. score matrices, trace matrices).
Provides seqan3::detail::alignment_coordinate and associated strong types.
The internal SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
constexpr auto const & get(configuration< configs_t... > const &config) noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: configuration.hpp:434
Adaptations of concepts from the Ranges TS.
T resize(T... args)
A strong type for designated initialisation of the column index of a matrix.
Definition: matrix_coordinate.hpp:34
A representation of a location or offset within a two-dimensional matrix.
Definition: matrix_coordinate.hpp:96
Strong type for setting the column dimension of a matrix.
Definition: two_dimensional_matrix.hpp:32
Strong type for setting the row dimension of a matrix.
Definition: two_dimensional_matrix.hpp:40
A strong type for designated initialisation of the row index of a matrix.
Definition: matrix_coordinate.hpp:65
This is helper structure to deprecate seqan3::value_type and will be removed before SeqAn 3....
Definition: pre.hpp:33
Provides seqan3::detail::two_dimensional_matrix_iterator_base.