Loading...
Searching...
No Matches
system_solvers_small.cpp
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
25// ========================================================================== //
26// LINEAR ALGEBRA PACKAGE //
27// //
28// Functions for basic linear algebra computations. //
29// ========================================================================== //
30// INFO //
31// ========================================================================== //
32// Author : Alessandro Alaia //
33// Data : Sept 26, 2014 //
34// Version : v2.0 //
35// //
36// All rights reserved. //
37// ========================================================================== //
38
39// ========================================================================== //
40// INCLUDES //
41// ========================================================================== //
42# include "matrix_utilities.hpp"
43# include "multiplication.hpp"
44# include "system_solvers_small.hpp"
45
46# include "bitpit_private_lapacke.hpp"
47
48namespace bitpit{
49
50namespace linearalgebra{
51
52namespace constants{
53
54const int ROW_MAJOR = LAPACK_ROW_MAJOR;
55const int COL_MAJOR = LAPACK_COL_MAJOR;
56
57}
58
64// -------------------------------------------------------------------------- //
80unsigned int factorizeLU(
81 std::vector<std::vector<double>> &A,
82 std::vector<std::vector<double>> &L,
83 std::vector<std::vector<double>> &U,
84 std::vector<std::vector<double>> *P
85) {
86
87// ========================================================================== //
88// VARIABLES DECLARATION //
89// ========================================================================== //
90
91// Parameters
92double toll_pivot = 1.0e-8;
93
94// Local variables
95int info = 0;
96int m, n, pivot_row;
97double pivot, pivot_trial;
98std::vector<std::vector<double>> AA;
99
100// Counter
101int i, j, k;
102
103// ========================================================================== //
104// CHECK INPUT //
105// ========================================================================== //
106m = A.size();
107if (m == 0) { return(3); };
108n = A[0].size();
109if (m != n) {
110 return (3);
111}
112
113// ========================================================================== //
114// RESIZE INPUT VARIABLES //
115// ========================================================================== //
116
117// LU matrices
118zeros(L, n, n);
119zeros(U, n, n);
120
121// Backup copy of coeffs. matrix
122AA = A;
123
124// Pivoting array
125if (P != NULL) {
126 eye(*P, n, n);
127}
128
129// ========================================================================== //
130// COMPUTE LU FACTORIZATION //
131// ========================================================================== //
132for (k = 0; k < n; k++) {
133 L[k][k] = 1.0;
134
135 // Pivoting ------------------------------------------------------------- //
136 pivot_row = k;
137 pivot = std::abs(AA[k][k]);
138 for (i = k+1; i < n; i++) {
139 pivot_trial = std::abs(AA[i][k]);
140 if (pivot_trial > pivot) {
141 pivot = pivot_trial;
142 pivot_row = i;
143 }
144 } //next i
145
146 // Perform rows permutation --------------------------------------------- //
147 if (pivot_row == k) {
148 if (pivot < 1.0e-14) {
149 info = 2;
150 return(info);
151 }
152 else if ((pivot >= 1.0e-14) && (pivot < toll_pivot)) {
153 info = 1;
154 }
155 }
156 else {
157 swap(AA[k], AA[pivot_row]);
158 if (P != NULL) {
159 swap((*P)[k], (*P)[pivot_row]);
160 }
161 }
162
163 // Gauss elimination ---------------------------------------------------- //
164 for (i = k+1; i < n; i++) {
165 L[i][k] = AA[i][k]/AA[k][k] ;
166 for (j = k+1; j < n; j++) {
167 AA[i][j] = AA[i][j] - L[i][k]*AA[k][j];
168 } //next j
169
170 } //next i
171 for (j = k; j < n; j++) {
172 U[k][j] = AA[k][j];
173 } //next j
174} //next k
175
176return(info); };
177
178// -------------------------------------------------------------------------- //
187 std::vector<std::vector<double>> &A,
188 std::vector<double> &B,
189 std::vector<double> &x
190) {
191
192// ========================================================================== //
193// VARIABLES DECLARATION //
194// ========================================================================== //
195
196// Local variables
197int m, n, l;
198double sum, d;
199
200// Counter
201int i, p;
202
203// ========================================================================== //
204// CHECK INPUT //
205// ========================================================================== //
206m = A.size();
207if (m == 0) { return; };
208n = A[0].size();
209if (m != n) {
210 return;
211}
212l = B.size();
213if (l == 0) { return; };
214if (l != n) {
215 return;
216}
217
218// ========================================================================== //
219// CHECK SOLVABILITY CONDITION //
220// ========================================================================== //
221d = 1.0;
222for (i = 0; i < n; i++) {
223 d = d*A[i][i];
224} //next i
225if (std::abs(d) < 1.0e-14) {
226 return;
227}
228
229// ========================================================================== //
230// RESIZE OUTPUT VARIABLES //
231// ========================================================================== //
232x.resize(n, 0.0);
233
234// ========================================================================== //
235// SOLVE LINEAR SYSTEM WITH BACKWARD SUBSTITUTION //
236// ========================================================================== //
237for (i = n-1; i >= 0; i--) {
238 sum = 0.0;
239 for(p = n-1; p > i; p--) {
240 sum += A[i][p]*x[p];
241 } //next p
242 x[i] = (B[i] - sum)/A[i][i];
243} //next i
244
245return; };
246
247// -------------------------------------------------------------------------- //
256 std::vector<std::vector<double>> &A,
257 std::vector<double> &B,
258 std::vector<double> &x
259) {
260
261// ========================================================================== //
262// VARIABLES DECLARATION //
263// ========================================================================== //
264
265// Local variables
266int m, n, l;
267double d, sum;
268
269// Counters
270int i, p;
271
272
273// ========================================================================== //
274// CHECK INPUT //
275// ========================================================================== //
276m = A.size();
277if (m == 0) { return; };
278n = A[0].size();
279if (m != n) {
280 return;
281}
282l = B.size();
283if (l == 0) { return; };
284if (l != n) {
285 return;
286}
287
288// ========================================================================== //
289// CHECK SOLVABILITY CONDITION //
290// ========================================================================== //
291d = 1.0;
292for (i = 0; i < n; i++) {
293 d = d*A[i][i];
294} //next i
295if (std::abs(d) < 1.0e-14) {
296 return;
297}
298
299// ========================================================================== //
300// RESIZE OUTPUT VARIABLES //
301// ========================================================================== //
302x.resize(n, 0.0);
303
304// ========================================================================== //
305// FORWARD SUBSTITUTION //
306// ========================================================================== //
307for(i = 0; i < n; i++) {
308 sum = 0.0;
309 for(p = 0; p < i; p++) {
310 sum += A[i][p] * x[p];
311 } //next p
312 x[i] = (B[i] - sum)/A[i][i];
313} //next i
314
315return; };
316
317// -------------------------------------------------------------------------- //
327 std::vector<std::vector<double>> &A,
328 std::vector<double> &B,
329 std::vector<double> &x
330) {
331
332// ========================================================================== //
333// VARIABLES DECLARATION //
334// ========================================================================== //
335
336// Local variables
337unsigned int info;
338std::vector<std::vector<double>> L, U, P, *P_ = &P;
339std::vector<double> z, C;
340
341// Counters
342// none
343
344// ========================================================================== //
345// COMPUTE LU FACTORIZATION //
346// ========================================================================== //
347info = factorizeLU(A, L, U, P_);
348if ((info == 2) || (info == 3)) {
349 return;
350}
351matmul(P, B, C);
352
353// ========================================================================== //
354// SOLVE THE LINEAR SYSTEM //
355// ========================================================================== //
356
357// Forward substitution
358forwardSubstitution(L, C, z);
359
360// Bacward substitution
361backwardSubstitution(U, z, x);
362
363return; };
364
365// -------------------------------------------------------------------------- //
386 int layout,
387 std::vector<double> &A,
388 std::vector<double> &B
389) {
390
391 std::vector<int> ipiv(B.size());
392 int info = solveLU(layout, B.size(), A.data(), B.data(),ipiv.data());
393 return info;
394
395};
396
397// -------------------------------------------------------------------------- //
418 int layout,
419 int matrixOrder,
420 double *A,
421 double *B,
422 int *ipiv
423) {
424
425 int ldb = (layout == constants::ROW_MAJOR ? 1 : matrixOrder);
426 int info = LAPACKE_dgesv(layout, matrixOrder, 1, A, matrixOrder, ipiv, B, ldb);
427 return info;
428
429};
430
435}
436}
void sum(const std::array< T, d > &x, T1 &s)
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)
--- layout: doxygen_footer ---