numerics 0.1.0
Loading...
Searching...
No Matches
subspace.cpp
Go to the documentation of this file.
1/// @file kernel/subspace.cpp
2/// @brief Implementations for num::kernel::subspace.
3
4#include "kernel/subspace.hpp"
5#include "core/matrix.hpp"
6#include "core/vector.hpp"
8#ifdef NUMERICS_HAS_BLAS
9#include <cblas.h>
10#endif
11
12namespace num::kernel::subspace {
13
14// ---------------------------------------------------------------------------
15// LinearOp concrete implementations
16// ---------------------------------------------------------------------------
17
18void DenseOp::apply(const Vector& x, Vector& y) const {
19 if (y.size() != A_.rows()) { y = Vector(A_.rows()); }
20 matvec(A_, x, y, b_);
21}
22
23void SparseOp::apply(const Vector& x, Vector& y) const {
24 if (y.size() != A_.n_rows()) { y = Vector(A_.n_rows()); }
25 sparse_matvec(A_, x, y);
26}
27
28// ---------------------------------------------------------------------------
29// mgs_orthogonalize (vector-basis overload)
30// ---------------------------------------------------------------------------
31
32real mgs_orthogonalize(const std::vector<Vector>& basis,
33 Vector& v,
34 std::vector<real>& h,
35 idx k) {
36 for (idx i = 0; i < k; ++i) {
37 h[i] = dot(v, basis[i]);
38 axpy(-h[i], basis[i], v);
39 }
40 return norm(v);
41}
42
43// ---------------------------------------------------------------------------
44// mgs_orthogonalize (matrix-basis overload, strided BLAS when available)
45// ---------------------------------------------------------------------------
46
47real mgs_orthogonalize(const Matrix& basis, idx k, Vector& v) {
48 const idx n = basis.rows();
49 const idx stride = basis.cols(); // row-major: stride between column elements
50
51 for (idx l = 0; l < k; ++l) {
52#ifdef NUMERICS_HAS_BLAS
53 const real proj = cblas_ddot(static_cast<int>(n),
54 basis.data() + l,
55 static_cast<int>(stride),
56 v.data(), 1);
57 cblas_daxpy(static_cast<int>(n), -proj,
58 basis.data() + l, static_cast<int>(stride),
59 v.data(), 1);
60#else
61 real proj = 0.0;
62 for (idx i = 0; i < n; ++i) { proj += basis(i, l) * v[i]; }
63 for (idx i = 0; i < n; ++i) { v[i] -= proj * basis(i, l); }
64#endif
65 }
66 return norm(v);
67}
68
69// ---------------------------------------------------------------------------
70// arnoldi_step
71// ---------------------------------------------------------------------------
72
74 std::vector<Vector>& basis,
75 std::vector<real>& h,
76 idx k,
77 Vector& scratch,
78 real breakdown_tol) {
79 // Step 1: w = A * basis[k] (written into the pre-allocated scratch buffer)
80 A.apply(basis[k], scratch);
81
82 // Step 2 & 3: MGS against basis[0..k], fills h[0..k]; returns ||w||
83 const real beta = mgs_orthogonalize(basis, scratch, h, k + 1);
84 h[k + 1] = beta;
85
86 // Step 4: normalize and extend basis (skip on lucky breakdown)
87 if (beta > breakdown_tol) {
88 scale(scratch, real(1) / beta);
89 basis.push_back(scratch);
90 }
91
92 return beta;
93}
94
95} // namespace num::kernel::subspace
constexpr idx size() const noexcept
Definition vector.hpp:80
Dense row-major matrix with optional GPU storage.
Definition matrix.hpp:12
real * data()
Definition matrix.hpp:28
constexpr idx rows() const noexcept
Definition matrix.hpp:24
constexpr idx cols() const noexcept
Definition matrix.hpp:25
idx n_rows() const
Definition sparse.hpp:33
Matrix operations.
real arnoldi_step(const LinearOp &A, std::vector< Vector > &basis, std::vector< real > &h, idx k, Vector &scratch, real breakdown_tol=real(1e-14))
One Arnoldi step: expand the orthonormal basis by one vector.
Definition subspace.cpp:73
real mgs_orthogonalize(const std::vector< Vector > &basis, Vector &v, std::vector< real > &h, idx k)
Modified Gram-Schmidt: orthogonalize v against basis[0..k-1].
Definition subspace.cpp:32
double real
Definition types.hpp:10
real beta(real a, real b)
B(a, b) – beta function.
Definition math.hpp:248
std::size_t idx
Definition types.hpp:11
void matvec(const Matrix &A, const Vector &x, Vector &y, Backend b=default_backend)
y = A * x
Definition matrix.cpp:120
void scale(Vector &v, real alpha, Backend b=default_backend)
v *= alpha
Definition vector.cpp:29
void sparse_matvec(const SparseMatrix &A, const Vector &x, Vector &y)
y = A * x
Definition sparse.cpp:124
real dot(const Vector &x, const Vector &y, Backend b=default_backend)
dot product
Definition vector.cpp:79
BasicVector< real > Vector
Real-valued dense vector with full backend dispatch (CPU + GPU)
Definition vector.hpp:130
real norm(const Vector &x, Backend b=default_backend)
Euclidean norm.
Definition vector.cpp:97
void axpy(real alpha, const Vector &x, Vector &y, Backend b=default_backend)
y += alpha * x
Definition vector.cpp:58
Compressed Sparse Row (CSR) matrix and operations.
void apply(const Vector &x, Vector &y) const override
y = A*x (y must be pre-allocated to the correct size)
Definition subspace.cpp:18
Abstract matrix-free linear operator: y = A*x.
Definition subspace.hpp:55
virtual void apply(const Vector &x, Vector &y) const =0
y = A*x (y must be pre-allocated to the correct size)
void apply(const Vector &x, Vector &y) const override
y = A*x (y must be pre-allocated to the correct size)
Definition subspace.cpp:23
Subspace construction and orthogonalization kernels. (namespace num::kernel::subspace)
Vector operations.