24namespace seqan3::detail
38template <simd::simd_concept simd_t>
39struct simd_global_alignment_state
42 simd_t score_offset{};
44 simd_t coordinate_offset{};
46 simd_t last_column_mask{};
48 simd_t last_row_mask{};
77template <
typename alignment_algorithm_t, simd::simd_concept simd_t>
78class simd_find_optimum_policy :
public simd_global_alignment_state<simd_t>
82 friend alignment_algorithm_t;
85 bool is_global_alignment{
false};
87 bool test_every_cell{
false};
89 bool test_last_row_cell{
false};
91 bool test_last_column_cell{
false};
96 constexpr simd_find_optimum_policy() =
default;
97 constexpr simd_find_optimum_policy(simd_find_optimum_policy
const &) =
default;
98 constexpr simd_find_optimum_policy(simd_find_optimum_policy &&) =
default;
99 constexpr simd_find_optimum_policy & operator=(simd_find_optimum_policy
const &) =
default;
100 constexpr simd_find_optimum_policy & operator=(simd_find_optimum_policy &&) =
default;
101 ~simd_find_optimum_policy() =
default;
104 template <
typename configuration_t>
105 simd_find_optimum_policy(configuration_t
const & config)
107 if constexpr (configuration_t::template exists<align_cfg::method_local>())
108 test_every_cell =
true;
110 is_global_alignment = configuration_t::template exists<align_cfg::method_global>();
112 auto method_global_config = config.get_or(align_cfg::method_global{});
114 test_last_row_cell = method_global_config.free_end_gaps_sequence1_trailing || is_global_alignment;
115 test_last_column_cell = method_global_config.free_end_gaps_sequence2_trailing || is_global_alignment;
121 template <
typename cell_t,
typename score_t>
122 constexpr void check_score_of_cell([[maybe_unused]] cell_t
const & current_cell,
123 [[maybe_unused]] alignment_algorithm_state<score_t> & state)
const noexcept
126 check_and_update(current_cell, state);
130 template <
typename other_alignment_algorithm_t, simd_concept score_t,
typename is_local_t>
131 friend class simd_affine_gap_policy;
134 template <
typename other_alignment_algorithm_t>
135 friend class affine_gap_init_policy;
138 template <
typename cell_t,
typename score_t>
140 check_score_of_last_row_cell([[maybe_unused]] cell_t
const & last_row_cell,
141 [[maybe_unused]] alignment_algorithm_state<score_t> & state)
const noexcept
144 if (!test_every_cell && test_last_row_cell)
146 if (is_global_alignment)
147 check_and_update<true>(last_row_cell, state);
149 check_and_update(last_row_cell, state);
154 template <
typename alignment_column_t,
typename score_t>
156 check_score_of_cells_in_last_column([[maybe_unused]] alignment_column_t && last_column,
157 [[maybe_unused]] alignment_algorithm_state<score_t> & state)
const noexcept
160 if (!test_every_cell && test_last_column_cell)
162 for (
auto && cell : last_column)
164 if (is_global_alignment)
165 check_and_update<false>(cell, state);
167 check_and_update(cell, state);
173 template <
typename cell_t,
typename score_t>
174 constexpr void check_score_of_last_cell([[maybe_unused]] cell_t
const & last_cell,
175 [[maybe_unused]] alignment_algorithm_state<score_t> & state)
const noexcept
178 if (!(test_every_cell || test_last_row_cell || test_last_column_cell))
179 check_and_update(last_cell, state);
194 template <std::ranges::forward_range sequence1_collection_t,
195 std::ranges::forward_range sequence2_collection_t,
197 void initialise_find_optimum_policy([[maybe_unused]] sequence1_collection_t && sequence1_collection,
198 [[maybe_unused]] sequence2_collection_t && sequence2_collection,
199 [[maybe_unused]] score_t
const padding_score)
201 if (is_global_alignment)
203 assert(std::ranges::distance(sequence1_collection) == std::ranges::distance(sequence2_collection));
205 constexpr size_t simd_size = simd_traits<simd_t>::length;
213 size_t array_index{};
214 for (
auto && [sequence1, sequence2] :
views::zip(sequence1_collection, sequence2_collection))
216 sequence1_sizes[array_index] = std::ranges::distance(sequence1);
217 sequence2_sizes[array_index] = std::ranges::distance(sequence2);
218 max_sequence1_size = std::max<std::ptrdiff_t>(sequence1_sizes[array_index], max_sequence1_size);
219 max_sequence2_size = std::max<std::ptrdiff_t>(sequence2_sizes[array_index], max_sequence2_size);
224 std::ptrdiff_t global_diagonal = max_sequence1_size - max_sequence2_size;
226 for (
size_t simd_index = 0; simd_index < simd_size; ++simd_index)
228 if (
std::ptrdiff_t local_diagonal = sequence1_sizes[simd_index] - sequence2_sizes[simd_index];
229 local_diagonal < global_diagonal)
231 this->last_row_mask[simd_index] = max_sequence1_size - (global_diagonal - local_diagonal);
232 this->last_column_mask[simd_index] = max_sequence2_size + 1;
233 this->coordinate_offset[simd_index] = max_sequence2_size - sequence2_sizes[simd_index];
234 this->score_offset[simd_index] = padding_score * this->coordinate_offset[simd_index];
238 this->last_column_mask[simd_index] = max_sequence2_size - (local_diagonal - global_diagonal);
239 this->last_row_mask[simd_index] = max_sequence1_size + 1;
240 this->coordinate_offset[simd_index] = max_sequence1_size - sequence1_sizes[simd_index];
241 this->score_offset[simd_index] = padding_score * this->coordinate_offset[simd_index];
257 template <
typename cell_t,
typename score_t>
258 constexpr void check_and_update(cell_t
const & cell, alignment_algorithm_state<score_t> & state)
const noexcept
260 assert(!is_global_alignment);
262 auto const & [score_cell, trace_cell] = cell;
263 state.optimum.update_if_new_optimal_score(score_cell.current,
264 column_index_type{trace_cell.coordinate.first},
265 row_index_type{trace_cell.coordinate.second});
284 template <
bool in_last_row,
typename cell_t,
typename score_t>
285 constexpr void check_and_update(cell_t
const & cell, alignment_algorithm_state<score_t> & state)
const noexcept
287 assert(is_global_alignment);
289 using simd_mask_t =
typename simd_traits<simd_t>::mask_type;
290 auto const & [score_cell, trace_cell] = cell;
291 simd_t column_positions = simd::fill<simd_t>(trace_cell.coordinate.first);
292 simd_t row_positions = simd::fill<simd_t>(trace_cell.coordinate.second);
296 if constexpr (in_last_row)
297 mask = (column_positions == this->last_row_mask);
299 mask = (row_positions == this->last_column_mask);
303 state.optimum.score = mask ? score_cell.current - this->score_offset : state.optimum.score;
304 state.optimum.column_index = mask ? column_positions - this->coordinate_offset : state.optimum.column_index;
305 state.optimum.row_index = mask ? row_positions - this->coordinate_offset : state.optimum.row_index;
Provides seqan3::detail::alignment_algorithm_state.
Provides seqan3::detail::alignment_optimum.
Provides seqan3::detail::empty_type.
Provides seqan3::detail::find_optimum_policy.
seqan::std::views::zip zip
A view adaptor that takes several views and returns tuple-like values from every i-th element of each...
Definition: zip.hpp:27
A type that satisfies std::is_arithmetic_v<t>.
Provides seqan3::simd::simd_concept.
Provides seqan3::views::zip.