SeqAn3 3.1.0
The Modern C++ library for sequence analysis.
edit_distance_score_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 <bitset>
16
19
20namespace seqan3::detail
21{
22
31template <typename word_t, typename score_t, bool is_semi_global, bool use_max_errors>
32class edit_distance_score_matrix_full
33{
34public:
36 template <std::ranges::viewable_range database_t,
37 std::ranges::viewable_range query_t,
38 typename align_config_t,
39 typename edit_traits>
40 friend class edit_distance_unbanded;
41
45 edit_distance_score_matrix_full() = default;
46 edit_distance_score_matrix_full(edit_distance_score_matrix_full const &) = default;
47 edit_distance_score_matrix_full(edit_distance_score_matrix_full &&) = default;
48 edit_distance_score_matrix_full & operator=(edit_distance_score_matrix_full const &) = default;
49 edit_distance_score_matrix_full & operator=(edit_distance_score_matrix_full &&) = default;
50 ~edit_distance_score_matrix_full() = default;
51
52protected:
54 template <typename derived_t, typename edit_traits>
55 friend class edit_distance_unbanded_score_matrix_policy;
56
60 edit_distance_score_matrix_full(size_t const rows_size)
61 : rows_size{rows_size}, columns{}
62 {}
64
65public:
67 using word_type = word_t;
68
70 static constexpr auto word_size = bits_of<word_type>;
71
73 using score_type = score_t;
74
77
79 using reference = value_type;
80
82 using size_type = size_t;
83
85 static constexpr std::optional<score_type> inf = std::nullopt;
86
95 void reserve(size_t const new_capacity)
96 {
97 columns.reserve(new_capacity);
98 }
99
108 template <typename score_type>
109 static size_t max_rows(word_type const score_mask, unsigned const last_block,
110 score_type const score, score_type const max_errors) noexcept
111 {
112 size_t const offset = std::bit_width(score_mask);
113 size_t const active_row = word_size * last_block + offset;
114 return active_row + (score <= max_errors);
115 }
116
122 static score_type score_delta_of_word(word_type const & vp, word_type const & vn) noexcept
123 {
124 score_type const p = std::bitset<word_size>{vp}.count();
125 score_type const n = std::bitset<word_size>{vn}.count();
126 return p - n;
127 }
128
129public:
131 reference at(matrix_coordinate const & coordinate) const noexcept
132 {
133 size_t col = coordinate.col;
134 size_t row = coordinate.row;
135
136 assert(row < rows());
137 assert(col < cols());
138
139 column_type const & column = columns[col];
140 if constexpr(use_max_errors)
141 if (!(row < column.max_rows))
142 return inf;
143
144 score_type score = is_semi_global ? 0u : static_cast<score_type>(col);
145
146 size_t current_row = 1u;
147 size_t word_idx = 0u;
148
149 for (; current_row + word_size <= row; ++word_idx, current_row += word_size)
150 score += score_delta_of_word(column.vp[word_idx], column.vn[word_idx]);
151
152 if (row >= current_row)
153 {
154 word_type const mask = (1u << (row - current_row + 1u)) - 1u;
155 score += score_delta_of_word(column.vp[word_idx] & mask, column.vn[word_idx] & mask);
156 }
157
158 return -score;
159 }
160
162 size_t rows() const noexcept
163 {
164 return rows_size;
165 }
166
168 size_t cols() const noexcept
169 {
170 return columns.size();
171 }
172
173protected:
175 struct max_errors_state
176 {
179 size_t max_rows;
180 };
181
183 struct score_matrix_state
184 {
189 };
190
192 struct column_type :
193 enable_state_t<true, score_matrix_state>,
194 enable_state_t<use_max_errors, max_errors_state>
195 {};
196
201 void add_column(std::vector<word_type> vp, std::vector<word_type> vn)
203 requires (!use_max_errors)
205 {
206 column_type column{};
207 column.vp = std::move(vp);
208 column.vn = std::move(vn);
209
210 columns.push_back(std::move(column));
211 }
212
218 void add_column(std::vector<word_type> vp, std::vector<word_type> vn, size_t const max_rows)
220 requires use_max_errors
222 {
223 column_type column{};
224 column.vp = std::move(vp);
225 column.vn = std::move(vn);
226 column.max_rows = max_rows;
227
228 columns.push_back(std::move(column));
229 }
230
231private:
233 size_t rows_size{};
235 std::vector<column_type> columns{};
236};
237
238} // namespace seqan3::detail
Provides utility functions for bit twiddling.
T count(T... args)
Forwards for seqan3::edit_distance_unbanded related types.
@ offset
Sequence (seqan3::field::seq) relative start position (0-based), unsigned value.
constexpr T bit_width(T x) noexcept
If x is not zero, calculates the number of bits needed to store the value x, that is,...
Definition: bit:183
typename decltype(detail::at< idx >(list_t{}))::type at
Return the type at given index from the type list.
Definition: traits.hpp:260