cMHN 1.1
C++ library for learning MHNs with pRC
Loading...
Searching...
No Matches
cholesky.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSD-2-Clause
2
3#ifndef pRC_ALGORITHMS_CHOLESKY_H
4#define pRC_ALGORITHMS_CHOLESKY_H
5
6#include <prc/config.hpp>
16
17namespace pRC
18{
19 template<Operator::Hint H = Operator::Hint::None, class X,
22 If<IsSatisfied<(typename R::Dimension() == 2)>> = 0,
23 If<IsSatisfied<(R::size(0) == R::size(1))>> = 0>
24 static inline constexpr auto cholesky(X &&a)
25 {
26 constexpr auto N = R::size(0);
27
28 decltype(auto) u = [&a]() -> decltype(auto)
29 {
30 if constexpr(H == Operator::Hint::UpperTriangular)
31 {
32 if constexpr(cDebugLevel >= DebugLevel::High)
33 {
34 if(!isUpperTriangular(a))
35 {
37 "Cholesky decomposition failed: Input is not upper "
38 "triangular part of self-adjoint matrix.");
39 }
40
41 return copy(eval(a));
42 }
43 else
44 {
45 return copy<!(!IsReference<X>() && !IsConst<R>())>(eval(a));
46 }
47 }
48 else if constexpr(H == Operator::Hint::LowerTriangular)
49 {
50 if constexpr(cDebugLevel >= DebugLevel::High)
51 {
52 if(!isLowerTriangular(a))
53 {
55 "Cholesky decomposition failed: Input is not lower "
56 "triangular part of self-adjoint matrix.");
57 }
58 }
59
60 return eval(transpose(a));
61 }
62 else if constexpr(H == Operator::Hint::None)
63 {
64 if constexpr(cDebugLevel >= DebugLevel::High)
65 {
66 if(!isSelfAdjoint(a))
67 {
69 "Cholesky decomposition failed: Input is not "
70 "self-adjoint.");
71 }
72 }
73
74 return eval(upperTriangular(a));
75 }
76 else
77 {
78 static_assert(H != H,
79 "Unsupported cholesky decomposition hint.");
80 }
81 }();
82
84 [&u](auto const i)
85 {
86 auto x = real(u(i, i));
87 for(Index k = 0; k < i; ++k)
88 {
89 x -= norm<2, 1>(u(k, i));
90 }
91 x = sqrt(x);
92 u(i, i) = x;
93 for(Index j = i + 1; j < N; ++j)
94 {
95 for(Index k = 0; k < i; ++k)
96 {
97 u(i, j) -= innerProduct(u(k, i), u(k, j));
98 }
99 if(u(i, j) != zero())
100 {
101 u(i, j) /= x;
102 }
103 }
104 });
105
106 if constexpr(cDebugLevel >= DebugLevel::High)
107 {
108 if(!isUpperTriangular(u))
109 {
111 "Cholesky decomposition failed: U is not upper "
112 "triangular.");
113 }
114
115 if(!isSelfAdjoint(adjoint(u) * u))
116 {
118 "Cholesky decomposition failed: Product is not self "
119 "adjoint.");
120 }
121
123 {
124 Logging::error("Cholesky decomposition failed.");
125 }
126 }
127
128 if constexpr(IsReference<decltype(u)>())
129 {
130 return forward<X>(a);
131 }
132 else
133 {
134 return u;
135 }
136 }
137}
138#endif // pRC_ALGORITHMS_CHOLESKY_H
static void error(Xs &&...args)
Definition log.hpp:14
Hint
Definition hint.hpp:9
Definition cholesky.hpp:18
static constexpr X eval(X &&a)
Definition eval.hpp:11
static constexpr auto makeConstantSequence()
Definition sequence.hpp:402
Size Index
Definition type_traits.hpp:21
static constexpr auto cholesky(X &&a)
Definition cholesky.hpp:24
static constexpr decltype(auto) real(X &&a)
Definition real.hpp:11
std::remove_reference_t< T > RemoveReference
Definition type_traits.hpp:56
static constexpr auto zero()
Definition zero.hpp:12
std::enable_if_t< B{}, int > If
Definition type_traits.hpp:68
Constant< Bool, B > IsSatisfied
Definition type_traits.hpp:71
static constexpr auto transpose(JacobiRotation< T > const &a)
Definition jacobi_rotation.hpp:319
static constexpr auto upperTriangular(X &&a)
Definition upper_triangular.hpp:15
static constexpr auto isSelfAdjoint(X &&a, TT const &tolerance=NumericLimits< TT >::tolerance())
Definition is_self_adjoint.hpp:18
static constexpr auto adjoint(JacobiRotation< T > const &a)
Definition jacobi_rotation.hpp:325
static constexpr auto isUpperTriangular(X &&a, TT const &tolerance=NumericLimits< TT >::tolerance())
Definition is_upper_triangular.hpp:18
static constexpr auto isApprox(XA &&a, XB &&b, TT const &tolerance=NumericLimits< TT >::tolerance())
Definition is_approx.hpp:24
static constexpr Conditional< IsSatisfied< C >, RemoveConstReference< X >, X > copy(X &&a)
Definition copy.hpp:13
constexpr auto cDebugLevel
Definition config.hpp:46
static constexpr auto sqrt(Complex< T > const &a)
Definition sqrt.hpp:12
static constexpr auto innerProduct(Complex< TA > const &a, Complex< TB > const &b)
Definition inner_product.hpp:16
static constexpr auto isLowerTriangular(X &&a, TT const &tolerance=NumericLimits< TT >::tolerance())
Definition is_lower_triangular.hpp:18