SeqAn3  3.0.2
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-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 
19 #include <seqan3/std/iterator>
20 #include <seqan3/std/ranges>
21 #include <seqan3/std/span>
22 
23 namespace seqan3::detail
24 {
25 
39 template <typename score_t>
40 class alignment_score_matrix_one_column_banded :
41  protected alignment_score_matrix_one_column_base<score_t>,
42  public alignment_matrix_column_major_range_base<alignment_score_matrix_one_column_banded<score_t>>
43 {
44 private:
46  using matrix_base_t = alignment_score_matrix_one_column_base<score_t>;
48  using range_base_t = alignment_matrix_column_major_range_base<alignment_score_matrix_one_column_banded<score_t>>;
49 
51  friend range_base_t;
52 
53 protected:
54  using typename matrix_base_t::element_type;
55  using typename range_base_t::alignment_column_type;
57  using column_data_view_type = std::span<element_type>;
58 
59 public:
60  using matrix_base_t::num_cols;
61  using matrix_base_t::num_rows;
62 
66  using value_type = alignment_score_matrix_proxy<score_t>;
69  using reference = value_type;
71  using iterator = typename range_base_t::iterator;
73  using sentinel = typename range_base_t::sentinel;
74  using typename matrix_base_t::size_type;
75  using typename matrix_base_t::underlying_type;
77 
81  constexpr alignment_score_matrix_one_column_banded() = default;
84  constexpr alignment_score_matrix_one_column_banded(alignment_score_matrix_one_column_banded const &) = default;
86  constexpr alignment_score_matrix_one_column_banded(alignment_score_matrix_one_column_banded &&) = default;
88  constexpr alignment_score_matrix_one_column_banded &
89  operator=(alignment_score_matrix_one_column_banded const &) = default;
91  constexpr alignment_score_matrix_one_column_banded &
92  operator=(alignment_score_matrix_one_column_banded &&) = default;
94  ~alignment_score_matrix_one_column_banded() = default;
95 
110  template <std::ranges::forward_range first_sequence_t,
111  std::ranges::forward_range second_sequence_t>
112  constexpr alignment_score_matrix_one_column_banded(first_sequence_t && first,
113  second_sequence_t && second,
114  align_cfg::band_fixed_size const & band,
115  score_t const initial_value = score_t{})
116  {
117  matrix_base_t::num_cols = static_cast<size_type>(std::ranges::distance(first) + 1);
118  matrix_base_t::num_rows = static_cast<size_type>(std::ranges::distance(second) + 1);
119 
120  band_col_index = std::min<int32_t>(std::max<int32_t>(band.upper_diagonal, 0), matrix_base_t::num_cols - 1);
121  band_row_index = std::min<int32_t>(std::abs(std::min<int32_t>(band.lower_diagonal, 0)),
122  matrix_base_t::num_rows - 1);
123 
124  band_size = band_col_index + band_row_index + 1;
125  // Reserve one more cell to deal with last cell in the banded column which needs only the diagonal and up cell.
126  matrix_base_t::pool.resize(band_size + 1, element_type{initial_value, initial_value});
127  }
129 
131  int32_t band_col_index{};
133  int32_t band_row_index{};
135  int32_t band_size{};
136 
137 private:
139  constexpr alignment_column_type initialise_column(size_type const column_index) noexcept
140  {
141  int32_t slice_begin = std::max<int32_t>(0, band_col_index - column_index);
142  int32_t row_end_index = column_index - band_col_index + band_size;
143  int32_t slice_end = band_size - std::max<int32_t>(row_end_index - matrix_base_t::num_rows, 0);
144 
145  assert(row_end_index >= 0);
146  assert(slice_begin >= 0);
147  assert(slice_end > 0);
148  assert(slice_begin < slice_end);
149 
150  return alignment_column_type{*this,
151  column_data_view_type{std::addressof(matrix_base_t::pool[slice_begin]),
152  std::addressof(matrix_base_t::pool[slice_end])}};
153  }
154 
156  template <std::random_access_iterator iter_t>
157  constexpr value_type make_proxy(iter_t host_iter) noexcept
158  {
159  return {std::get<0>(*host_iter), // current
160  std::get<0>(matrix_base_t::cache), // last diagonal
161  std::get<1>(*(host_iter + 1)), // last left (read)
162  std::get<1>(*(host_iter)), // next left (write)
163  std::get<1>(matrix_base_t::cache)}; // last up
164  }
165 
167  template <std::random_access_iterator iter_t>
168  constexpr void on_column_iterator_creation(iter_t host_iter) noexcept
169  {
170  // Cache the last diagonal value.
171  std::get<0>(matrix_base_t::cache) = std::get<0>(*host_iter);
172  }
173 
175  template <std::random_access_iterator iter_t>
176  constexpr void before_column_iterator_increment(iter_t SEQAN3_DOXYGEN_ONLY(host_iter)) noexcept
177  {
178  // noop.
179  }
180 
182  template <std::random_access_iterator iter_t>
183  constexpr void after_column_iterator_increment(iter_t host_iter) noexcept
184  {
185  // Cache the last diagonal value.
186  std::get<0>(matrix_base_t::cache) = std::get<0>(*host_iter);
187  }
188 };
189 
190 } // namespace seqan3::detail
span
Provides std::span from the C++20 standard library.
iterator
Provides C++20 additions to the <iterator> header.
alignment_score_matrix_proxy.hpp
Provides seqan3::detail::alignment_score_matrix_proxy.
std::addressof
T addressof(T... args)
align_config_band.hpp
Provides seqan3::detail::align_config_band.
ranges
Adaptations of concepts from the Ranges TS.
alignment_score_matrix_one_column_base.hpp
Provides seqan3::detail::alignment_score_matrix_one_column_base.
alignment_matrix_column_major_range_base.hpp
Provides seqan3::detail::alignment_matrix_column_major_range_base.