Tatooine
singular_values.h
Go to the documentation of this file.
1#ifndef TATOOINE_TENSOR_OPERATIONS_SINGULAR_VALUES_H
2#define TATOOINE_TENSOR_OPERATIONS_SINGULAR_VALUES_H
3//==============================================================================
4namespace tatooine {
5//==============================================================================
6template <typename Tensor, typename T, size_t M, size_t N>
7auto svd(base_tensor<Tensor, T, M, N> const& A_base, tag::full_t[ > tag < ]) {
8 auto A = mat<T, M, N>{A_base};
9 return lapack::gesvd(A, lapack::job::A, lapack::job::A);
10}
11// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
12template <typename Tensor, typename T, size_t M, size_t N>
14 tag::economy_t[ > tag < ]) {
15 auto A = mat<T, M, N>{A_base};
16 return lapack::gesvd(A, lapack::job::S, lapack::job::S);
17}
18// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
19template <typename Tensor, typename T, size_t M, size_t N>
21 return svd(A, tag::full);
22}
23// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
24template <typename Tensor, typename T, size_t M, size_t N>
26 tag::full_t[ > tag < ]) {
27 auto A = mat<T, M, N>{A_base};
28 return lapack::gesvd(A, lapack::job::A, lapack::job::N);
29}
30// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
31template <typename Tensor, typename T, size_t M, size_t N>
33 tag::economy_t[ > tag < ]) {
34 auto A = mat<T, M, N>{A_base};
35 return lapack::gesvd(A, lapack::job::S, lapack::job::N);
36}
37// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
38template <typename Tensor, typename T, size_t M, size_t N>
40 return svd_left(A, tag::full);
41}
42// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
43template <typename Tensor, typename T, size_t M, size_t N>
45 tag::full_t[ > tag < ]) {
46 auto A = mat<T, M, N>{A_base};
47 return lapack::gesvd(A, lapack::job::N, lapack::job::A);
48}
49// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
50template <typename Tensor, typename T, size_t M, size_t N>
52 tag::economy_t[ > tag < ]) {
53 auto A = mat<T, M, N>{A_base};
54 return lapack::gesvd(A, lapack::job::N, lapack::job::S);
55}
56// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
57template <typename Tensor, typename T, size_t M, size_t N>
59 return svd_right(A, tag::full);
60}
61//------------------------------------------------------------------------------
62template <typename Tensor, typename T>
64 auto const a = A(0, 0);
65 auto const b = A(0, 1);
66 auto const c = A(1, 0);
67 auto const d = A(1, 1);
68
69 auto const aa = a * a;
70 auto const bb = b * b;
71 auto const cc = c * c;
72 auto const dd = d * d;
73 auto const s1 = aa + bb + cc + dd;
74 auto const s2 = std::sqrt((aa + bb - cc - dd) * (aa + bb - cc - dd) +
75 4 * (a * c + b * d) * (a * c + b * d));
76 auto const sigma1 = std::sqrt((s1 + s2) / 2);
77 auto const sigma2 = std::sqrt((s1 - s2) / 2);
78 return vec{tatooine::max(sigma1, sigma2), tatooine::min(sigma1, sigma2)};
79}
80//------------------------------------------------------------------------------
81template <typename T, size_t M, size_t N>
82constexpr auto singular_values(tensor<T, M, N>&& A) {
83 if constexpr (M == 2 && N == 2) {
84 return singular_values22(A);
85 } else {
86 return gesvd(A, lapack::job::N, lapack::job::N);
87 }
88}
89// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
90template <typename Tensor, typename T, size_t M, size_t N>
91 constexpr auto singular_values(base_tensor<Tensor, T, M, N> const& A_base) {
92 if constexpr (M == 2 && N == 2) {
93 return singular_values22(A_base);
94 } else {
95 auto A = mat<T, M, N>{A_base};
96 return lapack::gesvd(A, lapack::job::N, lapack::job::N);
97 }
98}
99//==============================================================================
100} // namespace tatooine
101//==============================================================================
102#endif
static constexpr full_t full
Definition: tags.h:81
Definition: algorithm.h:6
constexpr auto singular_values(tensor< T, M, N > &&A)
Definition: singular_values.h:82
constexpr auto singular_values22(base_tensor< Tensor, T, 2, 2 > const &A)
Definition: singular_values.h:63
constexpr auto max(A &&a, B &&b)
Definition: math.h:20
constexpr auto min(A &&a, B &&b)
Definition: math.h:15
auto svd_right(base_tensor< Tensor, T, M, N > const &A_base, tag::full_t[> tag<])
Definition: singular_values.h:44
auto svd(base_tensor< Tensor, T, M, N > const &A_base, tag::full_t[> tag<])
Definition: singular_values.h:7
auto svd_left(base_tensor< Tensor, T, M, N > const &A_base, tag::full_t[> tag<])
Definition: singular_values.h:25
Definition: base_tensor.h:23
Definition: mat.h:14
Definition: tags.h:82
Definition: tags.h:80
Definition: tensor.h:17
Definition: vec.h:12