SeqAn3  3.0.1
The Modern C++ library for sequence analysis.
simd_affine_gap_policy.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2020, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2020, 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 
28 
29 namespace seqan3::detail
30 {
31 
32 // ----------------------------------------------------------------------------
33 // simd_affine_gap_policy
34 // ----------------------------------------------------------------------------
35 
53 template <typename alignment_algorithm_t, simd_concept score_t, typename align_local_t = std::false_type>
54 class simd_affine_gap_policy
55 {
56 private:
58  friend alignment_algorithm_t;
59 
61  using alignment_state_t = alignment_algorithm_state<score_t>;
62 
66  constexpr simd_affine_gap_policy() noexcept = default;
67  constexpr simd_affine_gap_policy(simd_affine_gap_policy const &) noexcept = default;
68  constexpr simd_affine_gap_policy(simd_affine_gap_policy &&) noexcept = default;
69  constexpr simd_affine_gap_policy & operator=(simd_affine_gap_policy const &) noexcept = default;
70  constexpr simd_affine_gap_policy & operator=(simd_affine_gap_policy &&) noexcept = default;
71  ~simd_affine_gap_policy() noexcept = default;
72 
91  template <typename cell_t>
92  constexpr void compute_cell(cell_t && current_cell,
93  alignment_algorithm_state<score_t> & state,
94  score_t const score) const noexcept
95  {
96  // score_cell = seqan3::detail::alignment_score_matrix_proxy
97  // trace_cell = seqan3::detail::alignment_trace_matrix_proxy
98  auto & [score_cell, trace_cell] = current_cell;
99  constexpr bool with_trace = !decays_to_ignore_v<std::remove_reference_t<decltype(trace_cell.current)>>;
100  // Precompute the diagonal score.
101  score_t tmp = score_cell.diagonal + score;
102 
103  if constexpr (with_trace)
104  {
105  auto mask = tmp < score_cell.up;
106  tmp = (mask) ? score_cell.up : tmp;
107  trace_cell.current = (mask) ? trace_cell.up : convert_to_simd(trace_directions::diagonal) | trace_cell.up;
108 
109  mask = tmp < score_cell.r_left;
110  tmp = (mask) ? score_cell.r_left : tmp;
111  trace_cell.current = (mask) ? trace_cell.r_left : trace_cell.current | trace_cell.r_left;
112  }
113  else
114  {
115  tmp = (tmp < score_cell.up) ? score_cell.up : tmp;
116  tmp = (tmp < score_cell.r_left) ? score_cell.r_left : tmp;
117  }
118 
119  if constexpr (align_local_t::value)
120  {
121  tmp = (tmp < simd::fill<score_t>(0))
122  /*then*/ ? (trace_cell.current = convert_to_simd(trace_directions::none), simd::fill<score_t>(0))
123  /*else*/ : tmp;
124  }
125 
126  // Store the current max score.
127  score_cell.current = tmp;
128  // Check if this was the optimum. Possibly a noop.
129  static_cast<alignment_algorithm_t const &>(*this).check_score_of_cell(current_cell, state);
130 
131  // Prepare horizontal and vertical score for next column.
132  tmp += state.gap_open_score;
133  score_cell.up += state.gap_extension_score;
134  score_cell.w_left = score_cell.r_left + state.gap_extension_score;
135 
136  auto mask = score_cell.up < tmp;
137  score_cell.up = (mask) ? tmp : score_cell.up;
138  trace_cell.up = (mask) ? convert_to_simd(trace_directions::up_open) : convert_to_simd(trace_directions::up);
139  mask = score_cell.w_left < tmp;
140  score_cell.w_left = (mask) ? tmp : score_cell.w_left;
141  trace_cell.w_left = (mask) ? convert_to_simd(trace_directions::left_open)
142  : convert_to_simd(trace_directions::left);
143  }
144 
158  template <typename alignment_configuration_t>
159  constexpr void initialise_alignment_state(alignment_configuration_t const & config) noexcept
160  {
161  using scalar_t = typename simd_traits<score_t>::scalar_type;
162  auto scheme = config.template value_or<align_cfg::gap>(gap_scheme{gap_score{-1}, gap_open_score{-10}});
163 
164  alignment_state.gap_extension_score = simd::fill<score_t>(static_cast<scalar_t>(scheme.get_gap_score()));
165  alignment_state.gap_open_score = simd::fill<score_t>(static_cast<scalar_t>(scheme.get_gap_score() +
166  scheme.get_gap_open_score()));
167  }
168 
172  constexpr score_t convert_to_simd(trace_directions const direction) const noexcept
173  {
174  using scalar_t = typename simd_traits<score_t>::scalar_type;
175 
176  return simd::fill<score_t>(static_cast<scalar_t>(direction));
177  }
178 
179  alignment_state_t alignment_state{};
180 };
181 
182 } // namespace seqan3::detail
gap_scheme.hpp
Provides seqan3::gap_scheme.
configuration.hpp
Provides seqan3::detail::configuration and utility functions.
tuple
align_config_gap.hpp
Provides seqan3::align_config::gap.
concept.hpp
Provides seqan3::simd::simd_concept.
trace_directions.hpp
Provides the declaration of seqan3::detail::trace_directions.
simd_algorithm.hpp
Provides algorithms to modify seqan3::simd::simd_type.
simd_traits.hpp
Provides seqan3::simd::simd_traits.
core_language.hpp
Provides concepts for core language types and relations that don't have concepts in C++20 (yet).
alignment_optimum.hpp
Provides seqan3::detail::alignment_optimum.
std::remove_reference_t
std::left
T left(T... args)
limits
alignment_algorithm_state.hpp
Provides seqan3::detail::alignment_algorithm_state.