Loading...
Searching...
No Matches
matrix_utilities.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
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
39namespace bitpit{
40
41namespace linearalgebra{
47// -------------------------------------------------------------------------- //
54template<class T>
56 std::ostream &out,
57 std::vector< std::vector< T > > &A
58) {
59
60// ========================================================================== //
61// VARIABLES DECLARATION //
62// ========================================================================== //
63
64// Local variables
65int m = A.size();
66
67// Counters
68int i;
69
70// ========================================================================== //
71// DISPLAY MATRIX CONTENT //
72// ========================================================================== //
73for (i = 0; i < m; ++i) {
74 out << A[i] << std::endl;
75} //next i
76
77return; };
78
79// -------------------------------------------------------------------------- //
87template<class T, size_t m, size_t n>
89 std::ostream &out,
90 std::array<std::array<T, n>, m> &A
91) {
92
93// ========================================================================== //
94// VARIABLES DECLARATION //
95// ========================================================================== //
96
97// Local variables
98// none
99
100// Counters
101size_t i;
102
103// ========================================================================== //
104// DISPLAY MATRIX CONTENT //
105// ========================================================================== //
106for (i = 0; i < m; ++i) {
107 out << A[i] << std::endl;
108} //next i
109
110return; };
111
112// -------------------------------------------------------------------------- //
122template<class T>
124 std::ostream &out,
125 T *A,
126 int nRows,
127 int nCols
128) {
129 for (int i = 0; i < nRows; ++i) {
130 for (int j = 0; j < nCols; ++j) {
131 out << A[linearIndexColMajor(i, j, nRows, nCols)] << " ";
132 }
133 out << std::endl;
134 }
135}
136
137// -------------------------------------------------------------------------- //
147template<class T>
149 std::ostream &out,
150 T *A,
151 int nRows,
152 int nCols
153) {
154 for (int i = 0; i < nRows; ++i) {
155 for (int j = 0; j < nCols; ++j) {
156 out << A[linearIndexRowMajor(i, j, nRows, nCols)] << " ";
157 }
158 out << std::endl;
159 }
160}
161
162// -------------------------------------------------------------------------- //
174template<class T>
176 std::ostream &out, T *A,
177 int nRows,
178 int nCols,
179 char uplo
180) {
181 assert(uplo=='L' || uplo=='U');
182
183 for (int i = 0; i < nRows; ++i) {
184 for (int j = 0; j < nCols; ++j) {
185 out << A[linearIndexColMajorSymmetric(i, j, nRows, nCols, uplo)] << " ";
186 }
187 out << std::endl;
188 }
189}
190
191// -------------------------------------------------------------------------- //
203template<class T>
205 std::ostream &out,
206 T *A,
207 int nRows,
208 int nCols,
209 char uplo
210) {
211 assert(uplo=='L' || uplo=='U');
212
213 for (int i = 0; i < nRows; ++i) {
214 for (int j = 0; j < nCols; ++j) {
215 out << A[linearIndexRowMajorSymmetric(i, j, nRows, nCols, uplo)] << " ";
216 }
217 out << std::endl;
218 }
219}
220
230// -------------------------------------------------------------------------- //
239template <class T>
241 int i,
242 int j,
243 std::vector< std::vector< T > > &A,
244 std::vector< std::vector< T > > &B
245) {
246
247// ========================================================================== //
248// VARIABLES DECLARATION //
249// ========================================================================== //
250
251// Local variables
252int m, n;
253
254// Counters
255int l, k;
256
257// ========================================================================== //
258// CHECK INPUT //
259// ========================================================================== //
260m = A.size();
261if (m == 0) { return; }
262n = A[0].size();
263if (n == 0) { return; }
264if ((i >= m) || (i < 0)) {
265 return;
266}
267if ((j >= n) || (j < 0)) {
268 return;
269}
270
271// ========================================================================== //
272// EXTRACT COMPLEMENT //
273// ========================================================================== //
274
275// Resize output variables
276B.resize(m-1);
277for (int p = 0; p < m-1; ++p) {
278 B[p].resize(n-1, T{});
279} //next p
280
281// Extract complement
282for (l = 0; l < i; l++) {
283 for (k = 0; k < j; k++) {
284 B[l][k] = A[l][k];
285 } //next k
286 for (k = j+1; k < n; k++) {
287 B[l][k-1] = A[l][k];
288 } //next k
289} //next l
290for (l = i+1; l < m; l++) {
291 for (k = 0; k < j; k++) {
292 B[l-1][k] = A[l][k];
293 } //next k
294 for (k = j+1; k < n; k++) {
295 B[l-1][k-1] = A[l][k];
296 } //next k
297} //next l
298
299return; };
300
301// -------------------------------------------------------------------------- //
311template <class T, size_t m, size_t n>
313 int i,
314 int j,
315 std::array< std::array< T, n >, m > &A,
316 std::array< std::array<T, n-1>, m-1> &B
317) {
318
319// ========================================================================== //
320// VARIABLES DECLARATION //
321// ========================================================================== //
322
323// Local variables
324// none
325
326// Counters
327int l, k;
328
329// ========================================================================== //
330// CHECK INPUT //
331// ========================================================================== //
332if (m == 0) { return; }
333if (n == 0) { return; }
334if ((i >= (long) m) || (i < 0)) {
335 return;
336}
337if ((j >= (long) n) || (j < 0)) {
338 return;
339}
340
341// ========================================================================== //
342// EXTRACT COMPLEMENT //
343// ========================================================================== //
344for (l = 0; l < i; l++) {
345 for (k = 0; k < j; k++) {
346 B[l][k] = A[l][k];
347 } //next k
348 for (k = j+1; k < (long) n; k++) {
349 B[l][k-1] = A[l][k];
350 } //next k
351} //next l
352for (l = i+1; l < (long) m; l++) {
353 for (k = 0; k < j; k++) {
354 B[l-1][k] = A[l][k];
355 } //next k
356 for (k = j+1; k < (long) n; k++) {
357 B[l-1][k-1] = A[l][k];
358 } //next k
359} //next l
360
361return; };
362
372// -------------------------------------------------------------------------- //
380template <class T>
381void zeros(
382 std::vector< std::vector < T > > &A,
383 int m,
384 int n
385) {
386
387// ========================================================================== //
388// VARIABLES DECLARATION //
389// ========================================================================== //
390
391// Local variables
392// none
393
394// Counters
395int i, j;
396
397// ========================================================================== //
398// CHECK INPUT //
399// ========================================================================== //
400if ((m == 0) || (n == 0)) {
401 return;
402}
403
404// ========================================================================== //
405// CREATE MATRIX //
406// ========================================================================== //
407A.resize(m);
408for (i = 0; i < m; i++) {
409 A[i].resize(n, (T) 0.0);
410 for (j = 0; j < n; j++) {
411 A[i][j] = (T) 0.0;
412 } //next j
413} //next i
414
415return; };
416
417// -------------------------------------------------------------------------- //
427template <class T, size_t m, size_t n>
428void zeros(
429 std::array< std::array < T, n >, m > &A
430) {
431
432// ========================================================================== //
433// template <class T, size_t m, size_t n> //
434// void zeros( //
435// array< array < T, n >, m > &A) //
436// //
437// Initialize a m-by-n matrix of zeros. //
438// ========================================================================== //
439// INPUT //
440// ========================================================================== //
441// - A : array< array< T, n >, m >, with m-by-n matrix of zeros //
442// - none //
443// ========================================================================== //
444// OUTPUT //
445// ========================================================================== //
446// - none //
447// ========================================================================== //
448
449// ========================================================================== //
450// VARIABLES DECLARATION //
451// ========================================================================== //
452
453// Local variables
454// none
455
456// Counters
457size_t i;
458
459// ========================================================================== //
460// CHECK INPUT //
461// ========================================================================== //
462if ((m == 0) || (n == 0)) {
463 return;
464}
465
466// ========================================================================== //
467// CREATE MATRIX //
468// ========================================================================== //
469for (i = 0; i < m; i++) {
470 A[i].fill(0.0);
471} //next i
472
473return; };
474
475// -------------------------------------------------------------------------- //
483template <class T>
484void ones(
485 std::vector< std::vector < T > > &A,
486 int m,
487 int n
488) {
489
490// ========================================================================== //
491// VARIABLES DECLARATION //
492// ========================================================================== //
493
494// Local variables
495// none
496
497// Counters
498int i, j;
499
500// ========================================================================== //
501// CHECK INPUT //
502// ========================================================================== //
503if ((m == 0) || (n == 0)) {
504 std::cout << "ERROR: number of rows (columns) must be > 0!!" << std::endl;
505}
506
507// ========================================================================== //
508// CREATE MATRIX //
509// ========================================================================== //
510A.resize(m);
511for (i = 0; i < m; i++) {
512 A[i].resize(n, (T) 1.0);
513 for (j = 0; j < n; j++) {
514 A[i][j] = (T) 1.0;
515 } //next j
516} //next i
517
518return; };
519
520// -------------------------------------------------------------------------- //
530template <class T, size_t m, size_t n>
531void ones(
532 std::array< std::array < T, n >, m > &A
533) {
534
535// ========================================================================== //
536// VARIABLES DECLARATION //
537// ========================================================================== //
538
539// Local variables
540// none
541
542// Counters
543size_t i;
544
545// ========================================================================== //
546// CHECK INPUT //
547// ========================================================================== //
548if ((m == 0) || (n == 0)) {
549 return;
550}
551
552// ========================================================================== //
553// CREATE MATRIX //
554// ========================================================================== //
555for (i = 0; i < m; i++) {
556 A[i].fill(1.0);
557} //next i
558
559return; };
560
561// -------------------------------------------------------------------------- //
570template <class T>
571void eye(
572 std::vector< std::vector < T > > &A,
573 int m,
574 int n
575) {
576
577// ========================================================================== //
578// VARIABLES DECLARATION //
579// ========================================================================== //
580
581// Local variables
582int s = std::min(m, n);
583
584// Counters
585int i;
586
587// ========================================================================== //
588// CHECK INPUT //
589// ========================================================================== //
590if ((m == 0) || (n == 0)) {
591 return;
592}
593
594// ========================================================================== //
595// CREATE MATRIX //
596// ========================================================================== //
597zeros(A, m, n);
598for (i = 0; i < s; i++) {
599 A[i][i] = (T) 1.0;
600} //next i
601
602return; };
603
604// -------------------------------------------------------------------------- //
614template <class T, size_t m, size_t n>
615void eye(
616 std::array< std::array < T, n >, m > &A
617) {
618
619// ========================================================================== //
620// VARIABLES DECLARATION //
621// ========================================================================== //
622
623// Local variables
624int s = std::min(m, n);
625
626// Counters
627int i;
628
629// ========================================================================== //
630// CHECK INPUT //
631// ========================================================================== //
632if ((m == 0) || (n == 0)) {
633 return;
634}
635
636// ========================================================================== //
637// CREATE MATRIX //
638// ========================================================================== //
639zeros(A);
640for (i = 0; i < s; i++) {
641 A[i][i] = (T) 1.0;
642} //next i
643
644return; };
645
651// Matrix determinant ======================================================= //
652
658// -------------------------------------------------------------------------- //
665template <class T>
667 std::array< std::array< T, 1 >, 1 > &A
668) {
669
670return(A[0][0]); };
671
672// -------------------------------------------------------------------------- //
679template <class T>
681 std::vector< std::vector < T > > &A
682) {
683
684// ========================================================================== //
685// VARIABLES DECLARATION //
686// ========================================================================== //
687
688// Local variables
689int m, n;
690T d = (T) 1.0e+18;
691std::vector< std::vector < T > > C;
692
693// ========================================================================== //
694// CHECK INPUT //
695// ========================================================================== //
696m = A.size();
697if (m == 0) { return(d); };
698n = A[0].size();
699if (n == 0) { return(d); };
700if (m != n) {
701 return(d);
702}
703
704// ========================================================================== //
705// COMPUTE DETERMINANT //
706// ========================================================================== //
707if (m == 1) {
708 d = A[0][0];
709}
710else if (m == 2) {
711 d = A[0][0]*A[1][1] - A[0][1]*A[1][0];
712}
713else if (m == 3) {
714 d = A[0][0]*A[1][1]*A[2][2] - A[0][0]*A[1][2]*A[2][1]
715 + A[0][1]*A[1][2]*A[2][0] - A[0][1]*A[1][0]*A[2][2]
716 + A[0][2]*A[1][0]*A[2][1] - A[0][2]*A[1][1]*A[2][0];
717}
718else {
719 d = (T) 0.0;
720 for (int i = 0; i < m; i++) {
721 complement(0, i, A, C);
722 d += pow(-1.0, i) * A[0][i] * det(C);
723 } //next i
724}
725
726return(d); };
727
728// -------------------------------------------------------------------------- //
738template <class T, size_t m, size_t n>
740 std::array< std::array < T, n >, m > &A
741) {
742
743// ========================================================================== //
744// VARIABLES DECLARATION //
745// ========================================================================== //
746
747// Local variables
748T d = (T) 0.0;
749
750// Counters
751int i;
752
753// ========================================================================== //
754// CHECK INPUT //
755// ========================================================================== //
756if (m == 0) { return(d); };
757if (n == 0) { return(d); };
758if (m != n) {
759 return(d);
760}
761
762// ========================================================================== //
763// COMPUTE DETERMINANT //
764// ========================================================================== //
765if (m == 1) {
766 d = A[0][0];
767}
768else if (m == 2) {
769 d = A[0][0]*A[1][1] - A[0][1]*A[1][0];
770}
771else if (m == 3) {
772 d = A[0][0]*A[1][1]*A[2][2] - A[0][0]*A[1][2]*A[2][1]
773 + A[0][1]*A[1][2]*A[2][0] - A[0][1]*A[1][0]*A[2][2]
774 + A[0][2]*A[1][0]*A[2][1] - A[0][2]*A[1][1]*A[2][0];
775}
776else {
777 std::array< std::array < double, m-1 >, m-1 > C;
778 for (i = 0; i < m; i++) {
779 complement(0, i, A, C);
780 d += pow(-1.0, i) * A[0][i] * det(C);
781 } //next i
782}
783
784return(d); };
785
786
790}
791
792}
std::array< T, d > pow(std::array< T, d > &x, double p)
int linearIndexRowMajor(int row, int col, int nRows, int nCols)
void complement(int, int, std::vector< std::vector< T > > &, std::vector< std::vector< T > > &)
int linearIndexColMajorSymmetric(int row, int col, int nRows, int nCols, char uplo)
int linearIndexRowMajorSymmetric(int row, int col, int nRows, int nCols, char uplo)
int linearIndexColMajor(int row, int col, int nRows, int nCols)
void displayColMajorSymmetric(std::ostream &out, T *A, int nRows, int nCols, char uplo)
void displayColMajor(std::ostream &out, T *A, int nRows, int nCols)
void display(std::ostream &, std::vector< std::vector< T > > &)
void displayRowMajorSymmetric(std::ostream &out, T *A, int nRows, int nCols, char uplo)
void displayRowMajor(std::ostream &out, T *A, int nRows, int nCols)
T det(std::vector< std::vector< T > > &)
void zeros(std::vector< std::vector< T > > &, int, int)
void ones(std::vector< std::vector< T > > &, int, int)
void eye(std::vector< std::vector< T > > &, int, int)
--- layout: doxygen_footer ---