numerics
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ᵀ
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ᵀ * A (project A to k-dim subspace)
23/// 5. SVD of B = Ũ * Sigma * Vᵀ (small kxn problem)
24/// 6. U = Q * Ũ (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/vector.hpp"
31#include "core/policy.hpp"
33#include "core/util/math.hpp"
34#include <cmath>
35#include <algorithm>
36#include <stdexcept>
37
38namespace num {
39
40/// @brief Result of a Singular Value Decomposition: A = U * diag(S) * Vᵀ
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; ///< Jacobi sweeps (full SVD only; 0 for randomized)
46 bool converged; ///< Whether Jacobi converged (always true for randomized)
47};
48
49/// @brief Full SVD of an mxn matrix via one-sided Jacobi.
50///
51/// Returns the economy SVD: r = min(m,n), U is mxr, S has r elements, Vt is rxn.
52///
53/// @param A Input matrix (not modified)
54/// @param backend Backend for column-update inner loops (Backend::omp parallelises)
55/// @param tol Convergence: stop when max |col_p * col_q| / (||col_p|| ||col_q||) < tol
56/// @param max_sweeps Safety cap on Jacobi sweeps
57SVDResult svd(const Matrix& A,
58 Backend backend = Backend::seq,
59 real tol = 1e-12, idx max_sweeps = 100);
60
61/// @brief Randomized truncated SVD -- top-k singular triplets.
62///
63/// Efficient when k << min(m,n). The two dominant costs -- Y = A*Omega and B = Qᵀ*A
64/// -- are dispatched via the given backend.
65///
66/// @param A Input matrix
67/// @param k Number of singular values/vectors to compute
68/// @param backend Backend for internal matmul calls (default: default_backend)
69/// @param oversampling Extra random vectors for accuracy (default 10)
70/// @param rng Random number generator (default: seeded from hardware)
72 Backend backend = default_backend,
73 idx oversampling = 10, Rng* rng = nullptr);
74
75} // namespace num
Dense row-major matrix with optional GPU storage.
Definition matrix.hpp:12
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:143
double real
Definition types.hpp:10
Backend
Selects which backend handles a linalg operation.
Definition policy.hpp:19
@ seq
Naive textbook loops – always available.
constexpr T ipow(T x) noexcept
Compute x^N at compile time via repeated squaring.
std::size_t idx
Definition types.hpp:11
constexpr real e
Definition math.hpp:41
SVDResult svd(const Matrix &A, Backend backend=Backend::seq, real tol=1e-12, idx max_sweeps=100)
Full SVD of an mxn matrix via one-sided Jacobi.
Definition svd.cpp:39
constexpr Backend default_backend
Definition policy.hpp:57
Backend enum for linear algebra operations.
QR factorization via Householder reflections.
Seeded pseudo-random number generator (Mersenne Twister). Pass a pointer to rng_* functions to draw s...
Definition math.hpp:274
Result of a Singular Value Decomposition: A = U * diag(S) * Vᵀ
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.