numerics 0.1.0
Loading...
Searching...
No Matches
svd.hpp
Go to the documentation of this file.
1/// @file svd/svd.hpp
2/// @brief Singular Value Decomposition -- dense and randomized truncated
3///
4/// Two algorithms:
5///
6/// svd(A) Full SVD via one-sided Jacobi: A = U * diag(S) * V^T
7/// svd_truncated(A,k) Randomized truncated SVD: top-k singular triplets
8///
9/// Full SVD (one-sided Jacobi)
10///
11/// The one-sided Jacobi algorithm applies Givens rotations to the columns
12/// of A (from the right) until the columns are mutually orthogonal.
13///
14/// Randomized truncated SVD
15///
16/// For large A where only the top-k singular triplets are needed.
17/// Algorithm (Halko, Martinsson, Tropp 2011):
18///
19/// 1. Draw Omega in R^{nx(k+p)} (Gaussian random sketch, p=10 oversampling)
20/// 2. Y = A * Omega (sample the range of A)
21/// 3. Q = QR(Y) (orthonormal basis for approx. range)
22/// 4. B = Q^T * A (project A to k-dim subspace)
23/// 5. SVD of B = U~ * Sigma * V^T (small kxn problem)
24/// 6. U = Q * U~ (lift back to full dimension)
25///
26/// Cost: O(mnk) vs O(mn*min(m,n)) for full SVD.
27#pragma once
28
29#include "core/matrix.hpp"
30#include "core/policy.hpp"
31#include "core/util/math.hpp"
32#include "core/vector.hpp"
34#include <algorithm>
35#include <cmath>
36#include <stdexcept>
37
38namespace num {
39
40/// @brief Result of a Singular Value Decomposition: A = U * diag(S) * V^T
41struct SVDResult {
42 Matrix U; ///< mxr left singular vectors (columns orthonormal)
43 Vector S; ///< r singular values in descending order
44 Matrix Vt; ///< rxn right singular vectors (rows orthonormal)
45 idx sweeps = 0; ///< Jacobi sweeps (full SVD only; 0 for randomized)
46 bool converged =
47 false; ///< Whether Jacobi converged (always true for randomized)
48};
49
50/// @brief Full SVD of an mxn matrix.
51///
52/// Returns the economy SVD: r = min(m,n), U is mxr, S has r elements, Vt is
53/// rxn.
54///
55/// @param A Input matrix (not modified)
56/// @param backend Backend::lapack uses LAPACKE_dgesdd (default when
57/// available).
58/// Backend::omp parallelises Jacobi column-update loops.
59/// Backend::seq uses our one-sided Jacobi implementation.
60/// @param tol Jacobi convergence tolerance (ignored for Backend::lapack)
61/// @param max_sweeps Jacobi sweep cap (ignored for Backend::lapack)
62SVDResult svd(const Matrix& A,
63 Backend backend = lapack_backend,
64 real tol = 1e-12,
65 idx max_sweeps = 100);
66
67/// @brief Randomized truncated SVD -- top-k singular triplets.
68///
69/// Efficient when k << min(m,n). The two dominant costs -- Y = A*Omega and B
70/// = Q^T*A
71/// -- are dispatched via the given backend.
72///
73/// @param A Input matrix
74/// @param k Number of singular values/vectors to compute
75/// @param backend Backend for internal matmul calls (default:
76/// default_backend)
77/// @param oversampling Extra random vectors for accuracy (default 10)
78/// @param rng Random number generator (default: seeded from hardware)
80 idx k,
81 Backend backend = default_backend,
82 idx oversampling = 10,
83 Rng* rng = nullptr);
84
85} // namespace num
Dense row-major matrix with optional GPU storage.
Definition matrix.hpp:12
Backend enum for linear algebra operations.
Thin wrappers around C++17 <cmath> and <numeric> with readable names.
Matrix operations.
SVDResult svd_truncated(const Matrix &A, idx k, Backend backend=default_backend, idx oversampling=10, Rng *rng=nullptr)
Randomized truncated SVD – top-k singular triplets.
Definition svd.cpp:50
double real
Definition types.hpp:10
Backend
Selects which backend handles a linalg operation.
Definition policy.hpp:19
std::size_t idx
Definition types.hpp:11
SVDResult svd(const Matrix &A, Backend backend=lapack_backend, real tol=1e-12, idx max_sweeps=100)
Full SVD of an mxn matrix.
Definition svd.cpp:31
constexpr Backend lapack_backend
Definition policy.hpp:124
constexpr real e
Definition math.hpp:43
constexpr Backend default_backend
Definition policy.hpp:92
QR factorization via Householder reflections.
Seeded pseudo-random number generator (Mersenne Twister). Pass a pointer to rng_* functions to draw s...
Definition math.hpp:281
Result of a Singular Value Decomposition: A = U * diag(S) * V^T.
Definition svd.hpp:41
Matrix Vt
rxn right singular vectors (rows orthonormal)
Definition svd.hpp:44
Matrix U
mxr left singular vectors (columns orthonormal)
Definition svd.hpp:42
Vector S
r singular values in descending order
Definition svd.hpp:43
bool converged
Whether Jacobi converged (always true for randomized)
Definition svd.hpp:46
idx sweeps
Jacobi sweeps (full SVD only; 0 for randomized)
Definition svd.hpp:45
Vector operations.