finitediff
SNmultiGaussian.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 __SNMULTIGAUSSIAN_H__105525
20 #define __SNMULTIGAUSSIAN_H__105525
21 
22 
23 #include "SNlowerTriangular.h"
24 #include "SNidentity.h"
25 #include "m_num.h"
26 
41 template <class T,unsigned int tp_size>
42 class SNmultiGaussian : public SNgeneric<T,tp_size>
43 {
44 
45  private :
47  m_num data_last_column; // the last non trivial column
48 
50  T _get(m_num,m_num) const override;
51  T& _at(m_num,m_num) override;
52  public:
70 
73 
87  void operator *=(const SNgaussian<T,tp_size>& other);
88 
91 
92  /*\brief Swap the lines \f$ i \f$ and \f$ j \f$.
93  *
94  * This only works when \f$ i \f$ and \f$ j \f$ are larger than
95  * the last non trivial column.
96  *
97  * If \f$ i \f$ or \f$ j \f$ is lower or equal to the last non trivial line,
98  * throw a `ProbablyNotWhatYouWantException`.
99  *
100  * In place replacement.
101  */
102  void swapLines(const m_num& i,const m_num& j);
103 
105  m_num getLastColumn() const;
113  void setLastColumn(const m_num& lc);
114 
145  template <class U,unsigned int s>
146  void setFirstLines(const SNgeneric<U,s>& other,const m_num max_l);
147 };
148 
149 // CONSTRUCTORS -------------------------------------------------
150 
151 // from nothing
152 template <class T,unsigned int tp_size>
154  data_L(SNidentity<T,tp_size>()),
155  data_last_column(tp_size+1) //force the user to initialize (see `_at`)
156 { }
157 
158 // from generic
159 template <class T,unsigned int tp_size>
161  data_L(A.getGaussian(0)),
163 { }
164 
165 // from multigaussian
166 template <class T,unsigned int tp_size>
168  data_L(A.data_L),
170 { }
171 
172 // from gaussian
173 template <class T,unsigned int tp_size>
175  data_last_column(A.getColumn())
176 {
177  for (m_num c=0;c<A.getColumn();++c)
178  {
179  for (m_num l=c+1;l<tp_size;++l)
180  {
181  this->at(l,c)=A.get(l,c);
182  }
183  }
184  for (m_num l=A.getColumn()+1;l<tp_size;++l)
185  {
186  this->at(l,A.getColumn())=A.get(l,A.getColumn());
187  }
188 }
189 
190 template <class T,unsigned int tp_size>
192 {
193  data_L.swap(other.data_L);
195 }
196 
197 // assignation
198 template <class T,unsigned int tp_size>
200 {
201  swap(other);
202  return *this;
203 }
204 
205 // GETTER/SETTER METHODS ---------------------------------------
206 
207 
208 template <class T,unsigned int tp_size>
210 {
211  return data_last_column;
212 }
213 
214 template <class T,unsigned int tp_size>
216 {
217  if (lc>tp_size-1) // makes no sense to have a gaussian
218  // behaviour on the last line.
219  {
220  throw OutOfRangeColumnNumber("The specified column number is larger than the size of the matrix.");
221  }
222  data_last_column=lc;
223 }
224 
225 template <class T,unsigned int tp_size>
226 template <class U,unsigned int s>
228  (const SNgeneric<U,s>& other,const m_num max_l)
229 {
230  for (m_num line=0;line<max_l+1;line++)
231  {
232  for (m_num col=0; col < line ;++col)
233  {
234  this->at(line,col)=other.get(line,col);
235  }
236  }
237 }
238 
239 // OPERATORS ---------------------------------------
240 
241 template <class T,unsigned int tp_size>
243 {
244  checkSizeCompatibility(*this,other);
245  if (other.getColumn()!=data_last_column+1)
246  {
247  throw ProbablyNotWhatYouWantException("You are trying to multiply a multi-Gaussian matrix by a gaussian matrix whose column is not the next one. This is mathematically possible, but probably not what you want. However; this situation is not yet implemented.");
248  }
250  for (m_num l=other.getColumn()+1;l<tp_size;++l)
251  {
252  this->at(l,other.getColumn())+=other.get(l,other.getColumn());
253  }
254 }
255 
256 // MATHEMATICS -------------------------------------------
257 
258 
259 template <class T,unsigned int tp_size>
261 {
262  auto ans=*this;
263  for (m_num col=0;col<getLastColumn()+1;++col)
264  {
265  // one can parallelize with respect to the columns,
266  // not with respect to the lines.
267  for (m_num line=col+1;line<tp_size;++line)
268  {
269  T acc=0;
270  for (m_num k=col;k<line;++k)
271  {
272  acc+=this->get(line,k)*ans.get(k,col);
273  }
274  ans.at(line,col)= - acc;
275  }
276  }
277  return ans;
278 }
279 
280 
281 template <class T,unsigned int tp_size>
283 {
284  if (i<=getLastColumn() or j<=getLastColumn())
285  {
286  throw ProbablyNotWhatYouWantException("You are trying to swap the lines "+std::to_string(i)+" and "+std::to_string(j)+" while the last non trivial column is "+std::to_string(getLastColumn()) );
287  }
288  for (m_num col=0;col<=getLastColumn();++col)
289  {
290  std::swap( this->at(i,col),this->at(j,col) );
291  }
292 }
293 
294 // UTILITIES ---------------------------------------
295 
296 
309 template <class T,unsigned int tp_size>
311 {
312  if (i==j)
313  {
314  return SpecialValue<T>(1,true);
315  }
316  if (j>data_last_column)
317  {
318  return SpecialValue<T>(0,true);
319  }
320  if (i<j)
321  {
322  return SpecialValue<T>(0,true);
323  }
324  return SpecialValue<T>(0,false); // In this case, the value "0" is dummy.
325 }
326 
327 
328 // _GET AND _AT METHODS ---------------------------------------
329 
330 template <class T,unsigned int tp_size>
332 {
334  if (sv.special)
335  {
336  return sv.value;
337  }
338  return data_L.get(i,j); //if you change here, you have to change _at
339 }
340 
341 template <class T,unsigned int tp_size>
343 {
344  if (data_last_column==tp_size+1)
345  {
346  throw NotInitializedMemberException("You are trying to populate a 'SNmultiGaussian' before to initialize the member 'data_last_column'. Use setLastColumn().");
347  }
349  if (sv.special)
350  {
351  throw SNchangeNotAllowedException(i,j);
352  }
353  return data_L.at(i,j); //if you change here, you have to change _get
354 }
355 
356 
357 
358 #endif
bool special
Definition: SNgeneric.h:130
virtual T & at(const m_num, const m_num) final
Definition: SNgeneric.h:218
Definition: SNgaussian.h:61
void checkSizeCompatibility(const SNgeneric< U, s > &A, const SNgeneric< V, t > &B)
Definition: MathUtilities.h:35
T _get(m_num, m_num) const override
Definition: SNmultiGaussian.h:331
T & _at(m_num, m_num) override
Definition: SNmultiGaussian.h:342
This is the base class for the other matrices types.
Definition: MathUtilities.h:32
m_num getLastColumn() const
Definition: SNmultiGaussian.h:209
SNmultiGaussian< T, tp_size > & operator=(SNmultiGaussian< T, tp_size >)
Definition: SNmultiGaussian.h:199
void setLastColumn(const m_num &lc)
Set the number of the last non trivial column.
Definition: SNmultiGaussian.h:215
Definition: m_num.h:34
Definition: SNidentity.h:28
SNgaussian< T, tp_size > getGaussian(const m_num c) const
Definition: SNgeneric.h:229
Definition: SNmultiGaussian.h:42
SpecialValue< T > checkForSpecialElements(const m_num &, const m_num &) const
Definition: SNmultiGaussian.h:310
virtual T get(const m_num, const m_num) const final
Definition: SNgeneric.h:211
Definition: SNgaussian.h:38
SNmultiGaussian()
Definition: SNmultiGaussian.h:153
m_num getColumn() const
Definition: SNgaussian.h:144
void setFirstLines(const SNgeneric< U, s > &other, const m_num max_l)
copies the first max_l lines from other to this.
Definition: SNmultiGaussian.h:228
Definition: SNexceptions.cpp:224
T value
Definition: SNgeneric.h:129
void swap(SNmultiGaussian< T, tp_size > &)
Definition: SNmultiGaussian.h:191
m_num data_last_column
Definition: SNmultiGaussian.h:47
Represents a lower triangular matrix (the diagonal can be non zero).
Definition: SNlowerTriangular.h:37
Definition: SNexceptions.cpp:119
SNlowerTriangular< T, tp_size > data_L
Definition: SNmultiGaussian.h:46
Definition: SNexceptions.cpp:104
void swap(m_num &other)
Definition: m_num.cpp:39
void swapLines(const m_num &i, const m_num &j)
Definition: SNmultiGaussian.h:282
void operator*=(const SNgaussian< T, tp_size > &other)
Definition: SNmultiGaussian.h:242
SNmultiGaussian< T, tp_size > inverse() const
Definition: SNmultiGaussian.h:260
Definition: SNexceptions.cpp:81