SeqAn3 3.3.0-rc.1
The Modern C++ library for sequence analysis.
 
Loading...
Searching...
No Matches
two_dimensional_matrix.hpp
Go to the documentation of this file.
1// -----------------------------------------------------------------------------------------------------
2// Copyright (c) 2006-2022, Knut Reinert & Freie Universität Berlin
3// Copyright (c) 2016-2022, 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 <algorithm>
16#include <memory>
17#include <ranges>
18#include <vector>
19
25
26namespace seqan3::detail
27{
28
31struct number_cols : strong_type<size_t, number_cols>
32{
35};
36
39struct number_rows : strong_type<size_t, number_rows>
40{
43};
44
61template <typename value_t,
62 typename allocator_t = std::allocator<value_t>,
65{
66private:
72
73 // Forward declaration. For definition see below.
74 template <bool const_range>
75 class basic_iterator;
76
77public:
81 // Doxygen: https://github.com/seqan/product_backlog/issues/424
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
103
111 {
112 storage.resize(row_dim.get() * col_dim.get());
113 }
114
121 template <std::ranges::forward_range entries_t>
122 requires (std::convertible_to<std::ranges::range_value_t<entries_t>, value_type>)
124 row_dim{row_dim.get()},
125 col_dim{col_dim.get()}
126 {
127 static_assert(std::move_constructible<std::ranges::range_value_t<entries_t>>,
128 "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
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>
170 requires std::assignable_from<other_value_t &, value_t &>
171 explicit constexpr two_dimensional_matrix(
174 {
175 for (size_t i = 0; i < cols(); ++i)
176 {
177 for (size_t j = 0; j < rows(); ++j)
178 {
179 matrix_coordinate coord{row_index_type{j}, column_index_type{i}};
180 (*this)[coord] = matrix[coord];
181 }
182 }
183 }
185
189 constexpr reference operator[](matrix_coordinate const & coordinate) noexcept
190 {
191 assert(coordinate.col < cols());
192 assert(coordinate.row < rows());
193
194 return *(begin()
195 + matrix_offset{row_index_type{static_cast<std::ptrdiff_t>(coordinate.row)},
196 column_index_type{static_cast<std::ptrdiff_t>(coordinate.col)}});
197 }
198
200 constexpr const_reference operator[](matrix_coordinate const & coordinate) const noexcept
201 {
202 assert(coordinate.col < cols());
203 assert(coordinate.row < rows());
204
205 return *(begin()
206 + matrix_offset{row_index_type{static_cast<std::ptrdiff_t>(coordinate.row)},
207 column_index_type{static_cast<std::ptrdiff_t>(coordinate.col)}});
208 }
209
211 constexpr reference at(matrix_coordinate const & coordinate)
212 {
213 if (coordinate.col >= cols())
214 throw std::invalid_argument{"Column index is out of range. Please check the dimensions of the matrix."};
215 if (coordinate.row >= rows())
216 throw std::invalid_argument{"Row index is out of range. Please check the dimensions of the matrix."};
217
218 return (*this)[coordinate];
219 }
220
222 constexpr const_reference at(matrix_coordinate const & coordinate) const
223 {
224 if (coordinate.col >= cols())
225 throw std::invalid_argument{"Column index is out of range. Please check the dimensions of the matrix."};
226 if (coordinate.row >= rows())
227 throw std::invalid_argument{"Row index is out of range. Please check the dimensions of the matrix."};
228
229 return (*this)[coordinate];
230 }
231
238 {
239 this->row_dim = row_dim.get();
240 this->col_dim = col_dim.get();
241 storage.resize(this->row_dim * this->col_dim);
242 }
243
245 size_t rows() const noexcept
246 {
247 return row_dim;
248 }
249
251 size_t cols() const noexcept
252 {
253 return col_dim;
254 }
255
257 constexpr pointer data() noexcept
258 {
259 return storage.data();
260 }
261
263 constexpr const_pointer data() const noexcept
264 {
265 return storage.data();
266 }
267
273 constexpr iterator begin() noexcept
274 {
275 return {*this, storage.begin()};
276 }
278 constexpr const_iterator begin() const noexcept
279 {
280 return {*this, storage.begin()};
281 }
282
284 constexpr const_iterator cbegin() const noexcept
285 {
286 return begin();
287 }
288
290 constexpr iterator end() noexcept
291 {
292 return {*this, storage.end()};
293 }
294
296 constexpr const_iterator end() const noexcept
297 {
298 return {*this, storage.end()};
299 }
300
302 constexpr const_iterator cend() const noexcept
303 {
304 return end();
305 }
307
308private:
312};
313
322template <typename value_t, typename allocator_t, matrix_major_order order>
323template <bool const_range>
324class two_dimensional_matrix<value_t, allocator_t, order>::basic_iterator :
325 public two_dimensional_matrix_iterator_base<basic_iterator<const_range>, order>
326{
327private:
330
333
335 template <typename derived_t, matrix_major_order other_order>
336 requires is_value_specialisation_of_v<derived_t, basic_iterator> && (other_order == order)
338
340 template <bool other_const_range>
341 friend class basic_iterator;
342
345
346public:
355 using pointer = typename storage_iterator::pointer;
361
365 constexpr basic_iterator() = default;
366 constexpr basic_iterator(basic_iterator const &) = default;
367 constexpr basic_iterator(basic_iterator &&) = default;
368 constexpr basic_iterator & operator=(basic_iterator const &) = default;
369 constexpr basic_iterator & operator=(basic_iterator &&) = default;
370 ~basic_iterator() = default;
371
376 constexpr basic_iterator(parent_t & matrix, storage_iterator iter) : matrix_ptr{&matrix}, host_iter{iter}
377 {}
378
380 constexpr basic_iterator(basic_iterator<!const_range> const & other) noexcept
381 requires const_range
382 : matrix_ptr{other.matrix_ptr}, host_iter{other.host_iter}
383 {}
385
386 // Import advance operator from base class.
387 using base_t::operator+=;
388
390 constexpr basic_iterator & operator+=(matrix_offset const & offset) noexcept
391 {
392 assert(matrix_ptr != nullptr);
393
394 if constexpr (order == matrix_major_order::column)
395 {
396 host_iter += (offset.col * matrix_ptr->rows());
397 host_iter += offset.row;
398 }
399 else
400 {
401 host_iter += offset.col;
402 host_iter += (offset.row * matrix_ptr->cols());
403 }
404 return *this;
405 }
406
408 matrix_coordinate coordinate() const noexcept
409 {
410 assert(matrix_ptr != nullptr);
411
412 auto diff = *this - matrix_ptr->begin();
413 if constexpr (order == matrix_major_order::column)
414 return {row_index_type{diff % matrix_ptr->rows()}, column_index_type{diff / matrix_ptr->rows()}};
415 else
416 return {row_index_type{diff / matrix_ptr->cols()}, column_index_type{diff % matrix_ptr->cols()}};
417 }
418
419private:
420 parent_t * matrix_ptr{nullptr};
421 storage_iterator host_iter{};
422};
423
424} // namespace seqan3::detail
T begin(T... args)
Defines the requirements of a matrix (e.g. score matrices, trace matrices).
Definition: matrix_concept.hpp:61
CRTP base class to declare a strong typedef for a regular type to avoid ambiguous parameter settings ...
Definition: strong_type.hpp:177
constexpr strong_type() noexcept=default
Defaulted.
A two-dimensional matrix iterator.
Definition: two_dimensional_matrix.hpp:326
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:376
matrix_coordinate coordinate() const noexcept
Returns the current position of the iterator as a two-dimensional matrix coordinate.
Definition: two_dimensional_matrix.hpp:408
constexpr basic_iterator & operator+=(matrix_offset const &offset) noexcept
Advances the iterator by the given offset.
Definition: two_dimensional_matrix.hpp:390
constexpr basic_iterator(basic_iterator &&)=default
Defaulted.
constexpr basic_iterator & operator=(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:344
typename storage_iterator::pointer pointer
The pointer type.
Definition: two_dimensional_matrix.hpp:355
constexpr basic_iterator & operator=(basic_iterator const &)=default
Defaulted.
constexpr basic_iterator(basic_iterator const &)=default
Defaulted.
constexpr basic_iterator(basic_iterator<!const_range > const &other) noexcept
Construction of cons-iterator from non-const-iterator.
Definition: two_dimensional_matrix.hpp:380
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:310
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:273
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:200
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:171
constexpr const_iterator begin() const noexcept
Returns an iterator pointing to the first element of the matrix.
Definition: two_dimensional_matrix.hpp:278
two_dimensional_matrix & operator=(two_dimensional_matrix &&)=default
Defaulted.
two_dimensional_matrix()=default
Defaulted.
size_type col_dim
The number of columns in the matrix.
Definition: two_dimensional_matrix.hpp:311
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:237
constexpr const_pointer data() const noexcept
Returns a pointer to the data.
Definition: two_dimensional_matrix.hpp:263
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:284
two_dimensional_matrix(two_dimensional_matrix const &)=default
Defaulted.
constexpr pointer data() noexcept
Returns a pointer to the data.
Definition: two_dimensional_matrix.hpp:257
constexpr reference operator[](matrix_coordinate const &coordinate) noexcept
Returns a reference to the element at the given coordinate.
Definition: two_dimensional_matrix.hpp:189
storage_type storage
The matrix as a one-dimensional (flattened) vector of entries.
Definition: two_dimensional_matrix.hpp:309
two_dimensional_matrix(number_rows const row_dim, number_cols const col_dim, entries_t entries)
Constructs the matrix by the given dimensions and initialises it with the given range.
Definition: two_dimensional_matrix.hpp:123
~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:302
size_t cols() const noexcept
The number of columns in the matrix.
Definition: two_dimensional_matrix.hpp:251
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:222
typename storage_type::value_type value_type
The value type.
Definition: two_dimensional_matrix.hpp:83
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:290
constexpr reference at(matrix_coordinate const &coordinate)
A reference to the entry of the matrix at the given coordinate.
Definition: two_dimensional_matrix.hpp:211
two_dimensional_matrix(two_dimensional_matrix &&)=default
Defaulted.
two_dimensional_matrix & operator=(two_dimensional_matrix const &)=default
Defaulted.
constexpr const_iterator end() const noexcept
Returns an iterator pointing behind-the-end of the matrix.
Definition: two_dimensional_matrix.hpp:296
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:245
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.
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: core/range/type_traits.hpp:44
@ offset
Sequence (seqan3::field::seq) relative start position (0-based), unsigned value.
Provides seqan3::detail::matrix_index, seqan3::detail::matrix_coordinate and associated strong types.
T move(T... args)
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:415
T resize(T... args)
A strong type for designated initialisation of the column index of a matrix.
Definition: matrix_coordinate.hpp:32
A representation of a location or offset within a two-dimensional matrix.
Definition: matrix_coordinate.hpp:90
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:61
Provides type traits for working with templates.
Provides seqan3::detail::two_dimensional_matrix_iterator_base.