<T>LAPACK 0.1.1
C++ Template Linear Algebra PACKage
Loading...
Searching...
No Matches
potrf2.hpp
Go to the documentation of this file.
1
4//
5// Copyright (c) 2021-2023, University of Colorado Denver. All rights reserved.
6//
7// This file is part of <T>LAPACK.
8// <T>LAPACK is free software: you can redistribute it and/or modify it under
9// the terms of the BSD 3-Clause license. See the accompanying LICENSE file.
10
11#ifndef TLAPACK_POTRF2_HH
12#define TLAPACK_POTRF2_HH
13
15#include "tlapack/blas/herk.hpp"
16#include "tlapack/blas/trsm.hpp"
17
18namespace tlapack {
19
72template <TLAPACK_UPLO uplo_t, TLAPACK_SMATRIX matrix_t>
73int potrf2(uplo_t uplo, matrix_t& A, const EcOpts& opts = {})
74{
75 using T = type_t<matrix_t>;
76 using real_t = real_type<T>;
77 using idx_t = size_type<matrix_t>;
78 using range = pair<idx_t, idx_t>;
79
80 // Constants
81 const real_t one(1);
82 const real_t zero(0);
83 const idx_t n = nrows(A);
84
85 // check arguments
86 tlapack_check_false(uplo != Uplo::Lower && uplo != Uplo::Upper);
87 tlapack_check_false(nrows(A) != ncols(A));
88
89 // Quick return
90 if (n <= 0) return 0;
91
92 // Stop recursion
93 else if (n == 1) {
94 const real_t a00 = real(A(0, 0));
95 if (a00 > zero) {
96 A(0, 0) = sqrt(a00);
97 return 0;
98 }
99 else {
101 opts.ec.internal, 1,
102 "The leading minor of order 1 is not positive definite,"
103 " and the factorization could not be completed.");
104 return 1;
105 }
106 }
107
108 // Recursive code
109 else {
110 const idx_t n1 = n / 2;
111
112 // Define A11 and A22
113 auto A11 = slice(A, range{0, n1}, range{0, n1});
114 auto A22 = slice(A, range{n1, n}, range{n1, n});
115
116 // Factor A11
117 int info = potrf2(uplo, A11, NO_ERROR_CHECK);
118 if (info != 0) {
120 opts.ec.internal, info,
121 "The leading minor of the reported order is not positive "
122 "definite,"
123 " and the factorization could not be completed.");
124 return info;
125 }
126
127 if (uplo == Uplo::Upper) {
128 // Update and scale A12
129 auto A12 = slice(A, range{0, n1}, range{n1, n});
130 trsm(LEFT_SIDE, Uplo::Upper, CONJ_TRANS, NON_UNIT_DIAG, one, A11,
131 A12);
132
133 // Update A22
134 herk(UPPER_TRIANGLE, CONJ_TRANS, -one, A12, one, A22);
135 }
136 else {
137 // Update and scale A21
138 auto A21 = slice(A, range{n1, n}, range{0, n1});
139 trsm(RIGHT_SIDE, Uplo::Lower, CONJ_TRANS, NON_UNIT_DIAG, one, A11,
140 A21);
141
142 // Update A22
143 herk(LOWER_TRIANGLE, NO_TRANS, -one, A21, one, A22);
144 }
145
146 // Factor A22
147 info = potrf2(uplo, A22, NO_ERROR_CHECK);
148 if (info == 0)
149 return 0;
150 else {
152 opts.ec.internal, info + n1,
153 "The leading minor of the reported order is not positive "
154 "definite,"
155 " and the factorization could not be completed.");
156 return info + n1;
157 }
158 }
159}
160
161} // namespace tlapack
162
163#endif // TLAPACK_POTRF2_HH
void herk(Uplo uplo, Op trans, const alpha_t &alpha, const matrixA_t &A, const beta_t &beta, matrixC_t &C)
Hermitian rank-k update:
Definition herk.hpp:68
void trsm(Side side, Uplo uplo, Op trans, Diag diag, const alpha_t &alpha, const matrixA_t &A, matrixB_t &B)
Solve the triangular matrix-vector equation.
Definition trsm.hpp:76
int potrf2(uplo_t uplo, matrix_t &A, const EcOpts &opts={})
Computes the Cholesky factorization of a Hermitian positive definite matrix A using the recursive alg...
Definition potrf2.hpp:73
constexpr ErrorCheck NO_ERROR_CHECK
Options to disable error checking.
Definition exceptionHandling.hpp:70
#define tlapack_error_if(cond, info, detailedInfo)
Error handler with conditional.
Definition exceptionHandling.hpp:171
#define tlapack_check_false(cond)
Throw an error if cond is true.
Definition exceptionHandling.hpp:113
typename traits::real_type_traits< Types..., int >::type real_type
The common real type of the list of types.
Definition scalar_type_traits.hpp:113
Options for error checking.
Definition exceptionHandling.hpp:76