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