finitediff
SNmatrix.h
Go to the documentation of this file.
1 /*
2 Copyright 2017 Laurent Claessens
3 contact : laurent@claessens-donadello.eu
4 
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #ifndef __SNMATRIX_H__153113__
20 #define __SNMATRIX_H__153113__
21 
22 #include <array>
23 #include <iostream>
24 #include <cmath>
25 
26 #include "SNgeneric.h"
27 #include "SNelement.h"
28 #include "SNline.h"
29 #include "SNgaussian.h"
30 #include "SNupperTriangular.h"
31 #include "Mpermutation.h"
32 #include "SNpermutation.h"
33 #include "MelementaryPermutation.h"
34 #include "MathUtilities.h"
35 #include "SNoperators.h"
36 #include "../SNvector.h"
37 #include "../exceptions/SNexceptions.cpp"
38 
39 #include "../Utilities.h"
40 
41 
42 // forward definition
43 template <class T,unsigned int tp_size>
44 class SNplu;
45 
46 
78 template <class T,unsigned int tp_size>
79 class SNmatrix : public SNgeneric<T,tp_size>
80 {
81 
82  friend class SNmatrixTest;
83  friend class GaussTest;
84 
85  template <class U,unsigned int s,class V,unsigned int t>
86  friend bool operator==(const SNmatrix<U,s>&,const SNmatrix<V,t>&);
87  template <class U,unsigned int s,class V,unsigned int t>
88  friend SNmatrix<U,s> operator+(const SNmatrix<U,s>& A,const SNmatrix<V,t>& B);
89 
90  friend std::array<T,tp_size*tp_size> SNupperTriangular<T,tp_size>::_get_other_data(const SNmatrix<T,tp_size>&) const;
91  friend std::array<T,tp_size*tp_size> SNlowerTriangular<T,tp_size>::_get_other_data(const SNmatrix<T,tp_size>&) const;
92 
93 
94  private:
95  std::array<T,tp_size*tp_size> data;
96  unsigned int size=tp_size;
97 
100 
101  // Substrat the given vector (line) from the line 'line'
102  // Using the Gauss's elimination one need to do many differences like
103  // L_i -> L_i - k*L_1/m
104  // where 'k' is the first element of L_i and 'm' is the pivot.
105  // The function 'lineMinusLine' serves to not compute L_1/m
106  // as many times as the number of substitutions to do.
108 
109 
110  // return the larger element (in absolute value) on the given column
111  // In case of equality, return the last one (the larger line).
112  // The template type T has to accept arithmetic manipulations
113  // like abs, comparison.
115 
116  // return the largest (absolute value) element under the diagonal
117  // on the given column.
119 
120  // From the line number "line", return a line normalized
121  // in such a way that the first (non zero) element is 1.
123  T& _at(const m_num,const m_num) override;
124  T _get(const m_num,const m_num) const override;
125 
127  void _set_from(const SNgeneric<T,tp_size>&);
128  void set_identity();
129  public:
130  SNmatrix();
138  SNmatrix(const T& x);
139 
140 
141  // return the max of the absolute values of all the matrix elements
142  T max_norm() const;
143 
144  // return the matrix element on given (line,column).
145  SNelement<T,tp_size> getElement(m_num line, m_num col) const;
146 
147 
151  void swapLines(m_num l1,m_num l2);
152 
153 
157  SNplu<T,tp_size> getPLU() const;
158 
159 };
160 
161 // CONSTRUCTORS -------------------------------------------
162 
163 template <class T,unsigned int tp_size>
165 
166 template <class T,unsigned int tp_size>
168 
169 template <class T,unsigned int tp_size>
171  data()
172 {
173  for (unsigned int k=0;k<tp_size*tp_size;++k)
174  {
175  data.at(k)=v;
176  }
177 };
178 
179 template <class T,unsigned int tp_size>
181 {
182  this->_set_from(A);
183 }
184 
185 // SOME ILLEGITIMATE(?) WAYS TO SET THE VALUES OF A MATRIX -----------------
186 
187 template <class T,unsigned int tp_size>
189 {
190  for (m_num i=0;i<tp_size;i++)
191  {
192  for (m_num j=0;j<tp_size;j++)
193  {
194  this->at(i,j)=A.get(i,j);
195  }
196  }
197 }
198 template <class T,unsigned int tp_size>
200 {
201  for (m_num i=0;i<tp_size;i++)
202  {
203  for (m_num j=0;j<tp_size;j++)
204  {
205  this->at(i,j)=0;
206  }
207  this->at(i,i)=1;
208  }
209 }
210 
211 // GETTER METHODS -------------------------------------------
212 
213 
214 template <class T,unsigned int tp_size>
216 {
217  return SNelement<T,tp_size>(line,col,this->get(line,col));
218 }
219 
220 
221 // _GET AND _AT METHODS ---------------------------
222 
223 template <class T,unsigned int tp_size>
225 {
226  return data.at(j*tp_size+i);
227 };
228 
229 template <class T,unsigned int tp_size>
230 T SNmatrix<T,tp_size>::_get(const m_num i,const m_num j) const
231 {
232  return data.at(j*tp_size+i);
233 };
234 
235 
236 // GAUSS'S ELIMINATION METHODS
237 
238 
239 
240 template <class T,unsigned int tp_size>
242 {
243  T m(0);
244  for (T v:data)
245  {
246  T s=std::abs(v);
247  if (s>m)
248  {
249  m=s;
250  }
251  }
252  return m;
253 }
254 
255 template <class T,unsigned int tp_size>
257 {
258  T max_val=0;
259  m_num max_line=0;
260 
261  for (m_num line=f_line;line<tp_size;line++)
262  {
263  if (std::abs(this->get(line,col))>max_val)
264  {
265  max_val=std::abs(this->get(line,col));
266  max_line=line;
267  };
268  };
269  return getElement(max_line,col);
270 }
271 
272 template <class T,unsigned int tp_size>
274 {
275  return getLargerUnder(0,col);
276 }
277 
278 template <class T,unsigned int tp_size>
280 {
281  return getLargerUnder(col,col);
282 }
283 
284 template <class T,unsigned int tp_size>
286 {
287  if (l1!=l2)
288  {
289  for (m_num col=0;col<tp_size;col++)
290  {
291  T tmp = this->get(l1,col);
292  this->at(l1,col)=this->get(l2,col);
293  this->at(l2,col)=tmp;
294  }
295  }
296 }
297 
298 
299 template <class T,unsigned int tp_size>
301 {
302  for (m_num c=0;c<tp_size;c++)
303  {
304  this->at(line,c)=this->get(line,c)-v.get(c);
305  }
306 }
307 
308 template <class T,unsigned int tp_size>
310 {
311  SNline<T,tp_size> l=this->getSNline(line);
312  l.makeUnit();
313  return l;
314 }
315 
316 template <class T,unsigned int tp_size>
318 
319  // for each column :
320  // - get the larger entry under the diagonal
321  // - swap the 'larger' line with the current line
322  // - the 'killing line' is the swapped line multiplied by the right number
323  // in such a way that the 'diagonal' entry is 1.
324  // - use that 'killing line' to eliminate the column (under the diagonal)
325  //
326  // All the mathematics is explained with some details here :
327  // http://laurent.claessens-donadello.eu/pdf/lefrido.pdf
328 
329 {
330  SNplu<T,tp_size> plu;
331 
332  Mpermutation<tp_size>& permutation=plu.data_P;
333 
334  // progressively become L
336  // this will progressively become U
337  SNmatrix<T,tp_size> mU=*this;
338 
339 
340  for (m_num c=0;c<tp_size;c++)
341  {
342  auto max_el = mU.getLargerUnderDiagonal(c);
343 
344  if (max_el.getValue()!=0) // not a column full of zero's
345  {
346 
347  // We swap the line 'c' with max_el.line
348  MelementaryPermutation<tp_size> el_perm(c,max_el.line);
349  permutation=permutation*el_perm;
350  mU.swapLines(c,max_el.line);
351 
352  auto G=mU.getGaussian(c);
353 
354  // On the first iteration, there is nothing to swap.
355  if (c!=0)
356  {
357  mM.swapLines(c,max_el.line);
358  mM*=G.inverse();
359  }
360  else
361  {
362  mM=G.inverse();
363  }
364  auto killing_line=mU.gaussEliminationLine(c);
365  for (m_num l=c+1;l<tp_size;l++)
366  {
367  T m = mU.get(l,c); // the value to be eliminated
368 
369  // TODO : this is not optimal because
370  // we already know the first 'c' differences are 0.
371  mU.lineMinusLine(l,m*killing_line);
372  }
373  }
374  }
375  // at this point, the matrix mU should be the correct one.
376  plu._setU(mU);
377  plu._setL(mM);
378  return plu;
379 }
380 
381 #endif
void _setU(const SNmatrix< T, tp_size > &A)
Definition: SNplu.h:71
friend SNmatrix< U, s > operator+(const SNmatrix< U, s > &A, const SNmatrix< V, t > &B)
Definition: SNoperators.h:451
void swapLines(m_num l1, m_num l2)
swap the lines l1 and l2.
Definition: SNmatrix.h:285
friend class GaussTest
Definition: SNmatrix.h:83
std::array< T, tp_size *tp_size > _get_other_data(const SNmatrix< T, tp_size > &) const
Definition: SNlowerTriangular.h:94
virtual T & at(const m_num, const m_num) final
Definition: SNgeneric.h:218
friend bool operator==(const SNmatrix< U, s > &, const SNmatrix< V, t > &)
Definition: SNoperators.h:489
SNmatrix()
Definition: SNmatrix.h:164
Represent a square numerical matrix.
Definition: SNline.h:29
void lineMinusLine(m_num line, SNline< T, tp_size > v)
Definition: SNmatrix.h:300
Definition: SNline.h:40
This is the base class for the other matrices types.
Definition: MathUtilities.h:32
T get(const unsigned int i) const
Definition: SNline.h:138
Definition: m_num.h:34
Definition: SNidentity.h:28
SNplu< T, tp_size > getPLU() const
Definition: SNmatrix.h:317
T & _at(const m_num, const m_num) override
Definition: SNmatrix.h:224
SNgaussian< T, tp_size > getGaussian(const m_num c) const
Definition: SNgeneric.h:229
SNelement< T, tp_size > getLargerUnderDiagonal(m_num col) const
Definition: SNmatrix.h:279
std::array< T, tp_size *tp_size > _get_other_data(const SNmatrix< T, tp_size > &) const
Definition: SNupperTriangular.h:64
Definition: SNmultiGaussian.h:42
virtual T get(const m_num, const m_num) const final
Definition: SNgeneric.h:211
Definition: SNplu.h:32
T max_norm() const
Definition: SNmatrix.h:241
SNelement< T, tp_size > getLargerOnColumn(m_num col) const
Definition: SNmatrix.h:273
virtual SNline< T, tp_size > getSNline(m_num l) const
Definition: SNgeneric.h:147
SNelement< T, tp_size > getLargerUnder(m_num f_line, m_num col) const
Definition: SNmatrix.h:256
void makeUnit()
Definition: SNline.h:168
void _set_from(const SNgeneric< T, tp_size > &)
Definition: SNmatrix.h:188
Definition: MelementaryPermutation.h:34
Mpermutation< tp_size > data_P
Definition: SNplu.h:38
T _get(const m_num, const m_num) const override
Definition: SNmatrix.h:230
SNelement< T, tp_size > getElement(m_num line, m_num col) const
Definition: SNmatrix.h:215
This is a template class that represent an element of a SNmatrix.
Definition: SNelement.h:40
std::array< T, tp_size *tp_size > data
Definition: SNmatrix.h:95
void swapLines(const m_num &i, const m_num &j)
Definition: SNmultiGaussian.h:282
This class represents a permutation (not a matrix).
Definition: MelementaryPermutation.h:26
friend class SNmatrixTest
Definition: SNmatrix.h:82
void _setL(const SNmatrix< T, tp_size > &A)
Definition: SNplu.h:78
SNline< T, tp_size > gaussEliminationLine(m_num line)
Definition: SNmatrix.h:309
SNmultiGaussian< T, tp_size > inverse() const
Definition: SNmultiGaussian.h:260
unsigned int size
Definition: SNmatrix.h:96
void set_identity()
Definition: SNmatrix.h:199