SeqAn3  3.2.0
The Modern C++ library for sequence analysis.
alignment_score_matrix_one_column_banded.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 <cassert>
16 #include <iterator>
17 #include <ranges>
18 #include <span>
19 
24 
25 namespace seqan3::detail
26 {
27 
41 template <typename score_t>
42 class alignment_score_matrix_one_column_banded :
43  protected alignment_score_matrix_one_column_base<score_t>,
44  public alignment_matrix_column_major_range_base<alignment_score_matrix_one_column_banded<score_t>>
45 {
46 private:
48  using matrix_base_t = alignment_score_matrix_one_column_base<score_t>;
50  using range_base_t = alignment_matrix_column_major_range_base<alignment_score_matrix_one_column_banded<score_t>>;
51 
53  friend range_base_t;
54 
55 protected:
56  using typename matrix_base_t::element_type;
57  using typename range_base_t::alignment_column_type;
59  using column_data_view_type = std::span<element_type>;
60 
61 public:
62  using matrix_base_t::num_cols;
63  using matrix_base_t::num_rows;
64 
69  using value_type = alignment_score_matrix_proxy<score_t>;
71  using reference = value_type;
73  using iterator = typename range_base_t::iterator;
75  using sentinel = typename range_base_t::sentinel;
76  using typename matrix_base_t::size_type;
77  using typename matrix_base_t::underlying_type;
79 
84  constexpr alignment_score_matrix_one_column_banded() = default;
86  constexpr alignment_score_matrix_one_column_banded(alignment_score_matrix_one_column_banded const &) = default;
88  constexpr alignment_score_matrix_one_column_banded(alignment_score_matrix_one_column_banded &&) = default;
90  constexpr alignment_score_matrix_one_column_banded &
91  operator=(alignment_score_matrix_one_column_banded const &) = default;
93  constexpr alignment_score_matrix_one_column_banded &
94  operator=(alignment_score_matrix_one_column_banded &&) = default;
96  ~alignment_score_matrix_one_column_banded() = default;
97 
112  template <std::ranges::forward_range first_sequence_t, std::ranges::forward_range second_sequence_t>
113  constexpr alignment_score_matrix_one_column_banded(first_sequence_t && first,
114  second_sequence_t && second,
115  align_cfg::band_fixed_size const & band,
116  score_t const initial_value = score_t{})
117  {
118  matrix_base_t::num_cols = static_cast<size_type>(std::ranges::distance(first) + 1);
119  matrix_base_t::num_rows = static_cast<size_type>(std::ranges::distance(second) + 1);
120 
121  band_col_index = std::min<int32_t>(std::max<int32_t>(band.upper_diagonal, 0), matrix_base_t::num_cols - 1);
122  band_row_index =
123  std::min<int32_t>(std::abs(std::min<int32_t>(band.lower_diagonal, 0)), matrix_base_t::num_rows - 1);
124 
125  band_size = band_col_index + band_row_index + 1;
126  // Reserve one more cell to deal with last cell in the banded column which needs only the diagonal and up cell.
127  matrix_base_t::pool.resize(band_size + 1, element_type{initial_value, initial_value});
128  }
130 
132  int32_t band_col_index{};
134  int32_t band_row_index{};
136  int32_t band_size{};
137 
138 private:
140  constexpr alignment_column_type initialise_column(size_type const column_index) noexcept
141  {
142  int32_t slice_begin = std::max<int32_t>(0, band_col_index - column_index);
143  int32_t row_end_index = column_index - band_col_index + band_size;
144  int32_t slice_end = band_size - std::max<int32_t>(row_end_index - matrix_base_t::num_rows, 0);
145 
146  assert(row_end_index >= 0);
147  assert(slice_begin >= 0);
148  assert(slice_end > 0);
149  assert(slice_begin < slice_end);
150 
151  return alignment_column_type{*this,
152  column_data_view_type{std::addressof(matrix_base_t::pool[slice_begin]),
153  std::addressof(matrix_base_t::pool[slice_end])}};
154  }
155 
157  template <std::random_access_iterator iter_t>
158  constexpr value_type make_proxy(iter_t host_iter) noexcept
159  {
160  return {std::get<0>(*host_iter), // current
161  std::get<0>(matrix_base_t::cache), // last diagonal
162  std::get<1>(*(host_iter + 1)), // last left (read)
163  std::get<1>(*(host_iter)), // next left (write)
164  std::get<1>(matrix_base_t::cache)}; // last up
165  }
166 
168  template <std::random_access_iterator iter_t>
169  constexpr void on_column_iterator_creation(iter_t host_iter) noexcept
170  {
171  // Cache the last diagonal value.
172  std::get<0>(matrix_base_t::cache) = std::get<0>(*host_iter);
173  }
174 
176  template <std::random_access_iterator iter_t>
177  constexpr void before_column_iterator_increment(iter_t SEQAN3_DOXYGEN_ONLY(host_iter)) noexcept
178  {
179  // noop.
180  }
181 
183  template <std::random_access_iterator iter_t>
184  constexpr void after_column_iterator_increment(iter_t host_iter) noexcept
185  {
186  // Cache the last diagonal value.
187  std::get<0>(matrix_base_t::cache) = std::get<0>(*host_iter);
188  }
189 };
190 
191 } // namespace seqan3::detail
T addressof(T... args)
Provides seqan3::detail::align_config_band.
Provides seqan3::detail::alignment_matrix_column_major_range_base.
Provides seqan3::detail::alignment_score_matrix_one_column_base.
Provides seqan3::detail::alignment_score_matrix_proxy.
The <ranges> header from C++20's standard library.
Provides std::span from the C++20 standard library.