Uni20
Asynchronous tensor and runtime library.
Loading...
Searching...
No Matches
krylov/tridiagonal.hpp
Go to the documentation of this file.
1#pragma once
2
5
6#include <cstddef>
7#include <span>
8#include <utility>
9#include <vector>
10
11namespace uni20::krylov
12{
13
14namespace detail
15{
16inline void check_symmetric_tridiagonal_shape(std::size_t diagonal_size, std::size_t offdiagonal_size)
17{
18 if (diagonal_size == 0)
19 {
20 PRECONDITION(offdiagonal_size == 0, "invalid symmetric tridiagonal shape", diagonal_size, offdiagonal_size);
21 return;
22 }
23
24 PRECONDITION(offdiagonal_size + 1 == diagonal_size, "invalid symmetric tridiagonal shape", diagonal_size,
25 offdiagonal_size);
26}
27} // namespace detail
28
37template <uni20::Real Real> struct symmetric_tridiagonal_view
38{
39 std::span<Real const> const diagonal;
40 std::span<Real const> const offdiagonal;
41
42 symmetric_tridiagonal_view(std::span<Real const> diagonal_in, std::span<Real const> offdiagonal_in)
43 : diagonal(diagonal_in), offdiagonal(offdiagonal_in)
44 {
45 detail::check_symmetric_tridiagonal_shape(diagonal.size(), offdiagonal.size());
46 }
47
48 [[nodiscard]] constexpr std::size_t size() const noexcept { return diagonal.size(); }
49 [[nodiscard]] constexpr bool empty() const noexcept { return diagonal.empty(); }
50
51 [[nodiscard]] Real operator[](std::size_t row, std::size_t column) const
52 {
53 PRECONDITION(row < this->size(), "symmetric tridiagonal row index out of range", row, this->size());
54 PRECONDITION(column < this->size(), "symmetric tridiagonal column index out of range", column, this->size());
55 if (row == column)
56 {
57 return diagonal[row];
58 }
59 if (row + 1 == column)
60 {
61 return offdiagonal[row];
62 }
63 if (column + 1 == row)
64 {
65 return offdiagonal[column];
66 }
67 return Real{};
68 }
69};
70
71template <uni20::Real Real>
72[[nodiscard]] symmetric_tridiagonal_view<Real> symmetric_tridiagonal(std::span<Real const> diagonal,
73 std::span<Real const> offdiagonal)
74{
75 return symmetric_tridiagonal_view<Real>{diagonal, offdiagonal};
76}
77
85template <uni20::Real Real> class symmetric_tridiagonal_matrix {
86 private:
87 std::vector<Real> diagonal_storage_;
88 std::vector<Real> offdiagonal_storage_;
89
90 public:
91 std::span<Real> const diagonal;
92 std::span<Real> const offdiagonal;
93
94 explicit symmetric_tridiagonal_matrix(std::size_t size)
95 : diagonal_storage_(size), offdiagonal_storage_(size == 0 ? 0 : size - 1), diagonal(diagonal_storage_),
96 offdiagonal(offdiagonal_storage_)
97 {}
98
100 : diagonal_storage_(other.diagonal_storage_), offdiagonal_storage_(other.offdiagonal_storage_),
101 diagonal(diagonal_storage_), offdiagonal(offdiagonal_storage_)
102 {}
103
105 : diagonal_storage_(std::move(other.diagonal_storage_)),
106 offdiagonal_storage_(std::move(other.offdiagonal_storage_)), diagonal(diagonal_storage_),
107 offdiagonal(offdiagonal_storage_)
108 {}
109
112
113 [[nodiscard]] std::size_t size() const noexcept { return diagonal.size(); }
114 [[nodiscard]] bool empty() const noexcept { return diagonal.empty(); }
115
116 [[nodiscard]] symmetric_tridiagonal_view<Real> view() const noexcept
117 {
119 }
120
121 [[nodiscard]] Real operator[](std::size_t row, std::size_t column) const { return this->view()[row, column]; }
122};
123
124} // namespace uni20::krylov
Fixed-size owning real symmetric tridiagonal matrix.
Definition krylov/tridiagonal.hpp:85
std::size_t size() const noexcept
Definition krylov/tridiagonal.hpp:113
symmetric_tridiagonal_matrix(symmetric_tridiagonal_matrix &&other) noexcept
Definition krylov/tridiagonal.hpp:104
symmetric_tridiagonal_matrix(symmetric_tridiagonal_matrix const &other)
Definition krylov/tridiagonal.hpp:99
symmetric_tridiagonal_matrix(std::size_t size)
Definition krylov/tridiagonal.hpp:94
std::span< Real > const offdiagonal
Definition krylov/tridiagonal.hpp:92
std::span< Real > const diagonal
Definition krylov/tridiagonal.hpp:91
symmetric_tridiagonal_matrix & operator=(symmetric_tridiagonal_matrix &&)=delete
bool empty() const noexcept
Definition krylov/tridiagonal.hpp:114
Real operator[](std::size_t row, std::size_t column) const
Definition krylov/tridiagonal.hpp:121
symmetric_tridiagonal_view< Real > view() const noexcept
Definition krylov/tridiagonal.hpp:116
symmetric_tridiagonal_matrix & operator=(symmetric_tridiagonal_matrix const &)=delete
Concept for real scalar types (float, double, etc.).
Definition scalar_concepts.hpp:69
Definition block_tensor_vector.hpp:23
symmetric_tridiagonal_view< Real > symmetric_tridiagonal(std::span< Real const > diagonal, std::span< Real const > offdiagonal)
Definition krylov/tridiagonal.hpp:72
Non-owning read-only view of a real symmetric tridiagonal matrix.
Definition krylov/tridiagonal.hpp:38
std::span< Real const > const diagonal
Definition krylov/tridiagonal.hpp:39
std::span< Real const > const offdiagonal
Definition krylov/tridiagonal.hpp:40
Real operator[](std::size_t row, std::size_t column) const
Definition krylov/tridiagonal.hpp:51
constexpr bool empty() const noexcept
Definition krylov/tridiagonal.hpp:49
constexpr std::size_t size() const noexcept
Definition krylov/tridiagonal.hpp:48
symmetric_tridiagonal_view(std::span< Real const > diagonal_in, std::span< Real const > offdiagonal_in)
Definition krylov/tridiagonal.hpp:42
#define PRECONDITION(cond,...)
Definition trace.hpp:341