OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
FLUMatrix.h
Go to the documentation of this file.
1#ifndef CLASSIC_FLUMatrix_HH
2#define CLASSIC_FLUMatrix_HH
3
4// ------------------------------------------------------------------------
5// $RCSfile: FLUMatrix.h,v $
6// ------------------------------------------------------------------------
7// $Revision: 1.1.1.1 $
8// ------------------------------------------------------------------------
9// Copyright: see Copyright.readme
10// ------------------------------------------------------------------------
11//
12// Template class: FLUMatrix
13//
14// ------------------------------------------------------------------------
15// Class category: FixedAlgebra
16// ------------------------------------------------------------------------
17//
18// $Date: 2000/03/27 09:32:36 $
19// $Author: fci $
20//
21// ------------------------------------------------------------------------
22
26#include <cmath>
27
28
29// Template class FLUMatrix<T,N>
30// ------------------------------------------------------------------------
32// Constructed from a FMatrix<T,N,N>, this class remembers the triangular
33// decomposition and can return the back-substitution or the inverse.
34// When FLUMatrix is used on a complex matrix, then the statement
35// [pre]
36// include std::abs;
37// [/pre]
38// is required in the calling file, so as to inject the [tt]abs()[/tt]
39// function to the global namespace.
40
41template <class T, int N>
42class FLUMatrix {
43
44public:
45
47 // Find triangel decomposition of the matrix [b]M[/b].
48 // Throw SingularMatrixError if [b]M[/b] is singular.
49 explicit FLUMatrix(const FMatrix<T, N, N> &M);
50
51 FLUMatrix();
53 ~FLUMatrix();
55
57 // Perform back substitution on the vector [b]B[/b].
58 // The new [b]B[/b] is the old [b]B[/b], premultiplied by the inverse.
59 void backSubstitute(FVector<T, N> &B) const;
60
62 // Perform back substitution on the matrix [b]M[/b].
63 // The new [b]M[/b] is the old [b]M[/b], premultiplied by the inverse.
64 template <int M>
65 void backSubstitute(FMatrix<T, N, M> &MM) const;
66
68 // Construct and return the inverse.
70
71private:
72
73 // Back substitution on iterator.
74 template <class Iterator>
75 void backSubstitute(Iterator) const;
76
77 // The LU-decomposed matrix.
79
80 // The [b]index[/b] array used for LU decomposition and back substitution.
82};
83
84
85// Template function implementation.
86// ------------------------------------------------------------------------
87
88template <class T, int N>
90 decomp(), index()
91{}
92
93
94template <class T, int N>
96 decomp(rhs.decomp), index(rhs.index)
97{}
98
99
100template <class T, int N>
102 decomp(rhs), index(rhs.nrows()) {
103 // Builds the L-U decomp of the square matrix rhs.
104 // This constructor is used in combination with backSubstitute
105 // to solve linear equations or invert a matrix.
106
107 // Scale the matrix (find largest element of each row).
108 FArray1D<double, N> scaleVector;
109 for(int i = 0; i < N; i++) {
110 double maximum = 0.0;
111
112 for(int j = 0; j < N; j++) {
113 double temp = std::abs(decomp[i][j]);
114 if(temp > maximum) maximum = temp;
115 }
116
117 if(maximum == 0.0) throw SingularMatrixError("FLUMatrix::FLUMatrix()");
118 scaleVector[i] = 1.0 / maximum;
119 }
120
121 // The loop over coFLUMns of Crout's method.
122 for(int j = 0; j < N; j++) {
123 // Eqn 2.3.12 except for j = i:
124 for(int i = 0; i < j; i++) {
125 for(int k = 0; k < i; k++) {
126 decomp[i][j] -= decomp[i][k] * decomp[k][j];
127 }
128 }
129
130 // Initialize the search for the largest pivot element.
131 double maximum = 0.0;
132 int col_max = 0;
133
134 // i = j of eq 2.3.12 & i = j + 1 .. N of 2.3.13.
135 for(int i = j; i < N; i++) {
136 for(int k = 0; k < j; k++) {
137 decomp[i][j] -= decomp[i][k] * decomp[k][j];
138 }
139
140 // Figure of merit for pivot.
141 double dum = std::abs(scaleVector[i] * decomp[i][j]);
142
143 // Is it better than the best so far ?
144 if(dum >= maximum) {
145 col_max = i;
146 maximum = dum;
147 }
148 }
149
150 // Do we need to interchange rows and the scale factor ?
151 if(j != col_max) {
152 decomp.swapRows(col_max, j);
153 std::swap(scaleVector[col_max], scaleVector[j]);
154 }
155
156 index[j] = col_max;
157
158 // Now, finally, divide by the pivot element.
159 if(j != N - 1) {
160 T dum = T(1) / decomp[j][j];
161 for(int i = j + 1; i < N; i++) decomp[i][j] *= dum;
162 }
163 }
164}
165
166template <class T, int N>
168{}
169
170
171template <class T, int N>
173 decomp = rhs.decomp;
174 index = rhs.index;
175 return *this;
176}
177
178
179template <class T, int N> template <class I> inline
181 // Solves the set of N linear equations A*X = B.
182 // Here "this" is the LU-decomp of the matrix A, determined by the
183 // routine LUDecompose().
184 // B is input as the rhs vector B, and returns with the solution vector X.
185 // This routine takes into account the possibility that B will begin with
186 // many zero elements, so it is efficient for use in matrix inversion.
187 // See pp 36-37 in Press & Flannery.
188
189 int ii = - 1;
190
191 for(int i = 0; i < N; i++) {
192 int ip = index[i];
193 T sum = iter[ip];
194 iter[ip] = iter[i];
195
196 if(ii >= 0) {
197 for(int j = ii; j < i; j++) {
198 sum -= decomp[i][j] * iter[j];
199 }
200 } else if(sum != T(0)) {
201 ii = i;
202 }
203
204 iter[i] = sum;
205 }
206
207 for(int i = N; i > 0;) {
208 i--;
209 T sum = iter[i];
210
211 for(int j = i + 1; j < N; j++) {
212 sum -= decomp[i][j] * iter[j];
213 }
214
215 // store a component of the solution vector X.
216 iter[i] = sum / decomp[i][i];
217 }
218}
219
220
221template <class T, int N>
223 backSubstitute(B.begin());
224}
225
226
227template <class T, int N> template <int M>
229 for(int column = 0; column < M; column++) {
230 backSubstitute(matrix.col_begin(column));
231 }
232}
233
234
235template <class T, int N>
237 FMatrix<T, N, N> result;
238 result = result + T(1);
239 backSubstitute(result);
240 return result;
241}
242
243#endif // CLASSIC_FLUMatrix_HH
T::PETE_Expr_t::PETE_Return_t sum(const PETE_Expr< T > &expr)
Definition: PETE.h:1111
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
iterator begin()
Get iterator pointing to beginning of array.
Definition: FArray1D.h:192
col_iterator col_begin(int c)
Get column iterator.
Definition: FArray2D.h:343
void swapRows(int r1, int r2)
Exchange rows.
Definition: FArray2D.h:409
A templated representation of a LU-decomposition.
Definition: FLUMatrix.h:42
FMatrix< T, N, N > inverse() const
Get inverse.
Definition: FLUMatrix.h:236
void backSubstitute(FVector< T, N > &B) const
Back substitution.
Definition: FLUMatrix.h:222
FMatrix< T, N, N > decomp
Definition: FLUMatrix.h:78
FArray1D< int, N > index
Definition: FLUMatrix.h:81
FLUMatrix()
Definition: FLUMatrix.h:89
void backSubstitute(Iterator) const
~FLUMatrix()
Definition: FLUMatrix.h:167
FLUMatrix< T, N > & operator=(const FLUMatrix &)
Definition: FLUMatrix.h:172
A templated representation for vectors.
Definition: FVector.h:38
Singular matrix exception.