SeqAn3 3.2.0
The Modern C++ library for sequence analysis.
simd_affine_gap_policy.hpp
Go to the documentation of this file.
1// -----------------------------------------------------------------------------------------------------
2// Copyright (c) 2006-2022, Knut Reinert & Freie Universität Berlin
3// Copyright (c) 2016-2022, 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 <limits>
16#include <tuple>
17
27
28namespace seqan3::detail
29{
30
31// ----------------------------------------------------------------------------
32// simd_affine_gap_policy
33// ----------------------------------------------------------------------------
34
52template <typename alignment_algorithm_t, simd_concept score_t, typename align_local_t = std::false_type>
53class simd_affine_gap_policy
54{
55private:
57 friend alignment_algorithm_t;
58
60 using alignment_state_t = alignment_algorithm_state<score_t>;
61
65 constexpr simd_affine_gap_policy() noexcept = default;
66 constexpr simd_affine_gap_policy(simd_affine_gap_policy const &) noexcept = default;
67 constexpr simd_affine_gap_policy(simd_affine_gap_policy &&) noexcept = default;
68 constexpr simd_affine_gap_policy & operator=(simd_affine_gap_policy const &) noexcept = default;
69 constexpr simd_affine_gap_policy & operator=(simd_affine_gap_policy &&) noexcept = default;
70 ~simd_affine_gap_policy() noexcept = default;
71
73 template <typename configuration_t>
74 simd_affine_gap_policy(configuration_t const & /*config*/)
75 {}
77
95 template <typename cell_t>
96 constexpr void
97 compute_cell(cell_t && current_cell, alignment_algorithm_state<score_t> & state, score_t const score) const noexcept
98 {
99 // score_cell = seqan3::detail::alignment_score_matrix_proxy
100 // trace_cell = seqan3::detail::alignment_trace_matrix_proxy
101 auto & [score_cell, trace_cell] = current_cell;
102 constexpr bool with_trace = !decays_to_ignore_v<std::remove_reference_t<decltype(trace_cell.current)>>;
103 // Precompute the diagonal score.
104 score_t tmp = score_cell.diagonal + score;
105
106 if constexpr (with_trace)
107 {
108 auto mask = tmp < score_cell.up;
109 tmp = (mask) ? score_cell.up : tmp;
110 trace_cell.current = (mask) ? trace_cell.up : convert_to_simd(trace_directions::diagonal) | trace_cell.up;
111
112 mask = tmp < score_cell.r_left;
113 tmp = (mask) ? score_cell.r_left : tmp;
114 trace_cell.current = (mask) ? trace_cell.r_left : trace_cell.current | trace_cell.r_left;
115 }
116 else
117 {
118 tmp = (tmp < score_cell.up) ? score_cell.up : tmp;
119 tmp = (tmp < score_cell.r_left) ? score_cell.r_left : tmp;
120 }
121
122 if constexpr (align_local_t::value)
123 {
124 tmp = (tmp < simd::fill<score_t>(0))
125 /*then*/
126 ? (trace_cell.current = convert_to_simd(trace_directions::none), simd::fill<score_t>(0))
127 /*else*/
128 : tmp;
129 }
130
131 // Store the current max score.
132 score_cell.current = tmp;
133 // Check if this was the optimum. Possibly a noop.
134 static_cast<alignment_algorithm_t const &>(*this).check_score_of_cell(current_cell, state);
135
136 // Prepare horizontal and vertical score for next column.
137 tmp += state.gap_open_score;
138 score_cell.up += state.gap_extension_score;
139 score_cell.w_left = score_cell.r_left + state.gap_extension_score;
140
141 auto mask = score_cell.up < tmp;
142 score_cell.up = (mask) ? tmp : score_cell.up;
143 trace_cell.up = (mask) ? convert_to_simd(trace_directions::up_open) : convert_to_simd(trace_directions::up);
144 mask = score_cell.w_left < tmp;
145 score_cell.w_left = (mask) ? tmp : score_cell.w_left;
146 trace_cell.w_left =
147 (mask) ? convert_to_simd(trace_directions::left_open) : convert_to_simd(trace_directions::left);
148 }
149
162 template <typename alignment_configuration_t>
163 constexpr void initialise_alignment_state(alignment_configuration_t const & config) noexcept
164 {
165 using scalar_t = typename simd_traits<score_t>::scalar_type;
166 auto scheme =
167 config.get_or(align_cfg::gap_cost_affine{align_cfg::open_score{-10}, align_cfg::extension_score{-1}});
168
169 alignment_state.gap_extension_score = simd::fill<score_t>(static_cast<scalar_t>(scheme.extension_score));
170 alignment_state.gap_open_score =
171 simd::fill<score_t>(static_cast<scalar_t>(scheme.extension_score + scheme.open_score));
172 }
173
177 constexpr score_t convert_to_simd(trace_directions const direction) const noexcept
178 {
179 using scalar_t = typename simd_traits<score_t>::scalar_type;
180
181 return simd::fill<score_t>(static_cast<scalar_t>(direction));
182 }
183
184 alignment_state_t alignment_state{};
185};
186
187} // namespace seqan3::detail
Provides algorithms to modify seqan3::simd::simd_type.
Provides seqan3::align_config::gap_cost_affine.
Provides seqan3::detail::alignment_algorithm_state.
Provides seqan3::detail::alignment_optimum.
Provides seqan3::configuration and utility functions.
T left(T... args)
Provides seqan3::simd::simd_traits.
Provides the declaration of seqan3::detail::trace_directions.
Provides concepts that do not have equivalents in C++20.
Provides seqan3::simd::simd_concept.