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