numerics 0.1.0
Loading...
Searching...
No Matches
svd.cpp
Go to the documentation of this file.
1/// @file linalg/svd/backends/lapack/svd.cpp
2/// @brief LAPACK SVD via LAPACKE_dgesdd (divide-and-conquer).
3#include "impl.hpp"
4#include "../seq/impl.hpp"
5#include <algorithm>
6#include <stdexcept>
7#include <string>
8
9#if defined(NUMERICS_HAS_LAPACK)
10 #include <lapacke.h>
11#endif
12
13namespace num::backends::lapack {
14
15SVDResult svd(const Matrix& A_in) {
16#if defined(NUMERICS_HAS_LAPACK)
17 const idx m = A_in.rows(), n = A_in.cols();
18 const idx r = std::min(m, n);
19 Matrix Aw = A_in; // dgesdd overwrites A
20 Vector S(r);
21 // Economy mode ('S'): U is m x r (lda=m), Vt is r x n (lda=r).
22 // Matrix lda equals its row count, so declare Vt as (r x n) not (n x n).
23 Matrix U(m, r);
24 Matrix Vt(r, n);
25
26 int info =
27 LAPACKE_dgesdd(LAPACK_ROW_MAJOR,
28 'S',
29 static_cast<lapack_int>(m),
30 static_cast<lapack_int>(n),
31 Aw.data(),
32 static_cast<lapack_int>(n), // lda = cols (row-major)
33 S.data(),
34 U.data(),
35 static_cast<lapack_int>(r), // ldu = r (cols of U)
36 Vt.data(),
37 static_cast<lapack_int>(n)); // ldvt = n (cols of Vt)
38 if (info != 0)
39 throw std::runtime_error("svd (lapack): dgesdd failed, info="
40 + std::to_string(info));
41
42 return {std::move(U), std::move(S), std::move(Vt), 0, true};
43#else
44 return seq::svd(A_in, 1e-12, 100);
45#endif
46}
47
48} // namespace num::backends::lapack
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
SVDResult svd(const Matrix &A)
Definition svd.cpp:15
SVDResult svd(const Matrix &A, real tol, idx max_sweeps)
Definition svd.cpp:11
std::size_t idx
Definition types.hpp:11
constexpr real e
Definition math.hpp:43
std::experimental::simd butterfly for FFT.
Result of a Singular Value Decomposition: A = U * diag(S) * V^T.
Definition svd.hpp:41