SeqAn3 3.4.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// SPDX-FileCopyrightText: 2006-2024 Knut Reinert & Freie Universität Berlin
2// SPDX-FileCopyrightText: 2016-2024 Knut Reinert & MPI für molekulare Genetik
3// SPDX-License-Identifier: BSD-3-Clause
4
10#pragma once
11
12#include <algorithm>
13#include <memory>
14#include <ranges>
15#include <vector>
16
22
23namespace seqan3::detail
24{
25
28struct number_cols : strong_type<size_t, number_cols>
29{
32};
33
36struct number_rows : strong_type<size_t, number_rows>
37{
40};
41
58template <typename value_t,
59 typename allocator_t = std::allocator<value_t>,
62{
63private:
69
70 // Forward declaration. For definition see below.
71 template <bool const_range>
72 class basic_iterator;
73
74public:
78 // Doxygen: https://github.com/seqan/product_backlog/issues/424
80 using value_type = typename storage_type::value_type;
81 using reference = typename storage_type::reference;
82 using const_reference = typename storage_type::const_reference;
83 using pointer = typename storage_type::pointer;
84 using const_pointer = typename storage_type::const_pointer;
85 using difference_type = typename storage_type::difference_type;
86 using size_type = typename storage_type::size_type;
90
100
111
118 template <std::ranges::forward_range entries_t>
119 requires (std::convertible_to<std::ranges::range_value_t<entries_t>, value_type>)
121 row_dim{row_dim.get()},
122 col_dim{col_dim.get()}
123 {
124 static_assert(std::move_constructible<std::ranges::range_value_t<entries_t>>,
125 "The value type must be moveable.");
126
127 assert(static_cast<size_t>(std::ranges::distance(entries)) == (row_dim.get() * col_dim.get()));
128 storage.resize(row_dim.get() * col_dim.get());
129 std::ranges::move(entries, storage.begin());
130 }
131
136 {
137 assert(static_cast<size_t>(std::ranges::distance(entries)) == (row_dim.get() * col_dim.get()));
138 storage = std::move(entries);
139 }
140
166 template <typename other_value_t, typename other_allocator_t, matrix_major_order other_order>
167 requires std::assignable_from<other_value_t &, value_t &>
168 explicit constexpr two_dimensional_matrix(
171 {
172 for (size_t i = 0; i < cols(); ++i)
173 {
174 for (size_t j = 0; j < rows(); ++j)
175 {
176 matrix_coordinate coord{row_index_type{j}, column_index_type{i}};
177 (*this)[coord] = matrix[coord];
178 }
179 }
180 }
182
186 constexpr reference operator[](matrix_coordinate const & coordinate) noexcept
187 {
188 assert(coordinate.col < cols());
189 assert(coordinate.row < rows());
190
191 return *(begin()
192 + matrix_offset{row_index_type{static_cast<std::ptrdiff_t>(coordinate.row)},
193 column_index_type{static_cast<std::ptrdiff_t>(coordinate.col)}});
194 }
195
197 constexpr const_reference operator[](matrix_coordinate const & coordinate) const noexcept
198 {
199 assert(coordinate.col < cols());
200 assert(coordinate.row < rows());
201
202 return *(begin()
203 + matrix_offset{row_index_type{static_cast<std::ptrdiff_t>(coordinate.row)},
204 column_index_type{static_cast<std::ptrdiff_t>(coordinate.col)}});
205 }
206
208 constexpr reference at(matrix_coordinate const & coordinate)
209 {
210 if (coordinate.col >= cols())
211 throw std::invalid_argument{"Column index is out of range. Please check the dimensions of the matrix."};
212 if (coordinate.row >= rows())
213 throw std::invalid_argument{"Row index is out of range. Please check the dimensions of the matrix."};
214
215 return (*this)[coordinate];
216 }
217
219 constexpr const_reference at(matrix_coordinate const & coordinate) const
220 {
221 if (coordinate.col >= cols())
222 throw std::invalid_argument{"Column index is out of range. Please check the dimensions of the matrix."};
223 if (coordinate.row >= rows())
224 throw std::invalid_argument{"Row index is out of range. Please check the dimensions of the matrix."};
225
226 return (*this)[coordinate];
227 }
228
235 {
236 this->row_dim = row_dim.get();
237 this->col_dim = col_dim.get();
238 storage.resize(this->row_dim * this->col_dim);
239 }
240
242 size_t rows() const noexcept
243 {
244 return row_dim;
245 }
246
248 size_t cols() const noexcept
249 {
250 return col_dim;
251 }
252
254 constexpr pointer data() noexcept
255 {
256 return storage.data();
257 }
258
260 constexpr const_pointer data() const noexcept
261 {
262 return storage.data();
263 }
264
270 constexpr iterator begin() noexcept
271 {
272 return {*this, storage.begin()};
273 }
275 constexpr const_iterator begin() const noexcept
276 {
277 return {*this, storage.begin()};
278 }
279
281 constexpr const_iterator cbegin() const noexcept
282 {
283 return begin();
284 }
285
287 constexpr iterator end() noexcept
288 {
289 return {*this, storage.end()};
290 }
291
293 constexpr const_iterator end() const noexcept
294 {
295 return {*this, storage.end()};
296 }
297
299 constexpr const_iterator cend() const noexcept
300 {
301 return end();
302 }
304
305private:
309};
310
319template <typename value_t, typename allocator_t, matrix_major_order order>
320template <bool const_range>
321class two_dimensional_matrix<value_t, allocator_t, order>::basic_iterator :
322 public two_dimensional_matrix_iterator_base<basic_iterator<const_range>, order>
323{
324private:
327
330
332 template <typename derived_t, matrix_major_order other_order>
334
336 template <bool other_const_range>
337 friend class basic_iterator;
338
341
342public:
351 using pointer = typename storage_iterator::pointer;
357
361 constexpr basic_iterator() = default;
362 constexpr basic_iterator(basic_iterator const &) = default;
363 constexpr basic_iterator(basic_iterator &&) = default;
364 constexpr basic_iterator & operator=(basic_iterator const &) = default;
365 constexpr basic_iterator & operator=(basic_iterator &&) = default;
366 ~basic_iterator() = default;
367
372 constexpr basic_iterator(parent_t & matrix, storage_iterator iter) : matrix_ptr{&matrix}, host_iter{iter}
373 {}
374
376 constexpr basic_iterator(basic_iterator<!const_range> const & other) noexcept
377 requires const_range
378 : matrix_ptr{other.matrix_ptr}, host_iter{other.host_iter}
379 {}
381
382 // Import advance operator from base class.
383 using base_t::operator+=;
384
386 constexpr basic_iterator & operator+=(matrix_offset const & offset) noexcept
387 {
388 assert(matrix_ptr != nullptr);
389
390 if constexpr (order == matrix_major_order::column)
391 {
392 host_iter += (offset.col * matrix_ptr->rows());
393 host_iter += offset.row;
394 }
395 else
396 {
397 host_iter += offset.col;
398 host_iter += (offset.row * matrix_ptr->cols());
399 }
400 return *this;
401 }
402
404 matrix_coordinate coordinate() const noexcept
405 {
406 assert(matrix_ptr != nullptr);
407
408 auto diff = *this - matrix_ptr->begin();
409 if constexpr (order == matrix_major_order::column)
410 return {row_index_type{diff % matrix_ptr->rows()}, column_index_type{diff / matrix_ptr->rows()}};
411 else
412 return {row_index_type{diff / matrix_ptr->cols()}, column_index_type{diff % matrix_ptr->cols()}};
413 }
414
415private:
416 parent_t * matrix_ptr{nullptr};
417 storage_iterator host_iter{};
418};
419
420} // namespace seqan3::detail
T begin(T... args)
Defines the requirements of a matrix (e.g. score matrices, trace matrices).
Definition matrix_concept.hpp:58
CRTP base class to declare a strong typedef for a regular type to avoid ambiguous parameter settings ...
Definition strong_type.hpp:174
constexpr value_t & get() &noexcept
Returns the underlying value.
Definition strong_type.hpp:201
constexpr strong_type() noexcept=default
Defaulted.
A two-dimensional matrix iterator.
Definition two_dimensional_matrix.hpp:323
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:372
matrix_coordinate coordinate() const noexcept
Returns the current position of the iterator as a two-dimensional matrix coordinate.
Definition two_dimensional_matrix.hpp:404
constexpr basic_iterator & operator+=(matrix_offset const &offset) noexcept
Advances the iterator by the given offset.
Definition two_dimensional_matrix.hpp:386
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:340
typename storage_iterator::pointer pointer
The pointer type.
Definition two_dimensional_matrix.hpp:351
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:376
A crtp-base class for iterators over seqan3::detail::two_dimensional_matrix.
Definition two_dimensional_matrix_iterator_base.hpp:74
A two dimensional matrix used inside of alignment algorithms.
Definition two_dimensional_matrix.hpp:62
size_type row_dim
The number of rows in the matrix.
Definition two_dimensional_matrix.hpp:307
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:105
constexpr iterator begin() noexcept
Returns an iterator pointing to the first element of the matrix.
Definition two_dimensional_matrix.hpp:270
typename storage_type::reference reference
The reference type.
Definition two_dimensional_matrix.hpp:81
typename storage_type::pointer pointer
The pointer type.
Definition two_dimensional_matrix.hpp:83
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:197
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:168
constexpr const_iterator begin() const noexcept
Returns an iterator pointing to the first element of the matrix.
Definition two_dimensional_matrix.hpp:275
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:308
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:234
constexpr const_pointer data() const noexcept
Returns a pointer to the data.
Definition two_dimensional_matrix.hpp:260
typename storage_type::const_reference const_reference
The const reference type.
Definition two_dimensional_matrix.hpp:82
constexpr const_iterator cbegin() const noexcept
Returns an iterator pointing to the first element of the matrix.
Definition two_dimensional_matrix.hpp:281
two_dimensional_matrix(two_dimensional_matrix const &)=default
Defaulted.
constexpr pointer data() noexcept
Returns a pointer to the data.
Definition two_dimensional_matrix.hpp:254
constexpr reference operator[](matrix_coordinate const &coordinate) noexcept
Returns a reference to the element at the given coordinate.
Definition two_dimensional_matrix.hpp:186
storage_type storage
The matrix as a one-dimensional (flattened) vector of entries.
Definition two_dimensional_matrix.hpp:306
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:120
~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:299
size_t cols() const noexcept
The number of columns in the matrix.
Definition two_dimensional_matrix.hpp:248
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:219
typename storage_type::value_type value_type
The value type.
Definition two_dimensional_matrix.hpp:80
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:133
typename storage_type::const_pointer const_pointer
The pointer type.
Definition two_dimensional_matrix.hpp:84
constexpr iterator end() noexcept
Returns an iterator pointing behind-the-end of the matrix.
Definition two_dimensional_matrix.hpp:287
constexpr reference at(matrix_coordinate const &coordinate)
A reference to the entry of the matrix at the given coordinate.
Definition two_dimensional_matrix.hpp:208
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:293
typename storage_type::size_type size_type
The difference type.
Definition two_dimensional_matrix.hpp:86
size_t rows() const noexcept
The number of rows in the matrix.
Definition two_dimensional_matrix.hpp:242
typename storage_type::difference_type difference_type
The difference type.
Definition two_dimensional_matrix.hpp:85
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:36
@ 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:41
@ 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:26
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:412
T resize(T... args)
A strong type for designated initialisation of the column index of a matrix.
Definition matrix_coordinate.hpp:29
A representation of a location or offset within a two-dimensional matrix.
Definition matrix_coordinate.hpp:87
Strong type for setting the column dimension of a matrix.
Definition two_dimensional_matrix.hpp:29
Strong type for setting the row dimension of a matrix.
Definition two_dimensional_matrix.hpp:37
A strong type for designated initialisation of the row index of a matrix.
Definition matrix_coordinate.hpp:58
Provides type traits for working with templates.
Provides seqan3::detail::two_dimensional_matrix_iterator_base.
Hide me