API Documentation
Loading...
Searching...
No Matches
LUDecomposition.hpp
Go to the documentation of this file.
1/**--------------------------------------------------------------------------------------------
2Copyright (c) 2019, NDEVR LLC
3tyler.parke@ndevr.org
4 __ __ ____ _____ __ __ _______
5 | \ | | | __ \ | ___|\ \ / / | __ \
6 | \ | | | | \ \ | |___ \ \ / / | |__) |
7 | . \| | | |__/ / | |___ \ V / | _ /
8 | |\ |_|_____/__|_____|___\_/____| | \ \
9 |__| \__________________________________| \__\
10
11Subject to the terms of the Enterprise+ Agreement, NDEVR hereby grants
12Licensee a limited, non-exclusive, non-transferable, royalty-free license
13(without the right to sublicense) to use the API solely for the purpose of
14Licensee's internal development efforts to develop applications for which
15the API was provided.
16
17The above copyright notice and this permission notice shall be included in all
18copies or substantial portions of the Software.
19
20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
21INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
22PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
23FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25DEALINGS IN THE SOFTWARE.
26
27Library: Base
28File: LUDecomposition
29Included in API: True
30Author(s): Tyler Parke
31 *-----------------------------------------------------------------------------------------**/
32#pragma once
33#include <NDEVR/Matrix.h>
34namespace NDEVR
35{
36 template<class t_type, uint01 t_m, uint01 t_n>
38 {
39 public:
41 : LU(A)
42 {
43
44 // Use a "left-looking", dot-product, Crout/Doolittle algorithm.
45
46 for (uint01 i = 0; i < t_m; i++)
47 {
48 piv[i] = i;
49 }
50 pivsign = 1;
51 Vector<t_m, t_type> LUrowi(0.0);
52 Vector<t_m, t_type> LUcolj(0.0);
53
54 // Outer loop.
55
56 for (uint01 j = 0; j < t_n; j++)
57 {
58
59 // Make a copy of the j-th column to localize references.
60 for (uint01 i = 0; i < t_m; i++)
61 LUcolj[i] = LU[i][j];
62
63 // Apply previous transformations.
64
65 for (uint01 i = 0; i < t_m; i++)
66 {
67 LUrowi = LU[i];
68
69 // Most of the time is spent in the following dot product.
70
71 uint01 kmax = getMin(i, j);
72 t_type s(0);
73 for (uint01 k = 0; k < kmax; k++)
74 s += LUrowi[k] * LUcolj[k];
75
76 LUrowi[j] = LUcolj[i] -= s;
77 }
78
79 // Find pivot and exchange if necessary.
80
81 uint01 p = j;
82 for (uint01 i = j + 1; i < t_m; i++)
83 {
84 if (abs(LUcolj[i]) > abs(LUcolj[p]))
85 p = i;
86 }
87 if (p != j)
88 {
89 for (uint01 k = 0; k < t_n; k++)
90 {
91 std::swap(LU[p][k], LU[j][k]);
92 }
93 std::swap(piv[p], piv[j]);
94 pivsign = -pivsign;
95 }
96
97 // Compute multipliers.
98
99 if (j < t_m && LU[j][j] != 0.0)
100 {
101 for (uint01 i = j + 1; i < t_m; i++) {
102 LU[i][j] /= LU[j][j];
103 }
104 }
105 }
106 }
107
108 /* ------------------------
109 Public Methods
110 * ------------------------ */
111
112 /** Is the matrix nonsingular?
113 @return true if U, and hence A, is nonsingular.
114 */
115
116 bool isNonsingular() const
117 {
118 for (uint01 j = 0; j < t_n; j++)
119 {
120 if (LU[j][j] == 0)
121 return false;
122 }
123 return true;
124 }
125
126 /** Return lower triangular factor
127 @return L
128 */
129
131 {
133 for (uint01 i = 0; i < t_m; i++)
134 {
135 for (uint01 j = 0; j < t_n; j++)
136 {
137 if (i > j)
138 mat[i][j] = LU[i][j];
139 else if (i == j)
140 mat[i][j] = t_type(1);
141 else
142 mat[i][j] = t_type(0);
143 }
144 }
145 return mat;
146 }
147
148 /** Return upper triangular factor
149 @return U
150 */
151
153 {
155 for (uint01 i = 0; i < t_n; i++)
156 {
157 for (uint01 j = 0; j < t_n; j++)
158 {
159 if (i <= j)
160 mat[i][j] = LU[i][j];
161 else
162 mat[i][j] = t_type(0);
163 }
164 }
165 return mat;
166 }
167
168 /** Return pivot permutation vector
169 @return piv
170 */
171 template<class t_pivot_type = sint04>
173 {
174 return piv.template as<t_m, t_pivot_type>();
175 }
176
177 /** Determinant
178 @return det(A)
179 @exception IllegalArgumentException Matrix must be square
180 */
181
182 t_type det() const
183 {
184 static_assert(t_m == t_n, "Matrix must be square.");
185 t_type d = cast<t_type>(pivsign);
186 for (uint01 j = 0; j < t_n; j++)
187 d *= LU[j][j];
188 return d;
189 }
190
191 /** Solve A*X = B
192 @param B A Matrix with as many rows as A and any number of columns.
193 @return X so that L*U*X = B(piv,:)
194 @exception IllegalArgumentException Matrix row dimensions must agree.
195 @exception RuntimeException Matrix is singular.
196 */
197 template<uint01 t_nx>
199 {
200 lib_assert(isNonsingular(), "Matrix cannot be singular.");
201
202 // Copy right hand side with pivoting
203 Matrix<t_type, t_m, t_nx> mat = B.template subMatrix<0, t_nx - 1>(piv);
204
205 // Solve L*Y = B(piv,:)
206 for (uint01 k = 0; k < t_n; k++)
207 {
208 for (uint01 i = k + 1; i < t_n; i++)
209 {
210 for (uint01 j = 0; j < t_nx; j++)
211 {
212 mat[i][j] -= mat[k][j] * LU[i][k];
213 }
214 }
215 }
216 // Solve U*X = Y;
217 for (uint01 k = t_n - 1; !isNaN(k); k--)
218 {
219 for (uint01 j = 0; j < t_nx; j++)
220 mat[k][j] /= LU[k][k];
221 for (uint01 i = 0; i < k; i++)
222 {
223 for (uint01 j = 0; j < t_nx; j++)
224 mat[i][j] -= mat[k][j] * LU[i][k];
225 }
226 }
227 return mat;
228 }
229
230 private:
232
233 /** Row and column dimensions, and pivot sign.
234 @serial column dimension.
235 @serial row dimension.
236 @serial pivot sign.
237 */
238 sint04 pivsign;
239
240 /** Internal storage of pivot vector.
241 @serial pivot vector.
242 */
244 };
245}
246
#define lib_assert(expression, message)
Asserts some logic in the code. Disabled in non debug mode by default. Can be re-enabled in release u...
Definition LibAssert.h:70
Definition LUDecomposition.hpp:38
Matrix< t_type, t_m, t_nx > solve(const Matrix< t_type, t_m, t_nx > &B)
Definition LUDecomposition.hpp:198
LUDecomposition(const Matrix< t_type, t_m, t_n > &A)
Definition LUDecomposition.hpp:40
bool isNonsingular() const
Definition LUDecomposition.hpp:116
Matrix< t_type, t_m, t_n > getU() const
Definition LUDecomposition.hpp:152
Vector< t_m, t_pivot_type > getPivot() const
Definition LUDecomposition.hpp:172
t_type det() const
Definition LUDecomposition.hpp:182
Matrix< t_type, t_m, t_n > getL() const
Definition LUDecomposition.hpp:130
Definition Matrix.hpp:173
An element of a vector space. An element of the real coordinate space Rn Basis vector,...
Definition Vector.hpp:62
Definition ACIColor.h:37
int32_t sint04
-Defines an alias representing a 4 byte, signed integer. -Can represent exact integer values -2147483...
Definition BaseValues.hpp:76
uint8_t uint01
-Defines an alias representing a 1 byte, unsigned integer -Can represent exact integer values 0 throu...
Definition BaseValues.hpp:98
constexpr t_to cast(const Angle< t_from > &value)
Definition Angle.h:514
constexpr Angle< t_angle_type > abs(const Angle< t_angle_type > &value)
Definition AngleFunctions.h:750
constexpr bool isNaN(const t_type &value)
Query if 'value' is valid or invalid.
Definition BaseFunctions.hpp:200
@ B
Definition BaseValues.hpp:203
@ A
Definition BaseValues.hpp:201
constexpr t_type getMin(const t_type &left, const t_type &right)
Finds the minimum of the given arguments based on the < operator.
Definition BaseFunctions.hpp:67