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