Loading...
Searching...
No Matches
system_solvers_small.tpp
1/*---------------------------------------------------------------------------*\
2 *
3 * bitpit
4 *
5 * Copyright (C) 2015-2021 OPTIMAD engineering Srl
6 *
7 * -------------------------------------------------------------------------
8 * License
9 * This file is part of bitpit.
10 *
11 * bitpit is free software: you can redistribute it and/or modify it
12 * under the terms of the GNU Lesser General Public License v3 (LGPL)
13 * as published by the Free Software Foundation.
14 *
15 * bitpit is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18 * License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with bitpit. If not, see <http://www.gnu.org/licenses/>.
22 *
23\*---------------------------------------------------------------------------*/
24
25namespace bitpit{
26namespace linearalgebra{
32// -------------------------------------------------------------------------- //
40template <class T>
41void cramer(
42 std::vector< std::vector < T > > &A,
43 std::vector< T > &B,
44 std::vector< T > &x
45) {
46
47// ========================================================================== //
48// VARIABLES DECLARATION //
49// ========================================================================== //
50
51// Local variables
52int l, m, n;
53T dA;
54std::vector< std::vector < T > > C;
55
56// Counters
57int i, j;
58
59// ========================================================================== //
60// CHECK INPUT //
61// ========================================================================== //
62m = A.size();
63if (m == 0) { return; }
64n = A[0].size();
65if (n == 0) { return; }
66if (m != n) {
67 return;
68}
69l = B.size();
70if (l == 0) { return; }
71if (l != m) {
72 return;
73}
74
75// =================================================================================== //
76// SOLVE LINEAR SYSTEM //
77// =================================================================================== //
78
79// Solvability condition
80dA = det(A);
81if (std::abs(dA) < 1.0e-14) {
82 return;
83}
84
85// Solve linear system
86x.resize(n, (T) 0.0);
87for (i = 0; i < m; i++) {
88
89 // Build B
90 C = A;
91 for (j = 0; j < m; j++) {
92 C[j][i] = B[j];
93 } //next j
94 x[i] = det(C)/dA;
95
96} //next i
97
98return; };
99
100// -------------------------------------------------------------------------- //
109template <class T, size_t m, size_t n>
111 std::array< std::array < T, n >, m > &A,
112 std::array< T, m > &B,
113 std::array< T, n > &x
114) {
115
116// ========================================================================== //
117// VARIABLES DECLARATION //
118// ========================================================================== //
119
120// Local variables
121T dA;
122std::array< std::array < T, n >, m > C;
123
124// Counters
125int i, j;
126
127// ========================================================================== //
128// CHECK INPUT //
129// ========================================================================== //
130if (m == 0) { return; }
131if (n == 0) { return; }
132if (m != n) {
133 return;
134}
135
136// ========================================================================== //
137// SOLVE LINEAR SYSTEM //
138// ========================================================================== //
139
140// Solvability condition
141dA = det(A);
142if (std::abs(dA) < 1.0e-14) {
143 return;
144}
145
146// Solve linear system
147for (i = 0; i < m; i++) {
148
149 // Build B
150 C = A;
151 for (j = 0; j < m; j++) {
152 C[j][i] = B[j];
153 } //next j
154 x[i] = det(C)/dA;
155
156} //next i
157
158return; };
159
160// -------------------------------------------------------------------------- //
176template<size_t m>
177unsigned int factorizeLU(
178 std::array< std::array < double, m >, m > &A,
179 std::array< std::array < double, m >, m > &L,
180 std::array< std::array < double, m >, m > &U,
181 std::array< std::array < double, m >, m > *P
182) {
183
184// ========================================================================== //
185// VARIABLES DECLARATION //
186// ========================================================================== //
187
188// Parameters
189double toll_pivot = 1.0e-8;
190
191// Local variables
192int info = 0;
193int pivot_row;
194double pivot, pivot_trial;
195std::array<std::array<double, m>, m> AA;
196
197// Counter
198int i, j, k;
199
200// ========================================================================== //
201// CHECK INPUT //
202// ========================================================================== //
203if (m == 0) { return(3); };
204
205// ========================================================================== //
206// RESIZE INPUT VARIABLES //
207// ========================================================================== //
208
209// LU matrices
210zeros(L);
211zeros(U);
212
213// Backup copy of coeffs. matrix
214AA = A;
215
216// Pivoting array
217eye(*P);
218
219// ========================================================================== //
220// COMPUTE LU FACTORIZATION //
221// ========================================================================== //
222for (k = 0; k < m; k++) {
223 L[k][k] = 1.0;
224
225 // Pivoting ------------------------------------------------------------- //
226 pivot_row = k;
227 pivot = std::abs(AA[k][k]);
228 for (i = k+1; i < m; i++) {
229 pivot_trial = std::abs(AA[i][k]);
230 if (pivot_trial > pivot) {
231 pivot = pivot_trial;
232 pivot_row = i;
233 }
234 } //next i
235
236 // Perform rows permutation --------------------------------------------- //
237 if (pivot_row == k) {
238 if (pivot < 1.0e-14) {
239 info = 2;
240 return(info);
241 }
242 else if ((pivot >= 1.0e-14) && (pivot < toll_pivot)) {
243 info = 1;
244 }
245 }
246 else {
247 swap(AA[k], AA[pivot_row]);
248 if (P != NULL) {
249 swap((*P)[k], (*P)[pivot_row]);
250 }
251 }
252
253 // Gauss elimination ---------------------------------------------------- //
254 for (i = k+1; i < m; i++) {
255 L[i][k] = AA[i][k]/AA[k][k] ;
256 for (j = k+1; j < m; j++) {
257 AA[i][j] = AA[i][j] - L[i][k]*AA[k][j];
258 } //next j
259
260 } //next i
261 for (j = k; j < m; j++) {
262 U[k][j] = AA[k][j];
263 } //next j
264} //next k
265
266return(info); };
267
268// -------------------------------------------------------------------------- //
277template<size_t m>
279 std::array< std::array < double, m >, m > &A,
280 std::array< double, m > &B,
281 std::array< double, m > &x
282) {
283
284// ========================================================================== //
285// VARIABLES DECLARATION //
286// ========================================================================== //
287
288// Local variables
289double sum, d;
290
291// Counter
292int i, p;
293
294// ========================================================================== //
295// CHECK INPUT //
296// ========================================================================== //
297if (m == 0) { return; };
298
299// ========================================================================== //
300// CHECK SOLVABILITY CONDITION //
301// ========================================================================== //
302d = 1.0;
303for (i = 0; i < m; i++) {
304 d = d*A[i][i];
305} //next i
306if (std::abs(d) < 1.0e-14) {
307 return;
308}
309
310// ========================================================================== //
311// SOLVE LINEAR SYSTEM WITH BACKWARD SUBSTITUTION //
312// ========================================================================== //
313for (i = m-1; i >= 0; i--) {
314 sum = 0.0;
315 for(p = m-1; p > i; p--) {
316 sum += A[i][p]*x[p];
317 } //next p
318 x[i] = (B[i] - sum)/A[i][i];
319} //next i
320
321return; };
322
323// -------------------------------------------------------------------------- //
332template<size_t m>
334 std::array< std::array < double, m >, m > &A,
335 std::array< double, m > &B,
336 std::array< double, m > &x
337) {
338
339// ========================================================================== //
340// VARIABLES DECLARATION //
341// ========================================================================== //
342
343// Local variables
344double d, sum;
345
346// Counters
347int i, p;
348
349
350// ========================================================================== //
351// CHECK INPUT //
352// ========================================================================== //
353if (m == 0) { return; };
354
355// ========================================================================== //
356// CHECK SOLVABILITY CONDITION //
357// ========================================================================== //
358d = 1.0;
359for (i = 0; i < m; i++) {
360 d = d*A[i][i];
361} //next i
362if (std::abs(d) < 1.0e-14) {
363 return;
364}
365
366// ========================================================================== //
367// FORWARD SUBSTITUTION //
368// ========================================================================== //
369for(i = 0; i < m; i++) {
370 sum = 0.0;
371 for(p = 0; p < i; p++) {
372 sum += A[i][p] * x[p];
373 } //next p
374 x[i] = (B[i] - sum)/A[i][i];
375} //next i
376
377return; };
378
379// -------------------------------------------------------------------------- //
388template<size_t m>
390 std::array< std::array< double, m >, m > &A,
391 std::array< double, m > &B,
392 std::array< double, m > &x
393) {
394
395// ========================================================================== //
396// VARIABLES DECLARATION //
397// ========================================================================== //
398
399// Local variables
400unsigned int info;
401std::array<std::array<double, m>, m> L, U, P, *P_ = &P;
402std::array<double, m> z, C;
403
404// Counters
405// none
406
407// ========================================================================== //
408// COMPUTE LU FACTORIZATION //
409// ========================================================================== //
410info = factorizeLU(A, L, U, P_);
411if ((info == 2) || (info == 3)) {
412 return;
413}
414matmul(P, B, C);
415
416// ========================================================================== //
417// SOLVE THE LINEAR SYSTEM //
418// ========================================================================== //
419
420// Forward substitution
421forwardSubstitution(L, C, z);
422
423// Bacward substitution
424backwardSubstitution(U, z, x);
425
426return; };
427
431}
432}
void sum(const std::array< T, d > &x, T1 &s)
T det(std::vector< std::vector< T > > &)
void matmul(T, const std::vector< std::vector< T > > &, std::vector< std::vector< T > > &)
void zeros(std::vector< std::vector< T > > &, int, int)
void eye(std::vector< std::vector< T > > &, int, int)
void forwardSubstitution(std::vector< std::vector< double > > &A, std::vector< double > &B, std::vector< double > &x)
void backwardSubstitution(std::vector< std::vector< double > > &A, std::vector< double > &B, std::vector< double > &x)
unsigned int factorizeLU(std::vector< std::vector< double > > &A, std::vector< std::vector< double > > &L, std::vector< std::vector< double > > &U, std::vector< std::vector< double > > *P)
void solveLU(std::vector< std::vector< double > > &A, std::vector< double > &B, std::vector< double > &x)
void cramer(std::vector< std::vector< T > > &, std::vector< T > &, std::vector< T > &)
--- layout: doxygen_footer ---