Flow123d
matrix.cpp
Go to the documentation of this file.
1 #include <cmath>
2 #include "system/exc_common.hh"
5 //#include "mesh/ngh/include/system.h"
6 //#include "mesh/ngh/include/problem.h"
7 //#include <math.h>
8 
9 using namespace mathfce;
10 
11 TMatrix::TMatrix(int size) {
12  nc = size;
13  nr = size;
14  elm = new double[ nc * nr ];
15 }
16 
17 TMatrix::TMatrix(int num_rows, int num_cols) {
18  nc = num_cols;
19  nr = num_rows;
20  elm = new double[ nc * nr ];
21 }
22 
24 {
25  nc = x.nc;
26  nr = x.nr;
27  elm = new double[nc*nr];
28  memcpy(elm,x.elm,nc*nr*sizeof(double));
29 }
30 
32  delete[] elm;
33 }
34 
35 TMVector::TMVector(int size) {
36  this->size = size;
37  elm = new double[size];
38 }
39 
41 {
42  size=x.size;
43  elm = new double[size];
44  memcpy(elm,x.elm,size*sizeof(double));
45 }
46 
48  delete[] elm;
49 }
50 
51 std::ostream & operator <<(std::ostream& stream, const TMatrix& M) {
52  for (int i = 1; i <= M.nr; i++) {
53  for (int j = 1; j <= M.nc; j++) {
54  stream << M.Get(i, j) << " ";
55  }
56  stream << "\n";
57  }
58  return stream;
59 }
60 
61 std::ostream & operator <<(std::ostream& stream, const TMVector& V) {
62  for (int i = 1; i <= V.size; i++) {
63  stream << V.elm[ i - 1 ] << "\n";
64  }
65  return stream;
66 }
67 
68 void TMatrix::Set(int row, int col, double value) {
69  if (row > nr)
70  THROW( ExcAssertMsg() << EI_Message( "Number of the row is greater than number of rows in the matrix.") );
71  if (col > nc)
72  THROW( ExcAssertMsg() << EI_Message( "Number of the column is greater than number of columns in the matrix.") );
73  elm[ (row - 1) * nc + col - 1 ] = value;
74  return;
75 }
76 
77 double TMatrix::Get(int row, int col) const {
78  if (row > nr)
79  THROW( ExcAssertMsg() << EI_Message( "Number of the row is greater than number of rows in the matrix.") );
80  if (col > nc)
81  THROW( ExcAssertMsg() << EI_Message( "Number of the column is greater than number of columns in the matrix.") );
82  return elm[ (row - 1) * nc + col - 1 ];
83 }
84 
85 void TMatrix::SwapRows(int r1, int r2) {
86  if (r1 > nr || r2 > nr) {
87  THROW( ExcAssertMsg() << EI_Message( "Number of the row is greater than number of rows in the matrix.") );
88  }
89 
90  for (int i = 1; i <= nc; i++) {
91  double tmp = Get(r1, i);
92  Set(r1, i, Get(r2, i));
93  Set(r2, i, tmp);
94  }
95 
96  return;
97 }
98 
99 void TMVector::SwapElements(int i1, int i2) {
100  if (i1 > size || i2 > size) {
101  THROW( ExcAssertMsg() << EI_Message( "Number of the element is greater than size of the vector.") );
102  }
103 
104  double tmp = elm[ i1 - 1 ];
105  elm[ i1 - 1 ] = elm[ i2 - 1 ];
106  elm[ i2 - 1 ] = tmp;
107 
108  return;
109 }
110 
111 double TMVector::Get(int i) {
112  if (i > size) {
113  THROW( ExcAssertMsg() << EI_Message("Number of the element is greater than size of the vector.") );
114  }
115 
116 
117  return elm[ i - 1 ];
118 }
119 
120 void TMVector::Set(int i, double value) {
121  if (i > size)
122  THROW( ExcAssertMsg() << EI_Message("Number of the element is greater than size of the vector.") );
123  elm[ i - 1 ] = value;
124  return;
125 }
126 
127 int TMatrix::NRows() const {
128  return nr;
129 }
130 
131 int TMatrix::NCols() const {
132  return nc;
133 }
134 
135 TNSolutions Gauss(const TMatrix& A, TMVector* X, const TMVector& B) {
136  TMatrix M(A);
137  TMVector b(B);
138 // TNSolutions ns;
139 
140  for (int i = 1; i < M.NRows(); i++) {
141  double tmp = fabs(M.Get(i, i));
142  int row = -1;
143  for (int j = i + 1; j <= M.NRows(); j++)
144  if (fabs(M.Get(j, i)) > tmp) {
145  tmp = fabs(M.Get(j, i));
146  row = j;
147  }
148  if (tmp < epsilon) {
149  // return badconditioned;
150  continue;
151  }
152 
153  if (row != -1) {
154  M.SwapRows(i, row);
155  b.SwapElements(i, row);
156  }
157 
158  for (int j = i + 1; j <= M.NRows(); j++) {
159  tmp = M.Get(j, i) / M.Get(i, i);
160  for (int k = i; k <= M.NCols(); k++) {
161  M.Set(j, k, M.Get(j, k) - tmp * M.Get(i, k));
162  }
163  b.Set(j, b.Get(j) - tmp * b.Get(i));
164  }
165  }
166 
167  for (int i = M.NRows(); i >= 1; i--) {
168  double tmp = b.Get(i);
169 
170  for (int k = i + 1; k <= M.NCols(); k++) {
171  tmp -= M.Get(i, k) * X->Get(k);
172  }
173 
174  if (IsZero(M.Get(i, i))) {
175  if (IsZero(tmp)) {
176  return inf_solutions;
177  } else {
178  return no_solution;
179  }
180  }
181 
182  X->Set(i, tmp / M.Get(i, i));
183  }
184 
185  return one_solution;
186 }