faer/linalg/cholesky/llt/
factor.rs1use crate::internal_prelude::*;
2use crate::linalg::cholesky::ldlt::factor::cholesky_recursion;
3
4#[derive(Copy, Clone, Debug)]
9pub struct LltRegularization<T> {
10 pub dynamic_regularization_delta: T,
12 pub dynamic_regularization_epsilon: T,
14}
15
16#[derive(Copy, Clone, Debug)]
18pub struct LltInfo {
19 pub dynamic_regularization_count: usize,
21}
22
23#[derive(Copy, Clone, Debug)]
25pub enum LltError {
26 NonPositivePivot { index: usize },
27}
28
29impl core::fmt::Display for LltError {
30 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
31 core::fmt::Debug::fmt(self, f)
32 }
33}
34impl core::error::Error for LltError {}
35
36impl<T: RealField> Default for LltRegularization<T> {
37 fn default() -> Self {
38 Self {
39 dynamic_regularization_delta: zero(),
40 dynamic_regularization_epsilon: zero(),
41 }
42 }
43}
44
45#[derive(Copy, Clone, Debug)]
46pub struct LltParams {
47 pub recursion_threshold: usize,
48 pub blocksize: usize,
49
50 #[doc(hidden)]
51 pub non_exhaustive: NonExhaustive,
52}
53
54impl<T: ComplexField> Auto<T> for LltParams {
55 #[inline]
56 fn auto() -> Self {
57 Self {
58 recursion_threshold: 64,
59 blocksize: 128,
60 non_exhaustive: NonExhaustive(()),
61 }
62 }
63}
64
65#[inline]
66pub fn cholesky_in_place_scratch<T: ComplexField>(dim: usize, par: Par, params: Spec<LltParams, T>) -> StackReq {
67 _ = par;
68 _ = params;
69 temp_mat_scratch::<T>(dim, 1)
70}
71
72#[math]
73pub fn cholesky_in_place<T: ComplexField>(
74 A: MatMut<'_, T>,
75 regularization: LltRegularization<T::Real>,
76 par: Par,
77 stack: &mut MemStack,
78 params: Spec<LltParams, T>,
79) -> Result<LltInfo, LltError> {
80 let params = params.config;
81 let N = A.nrows();
82 let mut D = unsafe { temp_mat_uninit(N, 1, stack).0 };
83 let D = D.as_mat_mut();
84
85 match cholesky_recursion(
86 A,
87 D.col_mut(0).transpose_mut(),
88 params.recursion_threshold,
89 params.blocksize,
90 true,
91 regularization.dynamic_regularization_delta > zero() && regularization.dynamic_regularization_epsilon > zero(),
92 ®ularization.dynamic_regularization_epsilon,
93 ®ularization.dynamic_regularization_delta,
94 None,
95 par,
96 ) {
97 Ok(count) => Ok(LltInfo {
98 dynamic_regularization_count: count,
99 }),
100 Err(index) => Err(LltError::NonPositivePivot { index }),
101 }
102}