API Documentation
Loading...
Searching...
No Matches
BandMatrix.hpp
Go to the documentation of this file.
1#pragma once
2#include <NDEVR/Buffer.h>
3#include <NDEVR/Vertex.h>
4namespace NDEVR
5{
6 /**--------------------------------------------------------------------------------------------------
7 Class: BandMatrix
8
9 \brief Band Matrix solver
10 *-----------------------------------------------------------------------------------------------**/
11 template<class t_type>
13 {
14 private:
15 Buffer<Buffer<t_type>> m_upper; // upper band
16 Buffer<Buffer<t_type>> m_lower; // lower band
17 public:
18 BandMatrix() {}; // constructor
19 ~BandMatrix() {}; // matrix dimension
21 {
22 return m_upper.size() - 1;
23 }
25 {
26 return m_lower.size() - 1;
27 }
29 {
30 resize(dim, n_u, n_l);
31 }
32 void resize(uint04 dim, uint04 n_u, uint04 n_l)
33 {
34 lib_assert(dim > 0U, "dim > 0");
35 m_upper.setSize(n_u + 1);
36 m_lower.setSize(n_l + 1);
37 for (uint04 i = 0; i < m_upper.size(); i++)
38 m_upper[i].setSize(dim);
39 for (uint04 i = 0; i < m_lower.size(); i++)
40 m_lower[i].setSize(dim);
41 }
42 uint04 dim() const
43 {
44 if (m_upper.size() > 0)
45 return m_upper[0].size();
46 else
47 return 0;
48 }
49 // defines the new operator (), so that we can access the elements
50 // by A(i,j), index going from i=0,...,dim()-1
52 {
53 if (j >= i)
54 return m_upper[j - i][i];
55 else
56 return m_lower[i - j][i];
57 }
58 t_type operator() (uint04 i, uint04 j) const
59 {
60 if (j >= i)
61 return m_upper[j - i][i];
62 else
63 return m_lower[i - j][i];
64 }
65 // second diag (used in LU decomposition), saved in m_lower
66 t_type savedDiag(uint04 i) const
67 {
68 lib_assert(i < dim(), "Bad band location");
69 return m_lower[0][i];
70 }
71 t_type& savedDiag(uint04 i)
72 {
73 lib_assert(i < dim(), "Bad band location");
74 return m_lower[0][i];
75 }
76
77 // LR-Decomposition of a band matrix
79 {
80 for (uint04 i = 0; i < dim(); i++)
81 {
82 lib_assert((*this)(i, i) != 0.0, "Bad decompision");
83 savedDiag(i) = 1.0 / (*this)(i, i);
84 uint04 j_min = getMax(0U, i - lowerCount());
85 uint04 j_max = getMin(dim() - 1, i + upperCount());
86 for (uint04 j = j_min; j <= j_max; j++)
87 (*this)(i, j) *= savedDiag(i);
88 (*this)(i, i) = 1.0; // prevents rounding errors
89 }
90
91 // Gauss LR-Decomposition
92 for (uint04 k = 0; k < dim(); k++)
93 {
94 uint04 i_max = getMin(dim() - 1, k + lowerCount()); // lowerCount not a mistake!
95 for (uint04 i = k + 1; i <= i_max; i++)
96 {
97 lib_assert((*this)(k, k) != 0.0, "get minimum");
98 t_type x = -(*this)(i, k) / (*this)(k, k);
99 (*this)(i, k) = -x; // assembly part of L
100 uint04 j_max = getMin(dim() - 1, k + upperCount());
101 for (uint04 j = k + 1; j <= j_max; j++)
102 {
103 // assembly part of R
104 (*this)(i, j) = (*this)(i, j) + x * (*this)(k, j);
105 }
106 }
107 }
108 }
109 // solves Ly=b
110 template<class t_l_type>
112 {
113 lib_assert(dim() == b.size(), "Bad size");
115 x.setSize(dim());
116 for (uint04 i = 0; i < dim(); i++)
117 {
118 t_l_type sum(0);
119 uint04 j_start = getMax(0U, i - lowerCount());
120 for (uint04 j = j_start; j < i; j++)
121 sum += (*this)(i, j) * x[j];
122 x[i] = (b[i] * savedDiag(i)) - sum;
123 }
124 return x;
125 }
126 // solves Rx=y
127 template<class t_r_type>
129 {
130 lib_assert(dim() == b.size(), "dimensions not equal");
132 x.setSize(dim());
133 for (uint04 i = dim() - 1; !isNaN(i); i--)
134 {
135 t_r_type sum(0);
136 uint04 j_stop = getMin(dim() - 1, i + upperCount());
137 for (uint04 j = i + 1; j <= j_stop; j++)
138 sum += (*this)(i, j) * x[j];
139 x[i] = (b[i] - sum) / (*this)(i, i);
140 }
141 return x;
142 }
143 template<class t_l_type>
144 Buffer<t_l_type> luSolve(const Buffer<t_l_type>& b, bool is_lu_decomposed = false)
145 {
146 lib_assert(dim() == b.size(), "Bad size");
147 if (!is_lu_decomposed)
148 luDecompose();
151 return x;
152 }
153 };
154}
#define lib_assert(expression, message)
Asserts some logic in the code. Disabled in non debug mode by default. Can be re-enabled in release u...
Definition LibAssert.h:70
Band Matrix solver.
Definition BandMatrix.hpp:13
~BandMatrix()
Definition BandMatrix.hpp:19
t_type savedDiag(uint04 i) const
Definition BandMatrix.hpp:66
uint04 dim() const
Definition BandMatrix.hpp:42
uint04 upperCount() const
Definition BandMatrix.hpp:20
Buffer< t_l_type > luSolve(const Buffer< t_l_type > &b, bool is_lu_decomposed=false)
Definition BandMatrix.hpp:144
void luDecompose()
Definition BandMatrix.hpp:78
Buffer< t_r_type > rSolve(const Buffer< t_r_type > &b) const
Definition BandMatrix.hpp:128
t_type & operator()(uint04 i, uint04 j)
Definition BandMatrix.hpp:51
BandMatrix(uint04 dim, uint04 n_u, uint04 n_l)
Definition BandMatrix.hpp:28
BandMatrix()
Definition BandMatrix.hpp:18
uint04 lowerCount() const
Definition BandMatrix.hpp:24
Buffer< t_l_type > lSolve(const Buffer< t_l_type > &b) const
Definition BandMatrix.hpp:111
void resize(uint04 dim, uint04 n_u, uint04 n_l)
Definition BandMatrix.hpp:32
t_type & savedDiag(uint04 i)
Definition BandMatrix.hpp:71
The equivelent of std::vector but with a bit more control. The basic array unit of the library.
Definition Buffer.hpp:64
constexpr t_index_type size() const
Definition Buffer.hpp:1461
void setSize(t_index_type new_size)
Definition Buffer.hpp:1413
Definition ACIColor.h:37
constexpr t_type getMax(const t_type &left, const t_type &right)
Finds the max of the given arguments using the > operator.
Definition BaseFunctions.hpp:116
uint32_t uint04
-Defines an alias representing a 4 byte, unsigned integer -Can represent exact integer values 0 throu...
Definition BaseValues.hpp:120
constexpr bool isNaN(const t_type &value)
Query if 'value' is valid or invalid.
Definition BaseFunctions.hpp:200
constexpr t_type getMin(const t_type &left, const t_type &right)
Finds the minimum of the given arguments based on the < operator.
Definition BaseFunctions.hpp:67