23 namespace seqan3::detail
31 template <
typename alignment_configuration_t,
typename ...policies_t>
33 requires is_type_specialisation_of_v<alignment_configuration_t, configuration>
35 class pairwise_alignment_algorithm_banded :
36 protected pairwise_alignment_algorithm<alignment_configuration_t, policies_t...>
40 using base_algorithm_t = pairwise_alignment_algorithm<alignment_configuration_t, policies_t...>;
43 using typename base_algorithm_t::traits_type;
44 using typename base_algorithm_t::alignment_result_type;
45 using typename base_algorithm_t::score_type;
47 static_assert(!std::same_as<alignment_result_type, empty_type>,
"Alignment result type was not configured.");
48 static_assert(traits_type::is_banded,
"Alignment configuration must have band configured.");
54 pairwise_alignment_algorithm_banded() =
default;
55 pairwise_alignment_algorithm_banded(pairwise_alignment_algorithm_banded
const &) =
default;
56 pairwise_alignment_algorithm_banded(pairwise_alignment_algorithm_banded &&) =
default;
57 pairwise_alignment_algorithm_banded & operator=(pairwise_alignment_algorithm_banded
const &) =
default;
58 pairwise_alignment_algorithm_banded & operator=(pairwise_alignment_algorithm_banded &&) =
default;
59 ~pairwise_alignment_algorithm_banded() =
default;
70 pairwise_alignment_algorithm_banded(alignment_configuration_t
const & config) : base_algorithm_t(config)
77 template <indexed_sequence_pair_range indexed_sequence_pairs_t,
typename callback_t>
80 requires std::invocable<callback_t, alignment_result_type>
82 void operator()(indexed_sequence_pairs_t && indexed_sequence_pairs, callback_t && callback)
86 for (
auto && [sequence_pair, idx] : indexed_sequence_pairs)
88 size_t const sequence1_size = std::ranges::distance(get<0>(sequence_pair));
89 size_t const sequence2_size = std::ranges::distance(get<1>(sequence_pair));
91 auto && [alignment_matrix, index_matrix] = this->acquire_matrices(sequence1_size,
93 this->lowest_viable_score());
95 compute_matrix(get<0>(sequence_pair), get<1>(sequence_pair), alignment_matrix, index_matrix);
96 this->make_result_and_invoke(
std::forward<decltype(sequence_pair)>(sequence_pair),
99 this->optimal_coordinate,
158 template <std::ranges::forward_range sequence1_t,
159 std::ranges::forward_range sequence2_t,
160 std::ranges::input_range alignment_matrix_t,
161 std::ranges::input_range index_matrix_t>
163 requires std::ranges::forward_range<std::ranges::range_reference_t<alignment_matrix_t>> &&
164 std::ranges::forward_range<std::ranges::range_reference_t<index_matrix_t>>
166 void compute_matrix(sequence1_t && sequence1,
167 sequence2_t && sequence2,
168 alignment_matrix_t && alignment_matrix,
169 index_matrix_t && index_matrix)
175 this->reset_optimum();
177 auto alignment_matrix_it = alignment_matrix.begin();
178 auto indexed_matrix_it = index_matrix.begin();
180 size_t row_size = std::max<int32_t>(0, -this->lower_diagonal);
181 size_t const column_size = std::max<int32_t>(0, this->upper_diagonal);
182 this->initialise_column(*alignment_matrix_it, *indexed_matrix_it, sequence2 |
views::take(row_size));
188 for (
auto sequence1_value : sequence1 |
views::take(column_size))
190 this->compute_column(*++alignment_matrix_it,
191 *++indexed_matrix_it,
200 size_t first_row_index = 0u;
201 for (
auto sequence1_value : sequence1 |
views::drop(column_size))
203 compute_band_column(*++alignment_matrix_it,
204 *++indexed_matrix_it |
views::drop(first_row_index + 1),
214 auto alignment_column = *alignment_matrix_it;
215 auto cell_index_column = *indexed_matrix_it |
views::drop(first_row_index);
217 auto alignment_column_it = alignment_column.begin();
218 auto cell_index_column_it = cell_index_column.begin();
220 this->track_last_column_cell(*alignment_column_it, *cell_index_column_it);
222 for (
size_t last_row = std::min<size_t>(std::ranges::distance(sequence2), row_size);
223 first_row_index < last_row;
225 this->track_last_column_cell(*++alignment_column_it, *++cell_index_column_it);
227 this->track_final_cell(*alignment_column_it, *cell_index_column_it);
249 template <std::ranges::input_range alignment_column_t,
250 std::ranges::input_range cell_index_column_t,
252 std::ranges::input_range sequence2_t>
253 void compute_band_column(alignment_column_t && alignment_column,
254 cell_index_column_t && cell_index_column,
255 sequence1_value_t
const & sequence1_value,
256 sequence2_t && sequence2)
262 auto alignment_column_it = alignment_column.begin();
263 auto cell_index_column_it = cell_index_column.begin();
265 auto cell = *alignment_column_it;
266 cell = this->track_cell(
267 this->initialise_band_first_cell(cell.best_score(),
268 *++alignment_column_it,
269 this->scoring_scheme.score(sequence1_value,
270 *std::ranges::begin(sequence2))),
271 *cell_index_column_it);
277 for (
auto && sequence2_value : sequence2 |
views::drop(1))
279 auto cell = *alignment_column_it;
280 cell = this->track_cell(
281 this->compute_inner_cell(cell.best_score(),
282 *++alignment_column_it,
283 this->scoring_scheme.score(sequence1_value, sequence2_value)),
284 *++cell_index_column_it);
291 this->track_last_row_cell(*alignment_column_it, *cell_index_column_it);