<T>LAPACK 0.1.1
C++ Template Linear Algebra PACKage
Loading...
Searching...
No Matches
trtri_recursive.hpp
Go to the documentation of this file.
1
3//
4// Copyright (c) 2021-2023, University of Colorado Denver. All rights reserved.
5//
6// This file is part of <T>LAPACK.
7// <T>LAPACK is free software: you can redistribute it and/or modify it under
8// the terms of the BSD 3-Clause license. See the accompanying LICENSE file.
9
10#ifndef TLAPACK_TRTRI_RECURSIVE_HH
11#define TLAPACK_TRTRI_RECURSIVE_HH
12
14#include "tlapack/blas/trsm.hpp"
15
16namespace tlapack {
17
47template <TLAPACK_UPLO uplo_t, TLAPACK_SMATRIX matrix_t>
49 Diag diag,
50 matrix_t& C,
51 const EcOpts& opts = {})
52{
53 using T = type_t<matrix_t>;
54 using idx_t = size_type<matrix_t>;
55 using range = pair<idx_t, idx_t>;
56 using real_t = real_type<T>;
57
58 const idx_t n = nrows(C);
59 const real_t zero(0);
60
61 // check arguments
62 tlapack_check_false(uplo != Uplo::Lower && uplo != Uplo::Upper);
63 tlapack_check_false(diag != Diag::NonUnit && diag != Diag::Unit);
64 tlapack_check_false(nrows(C) != ncols(C));
65
66 // Quick return
67 if (n <= 0) return 0;
68
69 idx_t n0 = n / 2;
70
71 if (n == 1) {
72 if (diag == Diag::NonUnit) {
73 if (C(0, 0) != zero) {
74 C(0, 0) = real_t(1.) / C(0, 0);
75 return 0;
76 }
77 else {
78 tlapack_error_if(opts.ec.internal, 1,
79 "A diagonal of entry of triangular "
80 "matrix is exactly zero.");
81 return 1;
82 }
83 }
84 else {
85 return 0;
86 }
87 }
88 else {
89 if (uplo == Uplo::Lower) {
90 auto C00 = slice(C, range(0, n0), range(0, n0));
91 auto C10 = slice(C, range(n0, n), range(0, n0));
92 auto C11 = slice(C, range(n0, n), range(n0, n));
93
94 trsm(RIGHT_SIDE, LOWER_TRIANGLE, NO_TRANS, diag, T(-1), C00, C10);
95 trsm(LEFT_SIDE, LOWER_TRIANGLE, NO_TRANS, diag, T(+1), C11, C10);
96 int info = trtri_recursive(LOWER_TRIANGLE, diag, C00, opts);
97
98 if (info != 0) {
99 tlapack_error_if(opts.ec.internal, info,
100 "A diagonal of entry of triangular "
101 "matrix is exactly zero.");
102 return info;
103 }
104 info = trtri_recursive(LOWER_TRIANGLE, diag, C11, opts);
105 if (info == 0)
106 return 0;
107 else {
108 tlapack_error_if(opts.ec.internal, info + n0,
109 "A diagonal of entry of triangular "
110 "matrix is exactly zero.");
111 return info + n0;
112 }
113
114 // there are two variants, the code below also works
115
116 // trtri_recursive( LOWER_TRIANGLE, C00);
117 // trtri_recursive( LOWER_TRIANGLE, C11);
118 // trmm(RIGHT_SIDE, LOWER_TRIANGLE, NO_TRANS, NON_UNIT_DIAG, T(-1),
119 // C00, C10); trmm(LEFT_SIDE, LOWER_TRIANGLE, NO_TRANS,
120 // NON_UNIT_DIAG, T(+1), C11, C10);
121 }
122 else {
123 auto C00 = slice(C, range(0, n0), range(0, n0));
124 auto C01 = slice(C, range(0, n0), range(n0, n));
125 auto C11 = slice(C, range(n0, n), range(n0, n));
126
127 trsm(LEFT_SIDE, UPPER_TRIANGLE, NO_TRANS, diag, T(-1), C00, C01);
128 trsm(RIGHT_SIDE, UPPER_TRIANGLE, NO_TRANS, diag, T(+1), C11, C01);
129 int info = trtri_recursive(UPPER_TRIANGLE, diag, C00, opts);
130 if (info != 0) {
131 tlapack_error_if(opts.ec.internal, info,
132 "A diagonal of entry of triangular "
133 "matrix is exactly zero.");
134 return info;
135 }
136 info = trtri_recursive(UPPER_TRIANGLE, diag, C11, opts);
137 if (info == 0)
138 return 0;
139 else {
140 tlapack_error_if(opts.ec.internal, info + n0,
141 "A diagonal of entry of triangular "
142 "matrix is exactly zero.");
143 return info + n0;
144 }
145
146 // there are two variants, the code below also works
147
148 // trtri_recursive( C00, Uplo::Upper);
149 // trtri_recursive( C11, Uplo::Upper);
150 // trmm(LEFT_SIDE, UPPER_TRIANGLE, NO_TRANS, NON_UNIT_DIAG, T(-1),
151 // C00, C01); trmm(RIGHT_SIDE, UPPER_TRIANGLE, NO_TRANS,
152 // NON_UNIT_DIAG, T(+1), C11, C01);
153 }
154 }
155}
156
157} // namespace tlapack
158
159#endif // TLAPACK_TRTRI_RECURSIVE_HH
Diag
Definition types.hpp:192
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 trtri_recursive(uplo_t uplo, Diag diag, matrix_t &C, const EcOpts &opts={})
TRTRI computes the inverse of a triangular matrix in-place Input is a triangular matrix,...
Definition trtri_recursive.hpp:48
#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