SeqAn3 3.1.0
The Modern C++ library for sequence analysis.
alignment_trace_matrix_full.hpp
Go to the documentation of this file.
1// -----------------------------------------------------------------------------------------------------
2// Copyright (c) 2006-2021, Knut Reinert & Freie Universität Berlin
3// Copyright (c) 2016-2021, 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/iterator>
16#include <seqan3/std/ranges>
17
23
24namespace seqan3::detail
25{
26
49template <typename trace_t, bool coordinate_only = false>
50class alignment_trace_matrix_full :
51 protected alignment_trace_matrix_base<trace_t>,
52 public alignment_matrix_column_major_range_base<alignment_trace_matrix_full<trace_t, coordinate_only>>
53{
54private:
55 static_assert(std::same_as<trace_t, trace_directions> || simd_concept<trace_t>,
56 "Value type must either be a trace_directions object or a simd vector.");
57
59 using matrix_base_t = alignment_trace_matrix_base<trace_t>;
61 using range_base_t = alignment_matrix_column_major_range_base<alignment_trace_matrix_full<trace_t, coordinate_only>>;
62
64 friend range_base_t;
65
66protected:
67 using typename matrix_base_t::element_type;
68 using typename matrix_base_t::coordinate_type;
69 using typename range_base_t::alignment_column_type;
71 using column_data_view_type = std::conditional_t<coordinate_only,
72 decltype(std::views::iota(coordinate_type{}, coordinate_type{})),
75 std::views::iota(coordinate_type{}, coordinate_type{})))>;
76
77public:
82 using value_type = alignment_trace_matrix_proxy<coordinate_type,
83 std::conditional_t<coordinate_only,
84 detail::ignore_t const,
85 trace_t>>;
87 using reference = value_type;
89 using iterator = typename range_base_t::iterator;
91 using sentinel = typename range_base_t::sentinel;
92 using typename matrix_base_t::size_type;
94
98 constexpr alignment_trace_matrix_full() = default;
99 constexpr alignment_trace_matrix_full(alignment_trace_matrix_full const &) = default;
100 constexpr alignment_trace_matrix_full(alignment_trace_matrix_full &&) = default;
101 constexpr alignment_trace_matrix_full & operator=(alignment_trace_matrix_full const &) = default;
102 constexpr alignment_trace_matrix_full & operator=(alignment_trace_matrix_full &&) = default;
103 ~alignment_trace_matrix_full() = default;
104
118 template <std::ranges::forward_range first_sequence_t, std::ranges::forward_range second_sequence_t>
119 constexpr alignment_trace_matrix_full(first_sequence_t && first,
120 second_sequence_t && second,
121 [[maybe_unused]] trace_t const initial_value = trace_t{})
122 {
123 matrix_base_t::num_cols = static_cast<size_type>(std::ranges::distance(first) + 1);
124 matrix_base_t::num_rows = static_cast<size_type>(std::ranges::distance(second) + 1);
125
126 if constexpr (!coordinate_only)
127 {
128 // Allocate the matrix here.
129 matrix_base_t::data = typename matrix_base_t::pool_type{number_rows{matrix_base_t::num_rows},
130 number_cols{matrix_base_t::num_cols}};
131 matrix_base_t::cache_left.resize(matrix_base_t::num_rows, initial_value);
132 }
133 }
135
142 auto trace_path(matrix_coordinate const & trace_begin)
143 {
144 static_assert(!coordinate_only, "Requested trace but storing the trace was disabled!");
145
146 using matrix_iter_t = std::ranges::iterator_t<typename matrix_base_t::pool_type>;
147 using trace_iterator_t = trace_iterator<matrix_iter_t>;
148 using path_t = std::ranges::subrange<trace_iterator_t, std::default_sentinel_t>;
149
150 if (trace_begin.row >= matrix_base_t::num_rows || trace_begin.col >= matrix_base_t::num_cols)
151 throw std::invalid_argument{"The given coordinate exceeds the matrix in vertical or horizontal direction."};
152
153 return path_t{trace_iterator_t{matrix_base_t::data.begin() + matrix_offset{trace_begin}},
154 std::default_sentinel};
155 }
156
157private:
159 constexpr alignment_column_type initialise_column(size_type const column_index) noexcept
160 {
161 coordinate_type row_begin{column_index_type{column_index}, row_index_type{0u}};
162 coordinate_type row_end{column_index_type{column_index}, row_index_type{matrix_base_t::num_rows}};
163 if constexpr (coordinate_only)
164 {
165 return alignment_column_type{*this,
166 column_data_view_type{std::views::iota(std::move(row_begin),
167 std::move(row_end))}};
168 }
169 else
170 {
171 matrix_coordinate current_position{row_index_type{0u}, column_index_type{column_index}};
172 auto col = views::zip(std::span<element_type>{std::addressof(matrix_base_t::data[current_position]),
173 matrix_base_t::num_rows},
174 std::span<element_type>{matrix_base_t::cache_left},
175 std::views::iota(std::move(row_begin), std::move(row_end)));
176 return alignment_column_type{*this, column_data_view_type{col}};
177 }
178 }
179
181 template <std::random_access_iterator iter_t>
182 constexpr value_type make_proxy(iter_t host_iter) noexcept
183 {
184 if constexpr (coordinate_only)
185 {
186 return {*host_iter, std::ignore, std::ignore, std::ignore, std::ignore};
187 }
188 else
189 {
190 return {std::get<2>(*host_iter), // the coordinate.
191 std::get<0>(*host_iter), // the current entry.
192 std::get<1>(*host_iter), // the last left cell to read from.
193 std::get<1>(*host_iter), // the next left cell to write to.
194 matrix_base_t::cache_up, // the last up cell to read/write from/to.
195 };
196 }
197 }
198};
199
200} // namespace seqan3::detail
T addressof(T... args)
Provides seqan3::detail::alignment_matrix_column_major_range_base.
Provides seqan3::detail::alignment_trace_matrix_base.
Provides seqan3::detail::alignment_trace_matrix_proxy.
T declval(T... args)
constexpr auto zip
A zip view.
Definition: zip.hpp:29
The <iterator> header from C++20's standard library.
The <ranges> header from C++20's standard library.
Provides seqan3::detail::trace_iterator.
Provides seqan3::views::zip.