Flow123d  release_2.2.0-914-gf1a3a4f
matrix.cpp
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file matrix.cpp
15  * @brief
16  */
17 
18 #include <cmath>
19 #include <cstring>
20 #include "system/exc_common.hh"
23 
24 using namespace mathfce;
25 
26 namespace ngh {
27 
28 TMatrix::TMatrix(int size) {
29  nc = size;
30  nr = size;
31  elm = new double[ nc * nr ];
32 }
33 
34 TMatrix::TMatrix(int num_rows, int num_cols) {
35  nc = num_cols;
36  nr = num_rows;
37  elm = new double[ nc * nr ];
38 }
39 
40 TMatrix::TMatrix(const TMatrix & x)
41 {
42  nc = x.nc;
43  nr = x.nr;
44  elm = new double[nc*nr];
45  memcpy(elm,x.elm,nc*nr*sizeof(double));
46 }
47 
48 TMatrix::~TMatrix() {
49  delete[] elm;
50 }
51 
52 TMVector::TMVector(int size) {
53  this->size = size;
54  elm = new double[size];
55 }
56 
57 TMVector::TMVector(const TMVector & x)
58 {
59  size=x.size;
60  elm = new double[size];
61  memcpy(elm,x.elm,size*sizeof(double));
62 }
63 
64 TMVector::~TMVector() {
65  delete[] elm;
66 }
67 
68 std::ostream & operator <<(std::ostream& stream, const TMatrix& M) {
69  for (int i = 1; i <= M.nr; i++) {
70  for (int j = 1; j <= M.nc; j++) {
71  stream << M.Get(i, j) << " ";
72  }
73  stream << "\n";
74  }
75  return stream;
76 }
77 
78 std::ostream & operator <<(std::ostream& stream, const TMVector& V) {
79  for (int i = 1; i <= V.size; i++) {
80  stream << V.elm[ i - 1 ] << "\n";
81  }
82  return stream;
83 }
84 
85 void TMatrix::Set(int row, int col, double value) {
86  if (row > nr)
87  THROW( ExcAssertMsg() << EI_Message( "Number of the row is greater than number of rows in the matrix.") );
88  if (col > nc)
89  THROW( ExcAssertMsg() << EI_Message( "Number of the column is greater than number of columns in the matrix.") );
90  elm[ (row - 1) * nc + col - 1 ] = value;
91  return;
92 }
93 
94 double TMatrix::Get(int row, int col) const {
95  if (row > nr)
96  THROW( ExcAssertMsg() << EI_Message( "Number of the row is greater than number of rows in the matrix.") );
97  if (col > nc)
98  THROW( ExcAssertMsg() << EI_Message( "Number of the column is greater than number of columns in the matrix.") );
99  return elm[ (row - 1) * nc + col - 1 ];
100 }
101 
102 void TMatrix::SwapRows(int r1, int r2) {
103  if (r1 > nr || r2 > nr) {
104  THROW( ExcAssertMsg() << EI_Message( "Number of the row is greater than number of rows in the matrix.") );
105  }
106 
107  for (int i = 1; i <= nc; i++) {
108  double tmp = Get(r1, i);
109  Set(r1, i, Get(r2, i));
110  Set(r2, i, tmp);
111  }
112 
113  return;
114 }
115 
116 void TMVector::SwapElements(int i1, int i2) {
117  if (i1 > size || i2 > size) {
118  THROW( ExcAssertMsg() << EI_Message( "Number of the element is greater than size of the vector.") );
119  }
120 
121  double tmp = elm[ i1 - 1 ];
122  elm[ i1 - 1 ] = elm[ i2 - 1 ];
123  elm[ i2 - 1 ] = tmp;
124 
125  return;
126 }
127 
128 double TMVector::Get(int i) {
129  if (i > size) {
130  THROW( ExcAssertMsg() << EI_Message("Number of the element is greater than size of the vector.") );
131  }
132 
133 
134  return elm[ i - 1 ];
135 }
136 
137 void TMVector::Set(int i, double value) {
138  if (i > size)
139  THROW( ExcAssertMsg() << EI_Message("Number of the element is greater than size of the vector.") );
140  elm[ i - 1 ] = value;
141  return;
142 }
143 
144 int TMatrix::NRows() const {
145  return nr;
146 }
147 
148 int TMatrix::NCols() const {
149  return nc;
150 }
151 
152 TNSolutions Gauss(const TMatrix& A, TMVector* X, const TMVector& B) {
153  TMatrix M(A);
154  TMVector b(B);
155 
156  for (int i = 1; i < M.NRows(); i++) {
157  double tmp = fabs(M.Get(i, i));
158  int row = -1;
159  for (int j = i + 1; j <= M.NRows(); j++)
160  if (fabs(M.Get(j, i)) > tmp) {
161  tmp = fabs(M.Get(j, i));
162  row = j;
163  }
164  if (tmp < epsilon) {
165  continue;
166  }
167 
168  if (row != -1) {
169  M.SwapRows(i, row);
170  b.SwapElements(i, row);
171  }
172 
173  for (int j = i + 1; j <= M.NRows(); j++) {
174  tmp = M.Get(j, i) / M.Get(i, i);
175  for (int k = i; k <= M.NCols(); k++) {
176  M.Set(j, k, M.Get(j, k) - tmp * M.Get(i, k));
177  }
178  b.Set(j, b.Get(j) - tmp * b.Get(i));
179  }
180  }
181 
182  for (int i = M.NRows(); i >= 1; i--) {
183  double tmp = b.Get(i);
184 
185  for (int k = i + 1; k <= M.NCols(); k++) {
186  tmp -= M.Get(i, k) * X->Get(k);
187  }
188 
189  if (IsZero(M.Get(i, i))) {
190  if (IsZero(tmp)) {
191  return inf_solutions;
192  } else {
193  return no_solution;
194  }
195  }
196 
197  X->Set(i, tmp / M.Get(i, i));
198  }
199 
200  return one_solution;
201 }
202 
203 } //namespace ngh
void Set(int, int, double)
Definition: matrix.cpp:85
int nr
Definition: matrix.h:37
Definition: abscissa.h:25
int NRows() const
Definition: matrix.cpp:144
bool IsZero(double)
Definition: mathfce.cpp:22
TNSolutions
Definition: matrix.h:26
void SwapRows(int, int)
Definition: matrix.cpp:102
static constexpr bool value
Definition: json.hpp:87
int nc
Definition: matrix.h:36
double * elm
Definition: matrix.h:39
double Get(int)
Definition: matrix.cpp:128
void Set(int, double)
Definition: matrix.cpp:137
TNSolutions Gauss(const TMatrix &, TMVector *, const TMVector &)
Definition: matrix.cpp:152
const double epsilon
Definition: mathfce.h:23
std::ostream & operator<<(std::ostream &stream, const TMVector &V)
Definition: matrix.cpp:78
int NCols() const
Definition: matrix.cpp:148
double * elm
Definition: matrix.h:62
double Get(int, int) const
Definition: matrix.cpp:94
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Definition: exceptions.hh:53
int size
Definition: matrix.h:60
void SwapElements(int, int)
Definition: matrix.cpp:116