LinearAlgebra.cc
Go to the documentation of this file.
1 #include "LinearAlgebra.h"
2 
3 #include <iostream>
4 #include <string>
5 #include <iomanip>
6 #include <sstream>
7 
8 #include <cmath>
9 #include <limits>
10 
11 
12 namespace FdEnergyDepositFinderKG {
13 
14  void
16  {
17  fill(fElements.begin(), fElements.end(), 0);
18  }
19 
20 
21  unsigned int
23  const
24  {
25  return 0.5*(sqrt(1 + 8*fElements.size()) - 1);
26  }
27 
28 
31  const
32  {
33  const unsigned int n = GetSize();
34  //std::cout << "Matrix size: " << n << "Column vector size: " << rhs.GetSize() << std::endl;
35 
36  if (!n) { // hack for "only direct light" case to avoit too many ifs in CalculateProfile
37  ColumnVector zero(rhs.GetSize());
38  zero.Zero();
39  return zero;
40  }
41  if (n != rhs.GetSize())
42  throw utl::OutOfBoundException("operator* size mismatch");
43  ColumnVector retval(n);
44 
45  for (unsigned int row = 0; row < n; ++row) {
46  const double* const rowArray = &fElements[(row*(row+1))/2];
47  double sum = 0;
48  for (unsigned int col = 0; col <= row; ++col)
49  sum += rowArray[col] * rhs.fElements[col];
50  retval.fElements[row] = sum;
51  }
52 
53  return retval;
54  }
55 
56 
59  const
60  {
61  const unsigned int n = GetSize();
62  if (n != rhs.GetSize())
63  throw utl::OutOfBoundException("operator+ size mismatch");
64  LowerTriangularMatrix retval(n);
65 
66  for (unsigned int row = 0; row < n; ++row) {
67  const unsigned int idx_row = (row*(row+1))/2;
68  for (unsigned int col = 0; col <= row; ++col) {
69  const unsigned int idx = idx_row + col;
70  retval.fElements[idx] = fElements[idx] + rhs.fElements[idx];
71  }
72  }
73  return retval;
74  }
75 
76 
79  const
80  {
81  const unsigned int n = GetSize();
82 
83  // some abbreviatons ...
84  const LowerTriangularMatrix& t = *this;
86 
87  const double epsilon = std::numeric_limits<double>::epsilon();
88 
89  // first calculate diagonal elements ...
90  for (unsigned int i = 0; i < n; ++i) {
91  const double tmp = t(i, i);
92  if (fabs(tmp) > epsilon)
93  r(i, i) = 1/tmp;
94  else {
95  std::ostringstream errMsg;
96  errMsg << "singular lower triangular matrix "
97  "diagonal element " << i << " too small: "
98  << tmp;
99  throw SingularMatrixException(errMsg.str());
100  }
101  }
102 
103  // ... then off diagonal
104  for (unsigned int i = 1; i < n; ++i) {
105  double diag = t(i, i);
106  for (unsigned int k = 0; k < i; ++k) {
107  double sum = 0;
108  for (unsigned int j = k; j < i; ++j)
109  sum += t(i, j) * r(j, k);
110  r(i, k) = -sum/diag;
111  }
112  }
113 
114  return r;
115  }
116 
117 
118  void
120  const
121  {
122  std::ostringstream dump;
123  dump << std::resetiosflags(std::ios::scientific)
124  << std::setiosflags(std::ios::fixed) << std::setprecision(2)
125  << std::setfill(' ');
126  const unsigned int n = GetSize();
127  dump << "LowerTriangularMatrix(" << n << "):\n";
128  for (unsigned int row = 0; row < n; ++row) {
129  dump << "[ ";
130  for (unsigned int col = 0; col < n; ++col) {
131  dump << std::setw(8);
132  if (row >= col)
133  dump << (*this)(row, col) << " ";
134  else
135  dump << 0 << " ";
136  }
137  dump << " ]\n";
138  }
139  std::cout << dump.str() << std::flush;
140  }
141 
142 
145  const
146  {
147  const unsigned int n = GetSize();
148  if (n != rhs.GetSize())
149  throw utl::OutOfBoundException("operator+ size mismatch");
150  LowerTriangularMatrix retval(*this);
151 
152  for (unsigned int row = 0; row < n; ++row) {
153  const unsigned int idx = (row*(row+1))/2 + row;
154 
155  retval.fElements[idx] += rhs.fElements[row];
156  }
157  return retval;
158  }
159 
160 
161  /**************************************************************/
162 
163  const double&
164  DiagonalMatrix::operator()(const int row, const int col)
165  const
166  {
167  if (row != col)
168  throw utl::OutOfBoundException("operator(i, j): i != j");
169  return fElements[row];
170  }
171 
172 
173  double&
174  DiagonalMatrix::operator()(const int row, const int col)
175  {
176  if (row != col)
177  throw utl::OutOfBoundException("operator(i, j): i != j");
178  return fElements[row];
179  }
180 
181 
182  void
184  {
185  fill(fElements.begin(), fElements.end(), 0);
186  }
187 
188 
189  void
191  const
192  {
193  std::ostringstream dump;
194  dump << std::resetiosflags(std::ios::scientific)
195  << std::setiosflags(std::ios::fixed) << std::setprecision(2)
196  << std::setfill(' ');
197  const unsigned int n = GetSize();
198  dump << "DiagonalMatrix(" << n << "):\n";
199  for (unsigned int row = 0; row < n; ++row) {
200  dump << "[ ";
201  for (unsigned int col = 0; col < n; ++col) {
202  dump << std::setw(8);
203  if (row == col)
204  dump << (*this)(row) << ' ';
205  else
206  dump << "0 ";
207  }
208  dump << " ]\n";
209  }
210  std::cout << dump.str() << std::flush;
211  }
212 
213 
216  const
217  {
218  const unsigned int n = GetSize();
219  if (n != rhs.GetSize())
220  throw utl::OutOfBoundException("operator+ size mismatch");
221  DiagonalMatrix retval(n);
222 
223  for (unsigned int row = 0; row < n; ++row)
224  retval.fElements[row] = fElements[row] + rhs.fElements[row];
225 
226  return retval;
227  }
228 
229 
232  const
233  {
234  const unsigned int n = GetSize();
235  if (n != rhs.GetSize())
236  throw utl::OutOfBoundException("operator* size mismatch");
237  ColumnVector retval(n);
238 
239  for (unsigned int row = 0; row < n; ++row)
240  retval.fElements[row] = fElements[row] * rhs.fElements[row];
241 
242  return retval;
243  }
244 
245 
248  const
249  {
250  const unsigned int n = GetSize();
251 
252  // some abbreviatons ...
253  const DiagonalMatrix& t = *this;
254  DiagonalMatrix r(n);
255 
256  const double epsilon = std::numeric_limits<double>::epsilon();
257 
258  // calculate diagonal elements ...
259  for (unsigned int i = 0; i < n; ++i) {
260  const double tmp = t(i, i);
261  if (fabs(tmp) > epsilon)
262  r(i, i) = 1/tmp;
263  else {
264  std::ostringstream errMsg;
265  errMsg << "singular diagonal matrix "
266  "element " << i << " too small: "
267  << tmp;
268  throw SingularMatrixException(errMsg.str());
269  }
270  }
271 
272  return r;
273  }
274 
275 
276  /**************************************************************/
277 
280  const
281  {
282  const unsigned int n = GetSize();
283  if (n != rhs.GetSize())
284  throw utl::OutOfBoundException("operator+ size mismatch");
285 
286  ColumnVector retval(n);
287  for (unsigned int row = 0; row < n; ++row)
288  retval.fElements[row] = fElements[row] + rhs.fElements[row];
289  return retval;
290  }
291 
292 
293  void
295  {
296  fill(fElements.begin(), fElements.end(), 0);
297  }
298 
299 }
const double & operator()(const int row, const int col) const
Read-only access to a matrix element.
void Zero()
Set all elements to 0.
ColumnVector operator*(const ColumnVector &rhs) const
void diag(const std::string &msg)
Definition: testlib.cc:59
LowerTriangularMatrix operator+(const LowerTriangularMatrix &rhs) const
Exception for reporting variable out of valid range.
ColumnVector operator+(const ColumnVector &rhs) const
void Zero()
Set all elements to 0.
LowerTriangularMatrix GetInverse() const
Get the inverse of the matrix.
void Print() const
Dump ASCII representation to STDOUT (for debugging)
ColumnVector operator*(const ColumnVector &rhs) const
DiagonalMatrix operator+(const DiagonalMatrix &rhs) const
void Print() const
Dump ASCII representation to STDOUT (for debugging)

, generated on Tue Sep 26 2023.