numerics 0.1.0
Loading...
Searching...
No Matches
expv.hpp
Go to the documentation of this file.
1/// @file expv.hpp
2/// @brief Krylov subspace matrix exponential-vector product: compute exp(t*A)*v
3///
4/// Approximates \f$\exp(tA)v \approx \|v\| Q_m \exp(tH_m)e_1\f$ where
5/// \f$AQ_m \approx Q_{m+1}\bar{H}_m\f$ is the Arnoldi relation.
6/// @todo Add adaptive step subdivision and an a posteriori error estimate for
7/// large \f$|t|\|A\|\f$.
8#pragma once
9
10#include "core/matrix.hpp"
11#include "core/types.hpp"
12#include "core/vector.hpp"
13#include "kernel/subspace.hpp"
15#include "core/concepts.hpp"
16#include <stdexcept>
17#include <utility>
18#include <vector>
19
20namespace num {
21
22namespace detail {
24}
25
26/// @brief Compute \f$\exp(tA)v\f$ for any \f$y=A x\f$ adapter.
27template<class Op>
28 requires LinearOperator<Op, Vector, Vector>
29Vector expv(real t, const Op& A, const Vector& v, int m_max = 30, real tol = 1e-8) {
30 const idx n = A.rows();
31 if (A.cols() != n || v.size() != n) {
32 throw std::invalid_argument("expv: dimension mismatch");
33 }
34
35 real beta = norm(v);
36 if (beta < 1e-300) {
37 return Vector(n, 0.0);
38 }
39
40 std::vector<Vector> V;
41 V.reserve(m_max + 1);
42
43 Vector v0(n);
44 for (idx i = 0; i < n; i++) {
45 v0[i] = v[i] / beta;
46 }
47 V.push_back(std::move(v0));
48
49 Matrix H(m_max + 1, m_max, 0.0);
50 int m_actual = m_max;
51 std::vector<real> h_col(m_max + 1, 0.0);
52
53 for (int j = 0; j < m_max; j++) {
54 Vector w(n, 0.0);
55 A.apply(V[j], w);
56
57 const real h_next = kernel::subspace::mgs_orthogonalize(V, w, h_col, j + 1);
58 for (int i = 0; i <= j; i++) {
59 H(i, j) = h_col[i];
60 }
61 H(j + 1, j) = h_next;
62
63 if (h_next < tol) {
64 m_actual = j + 1;
65 break;
66 }
67
68 scale(w, real(1) / h_next);
69 V.push_back(std::move(w));
70 }
71
72 Matrix Hm(m_actual, m_actual, 0.0);
73 for (int i = 0; i < m_actual; i++) {
74 for (int j = 0; j < m_actual; j++) {
75 Hm(i, j) = t * H(i, j);
76 }
77 }
78
80
81 Vector result(n, 0.0);
82 for (int j = 0; j < m_actual; j++) {
83 axpy(beta * E(j, 0), V[j], result);
84 }
85
86 return result;
87}
88
90 const SparseMatrix& A,
91 const Vector& v,
92 int m_max = 30,
93 real tol = 1e-8);
94
95} // namespace num
constexpr idx size() const noexcept
Definition vector.hpp:83
Storage and operator concepts for numerical routines.
Core type definitions.
Dense row-major matrix templated over scalar type T.
Matrix dense_expm_pade6(const Matrix &A)
Definition expv.cpp:14
real mgs_orthogonalize(const std::vector< Vector > &basis, Vector &v, std::vector< real > &h, idx k)
Modified Gram-Schmidt against basis[0..k-1].
Definition subspace.cpp:9
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 scale(Vector &v, real alpha, Backend b=default_backend)
Compute .
Definition vector.cpp:15
BasicMatrix< real > Matrix
Double-precision dense matrix with full backend dispatch (CPU + GPU).
Definition matrix.hpp:127
constexpr real e
Definition math.hpp:44
BasicVector< real > Vector
Real-valued dense vector with full backend dispatch (CPU + GPU)
Definition vector.hpp:129
real norm(const Vector &x, Backend b=default_backend)
Compute .
Definition vector.cpp:83
Vector expv(real t, const Op &A, const Vector &v, int m_max=30, real tol=1e-8)
Compute for any adapter.
Definition expv.hpp:29
void axpy(real alpha, const Vector &x, Vector &y, Backend b=default_backend)
Compute .
Definition vector.cpp:44
Compressed Sparse Row (CSR) matrix and operations.
Subspace construction and orthogonalization kernels.
Dense vector storage and operations.