SeqAn3  3.0.1
The Modern C++ library for sequence analysis.
simd_matrix_scoring_scheme.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
6 // -----------------------------------------------------------------------------------------------------
7 
13 #pragma once
14 
21 #include <seqan3/std/concepts>
22 
23 namespace seqan3::detail
24 {
25 
43 template <simd_concept simd_score_t, semialphabet alphabet_t, typename alignment_t, typename scoring_scheme_t>
49 class simd_matrix_scoring_scheme
50 {
51 public:
55  constexpr simd_matrix_scoring_scheme() = default;
56  constexpr simd_matrix_scoring_scheme(simd_matrix_scoring_scheme const &) = default;
57  constexpr simd_matrix_scoring_scheme(simd_matrix_scoring_scheme &&) = default;
58  constexpr simd_matrix_scoring_scheme & operator=(simd_matrix_scoring_scheme const &) = default;
59  constexpr simd_matrix_scoring_scheme & operator=(simd_matrix_scoring_scheme &&) = default;
60  ~simd_matrix_scoring_scheme() = default;
61 
63  constexpr explicit simd_matrix_scoring_scheme(scoring_scheme_t const & scoring_scheme)
64  {
65  initialise_from_scalar_scoring_scheme(scoring_scheme);
66  }
67 
69  constexpr simd_matrix_scoring_scheme & operator=(scoring_scheme_t const & scoring_scheme)
70  {
71  initialise_from_scalar_scoring_scheme(scoring_scheme);
72  return *this;
73  }
75 
96  constexpr simd_score_t score(simd_score_t const & lhs, simd_score_t const & rhs) const noexcept
97  {
98  simd_score_t result{};
99 
100  for (size_t i = 0; i < simd_traits<simd_score_t>::length; ++i)
101  {
102  if (is_padded(lhs[i]) || is_padded(rhs[i]))
103  {
105  result[i] = 1;
106  else
107  result[i] = -1;
108  }
109  else
110  {
111  result[i] = internal_scoring_scheme.score(assign_rank_to(lhs[i], alphabet_t{}),
112  assign_rank_to(rhs[i], alphabet_t{}));
113  }
114  }
115 
116  return result;
117  }
119 
121  constexpr typename scoring_scheme_t::score_type padding_match_score() noexcept
122  {
123  return 1;
124  }
125 
126 private:
128  scoring_scheme_t internal_scoring_scheme;
129 
133  constexpr void initialise_from_scalar_scoring_scheme(scoring_scheme_t const & scoring_scheme)
134  {
135  using score_t = decltype(std::declval<scoring_scheme_t const &>().score(alphabet_t{}, alphabet_t{}));
136  using simd_scalar_t = typename simd_traits<simd_score_t>::scalar_type;
137 
138  // Check if the scoring scheme match and mismatch scores do not overflow with the respective scalar type.
139  if constexpr (sizeof(simd_scalar_t) < sizeof(score_t))
140  {
141  if (min_or_max_exceeded<score_t, simd_scalar_t>(scoring_scheme))
142  throw std::invalid_argument{"The selected scoring scheme score overflows "
143  "for the selected scalar type of the simd type."};
144  }
145 
146  internal_scoring_scheme = scoring_scheme;
147  }
148 
156  template <typename score_t, typename simd_scalar_t>
157  constexpr bool min_or_max_exceeded(scoring_scheme_t const & scoring_scheme)
158  {
159  score_t max_val = static_cast<score_t>(std::numeric_limits<simd_scalar_t>::max());
160  score_t min_val = static_cast<score_t>(std::numeric_limits<simd_scalar_t>::lowest());
161 
162  for (uint8_t i = 0; i < alphabet_size<alphabet_t>; ++i)
163  {
164  for (uint8_t j = 0; j < alphabet_size<alphabet_t>; ++j)
165  {
166  score_t tmp_score = scoring_scheme.score(assign_rank_to(i, alphabet_t{}),
167  assign_rank_to(j, alphabet_t{}));
168 
169  if (tmp_score > max_val || tmp_score < min_val)
170  return true;
171  }
172  }
173 
174  return false;
175  }
176 
184  constexpr bool is_padded(typename simd_traits<simd_score_t>::scalar_type const & value) const
185  {
186  using unsigned_scalar_t = typename std::make_unsigned<typename simd_traits<simd_score_t>::scalar_type>::type;
187 
188  return static_cast<unsigned_scalar_t>(value) >= alphabet_size<alphabet_t>;
189  }
190 };
191 
192 } // namespace seqan3::detail
seqan3::assign_rank_to
constexpr auto assign_rank_to
Assign a rank to an alphabet object.
Definition: concept.hpp:238
scoring_scheme
A concept that requires that type be able to score two letters.
concept.hpp
Provides seqan3::simd::simd_concept.
concepts
The Concepts library.
same_as
The concept std::same_as<T, U> is satisfied if and only if T and U denote the same type.
simd_algorithm.hpp
Provides algorithms to modify seqan3::simd::simd_type.
scoring_scheme_concept.hpp
Provides seqan3::scoring_scheme.
std::invalid_argument
cereal.hpp
Adaptions of concepts from the Cereal library.
align_config_mode.hpp
Provides global alignment configurations.
std::numeric_limits
scoring_scheme::score
score_type score(alph1_t const alph1, alph2_t const alph2)
Compute the score of two letters.
concept.hpp
Core alphabet concept and free function/type trait wrappers.
std::make_unsigned