guanaqo main
Utilities for scientific software
Loading...
Searching...
No Matches
sparsity.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file
4/// @ingroup linalg_sparsity
5/// Sparse and dense sparsity descriptors.
6
8
9#include <cassert>
10#include <cstdint>
11#include <span>
12#include <variant>
13
15
16/// @addtogroup linalg_sparsity
17/// @{
18
19/// Describes the symmetry of matrices.
20enum class Symmetry : uint8_t {
21 Unsymmetric = 0, ///< No symmetry.
22 Upper = 1, ///< Symmetric, upper-triangular part is stored.
23 Lower = 2, ///< Symmetric, lower-triangular part is stored.
24};
25
26inline const char *enum_name(Symmetry s) {
27 switch (s) {
28 case Symmetry::Unsymmetric: return "Unsymmetric";
29 case Symmetry::Upper: return "Upper";
30 case Symmetry::Lower: return "Lower";
31 default: return "<invalid>";
32 }
33}
34
35/// Dense matrix structure. Stores all elements in column-major storage.
36/// Symmetric dense matrices always store all elements.
41
42/// Sparse compressed-column structure (CCS or CSC).
43template <class Index, class StorageIndex>
44struct SparseCSC {
45 using index_t = Index;
46 using storage_index_t = StorageIndex;
47 length_t rows = 0, cols = 0;
49 std::span<const index_t> inner_idx{};
50 std::span<const storage_index_t> outer_ptr{};
51 enum Order : uint8_t {
52 /// The row indices are not sorted.
54 /// Within each column, all row indices are sorted in ascending order.
56 };
58
59 /// Get the number of structurally nonzero elements.
60 [[nodiscard]] length_t nnz() const {
61 assert(static_cast<length_t>(outer_ptr.size()) == cols + 1);
62 auto nnz = static_cast<length_t>(inner_idx.size());
63 assert(static_cast<length_t>(outer_ptr.back()) == nnz);
64 return nnz;
65 }
66};
67
68/// Sparse coordinate list structure (COO).
69template <class Index = index_t>
70struct SparseCOO {
71 using index_t = Index;
72 length_t rows = 0, cols = 0;
74 std::span<const index_t> row_indices{};
75 std::span<const index_t> col_indices{};
76 enum Order : uint8_t {
77 /// The indices are not sorted.
79 /// The indices are sorted by column first, and within each column, the
80 /// rows are sorted as well.
82 /// The indices are sorted by column, but the rows within each column
83 /// are not sorted.
85 /// The indices are sorted by row first, and within each row, the
86 /// columns are sorted as well.
88 /// The indices are sorted by row, but the columns within each row are
89 /// not sorted.
91 };
93 index_t first_index = 0; ///< Zero for C/C++, one for Fortran.
94
95 /// Get the number of structurally nonzero elements.
96 [[nodiscard]] length_t nnz() const {
97 assert(row_indices.size() == col_indices.size());
98 return static_cast<length_t>(row_indices.size());
99 }
100};
101
102/// Helper for @ref Sparsity.
103using SparsityVariant = std::variant< //
104 Dense, //
114 >;
115
116/// Stores any of the supported sparsity patterns.
117/// @see @ref SparsityConverter<Sparsity<Conf>, To>
118struct Sparsity {
119 Sparsity(std::convertible_to<SparsityVariant> auto value)
120 : value{std::move(value)} {}
122};
123
124/// @}
125
126namespace detail {
127template <class... Ts>
128struct overloaded : Ts... {
129 using Ts::operator()...;
130};
131template <class... Ts>
132overloaded(Ts...) -> overloaded<Ts...>;
133} // namespace detail
134
135/// @addtogroup linalg_sparsity
136/// @{
137
138/// Returns true if the sparsity pattern represents a dense matrix.
139inline bool is_dense(const Sparsity &sp) {
140 auto visitor = detail::overloaded{
141 [](const Dense &) { return true; },
142 [](const auto &) { return false; },
143 };
144 return std::visit(visitor, sp.value);
145}
146
147/// Get the number of structurally nonzero elements.
148inline length_t get_nnz(const Sparsity &sp) {
149 auto visitor = detail::overloaded{
150 [](const Dense &d) { return d.rows * d.cols; },
151 [](const auto &s) { return s.nnz(); },
152 };
153 return std::visit(visitor, sp.value);
154}
155
156/// Returns the symmetry of the sparsity pattern.
157inline Symmetry get_symmetry(const Sparsity &sp) {
158 return std::visit([](const auto &s) { return s.symmetry; }, sp.value);
159}
160
161/// Returns the number of rows of the sparsity pattern.
162inline length_t num_rows(const Sparsity &sp) {
163 return std::visit([](const auto &s) { return s.rows; }, sp.value);
164}
165
166/// Returns the number of rows of the sparsity pattern.
167inline length_t num_cols(const Sparsity &sp) {
168 return std::visit([](const auto &s) { return s.cols; }, sp.value);
169}
170
171/// @}
172
173} // namespace guanaqo::linalg::sparsity
174
175namespace guanaqo::linalg {
176using sparsity::Sparsity;
177} // namespace guanaqo::linalg
Common linear algebra index types.
bool is_dense(const Sparsity &sp)
Returns true if the sparsity pattern represents a dense matrix.
Definition sparsity.hpp:139
const char * enum_name(Symmetry s)
Definition sparsity.hpp:26
std::variant< Dense, SparseCSC< int, int >, SparseCSC< int, long >, SparseCSC< int, long long >, SparseCSC< long, long >, SparseCSC< long, long long >, SparseCSC< long long, long long >, SparseCOO< int >, SparseCOO< long >, SparseCOO< long long > > SparsityVariant
Helper for Sparsity.
Definition sparsity.hpp:103
length_t num_rows(const Sparsity &sp)
Returns the number of rows of the sparsity pattern.
Definition sparsity.hpp:162
length_t get_nnz(const Sparsity &sp)
Get the number of structurally nonzero elements.
Definition sparsity.hpp:148
length_t num_cols(const Sparsity &sp)
Returns the number of rows of the sparsity pattern.
Definition sparsity.hpp:167
Symmetry
Describes the symmetry of matrices.
Definition sparsity.hpp:20
Symmetry get_symmetry(const Sparsity &sp)
Returns the symmetry of the sparsity pattern.
Definition sparsity.hpp:157
@ Upper
Symmetric, upper-triangular part is stored.
Definition sparsity.hpp:22
@ Lower
Symmetric, lower-triangular part is stored.
Definition sparsity.hpp:23
Dense matrix structure.
Definition sparsity.hpp:37
std::ptrdiff_t length_t
Definition config.hpp:14
overloaded(Ts...) -> overloaded< Ts... >
Sparsity(std::convertible_to< SparsityVariant > auto value)
Definition sparsity.hpp:119
Sparse coordinate list structure (COO).
Definition sparsity.hpp:70
std::span< const index_t > row_indices
Definition sparsity.hpp:74
length_t nnz() const
Get the number of structurally nonzero elements.
Definition sparsity.hpp:96
std::span< const index_t > col_indices
Definition sparsity.hpp:75
Sparse compressed-column structure (CCS or CSC).
Definition sparsity.hpp:44
length_t nnz() const
Get the number of structurally nonzero elements.
Definition sparsity.hpp:60
Stores any of the supported sparsity patterns.
Definition sparsity.hpp:118
Sparsity(std::convertible_to< SparsityVariant > auto value)
Definition sparsity.hpp:119