HyperHDG
dense_la.hxx
Go to the documentation of this file.
1 #pragma once // Ensure that file is included only once in a single compilation.
2 
3 #include <HyperHDG/hy_assert.hxx>
4 
5 #include <array>
6 #include <cmath>
7 #include <ostream>
8 #include <vector> // Allows explicit converion from vector to SmallMat!
9 
10 // #include <exception>
11 
12 /*!*************************************************************************************************
13  * \brief Exception to be thrown if division by zero appears.
14  *
15  * \authors Guido Kanschat, Heidelberg University, 2019--2020.
16  * \authors Andreas Rupp, Heidelberg University, 2019--2020.
17  **************************************************************************************************/
19 {
20  const char* what() const throw() { return "Division by zero in dense linear algebra."; }
21 };
22 
23 /*!*************************************************************************************************
24  * \brief This class implements a small/dense matrix.
25  *
26  * \tparam n_rowsT Number of rows of the matrix.
27  * \tparam n_colsT Number of columns of the matrix. Defaults to create square matrix.
28  * \tparam mat_entry_t Floating point type specification. Default is double.
29  *
30  * \authors Guido Kanschat, Heidelberg University, 2019--2020.
31  * \authors Andreas Rupp, Heidelberg University, 2019--2020.
32  **************************************************************************************************/
33 template <unsigned int n_rowsT, unsigned int n_colsT = n_rowsT, typename mat_entry_t = double>
34 class SmallMat
35 {
36  public:
37  /*!***********************************************************************************************
38  * \brief Return number of rows of the matrix.
39  *
40  * \retval n_rows Number of rows of the matrix.
41  ************************************************************************************************/
42  static constexpr unsigned int n_rows() { return n_rowsT; }
43  /*!***********************************************************************************************
44  * \brief Return number of columns of the matrix.
45  *
46  * \retval n_cols Number of columns of the matrix.
47  ************************************************************************************************/
48  static constexpr unsigned int n_cols() { return n_colsT; }
49  /*!***********************************************************************************************
50  * \brief Return size a SmallMat.
51  *
52  * \retval size Amount of entries that can be stored within the matrix
53  ************************************************************************************************/
54  static constexpr unsigned int size() { return n_rowsT * n_colsT; }
55  /*!***********************************************************************************************
56  * \brief Return dimensions a SmallMat.
57  *
58  * \retval dims Number of rows and number of columns of the matrix.
59  ************************************************************************************************/
60  static constexpr std::array<unsigned int, 2> dimensions()
61  {
62  return std::array<unsigned int, 2>{n_rowsT, n_colsT};
63  }
64  /*!***********************************************************************************************
65  * \brief Define value_type of SmallMat as the typename of its entries!
66  ************************************************************************************************/
67  typedef mat_entry_t value_type;
68 
69  private:
70  /*!***********************************************************************************************
71  * \brief Array containing the entries of the SmallMat.
72  ************************************************************************************************/
73  std::array<mat_entry_t, size()> entries_;
74  /*!***********************************************************************************************
75  * \brief Translate row and column indices to local index of entry in matrix' array entries_.
76  *
77  * Local \f$ m \times n \f$ matrices are encoded as arrays of size \f$mn\f$. This function
78  * translates a row and a column index into the index of the long array, where the corresponding
79  * entry is located. Note that this is done column-wise (not row-wise as usually), to have the
80  * correct format for LAPACK.
81  *
82  * The function is static inline, since it is used in the constructor's initializer list.
83  *
84  * \param row Row index of local mtatrix entry.
85  * \param column Column index of local matrix entry.
86  * \retval index Overall index of local matrix entry.
87  ************************************************************************************************/
88  static inline unsigned int loc_matrix_index(const unsigned int row, const unsigned int column)
89  {
90  static_assert(n_rowsT > 0, "Matrix must have at least one row");
91  static_assert(n_colsT > 0, "Matrix must have at least one column");
92 
93  hy_assert(row < n_rowsT, "Row index must be smaller than number of rows.");
94  hy_assert(column < n_colsT, "Column index must be smaller than number of columns.");
95 
96  return column * n_rowsT + row; // Encoded like this for easy use of LAPACK!
97  }
98 
99  public:
100  // -----------------------------------------------------------------------------------------------
101  // Constructors and assignment operators:
102  // -----------------------------------------------------------------------------------------------
103 
104  /*!***********************************************************************************************
105  * \brief Empty constructor for a SmallMat.
106  *
107  * Fills entries of the SmallMat with zeros.
108  ************************************************************************************************/
109  SmallMat() { entries_.fill(0.); }
110  /*!***********************************************************************************************
111  * \brief Construct SmallMat that contains specified value.
112  *
113  * Fills entries of the SmallMat with given value.
114  ************************************************************************************************/
115  SmallMat(const mat_entry_t entry_value) { entries_.fill(entry_value); }
116  /*!***********************************************************************************************
117  * \brief Construct SmallMat from array of entries.
118  *
119  * Fills the SmallMat's array of entries with the input parameter.
120  *
121  * \param entries A \c std::array containing the entries of the SmallMat.
122  ************************************************************************************************/
123  SmallMat(const std::array<mat_entry_t, size()>& entries) : entries_(entries) {}
124  // { for (unsigned int i = 0; i < size(); ++i) entries_[i] = entries[i]; }
125  /*!***********************************************************************************************
126  * \brief Move constructor from array.
127  ************************************************************************************************/
128  SmallMat(std::array<mat_entry_t, size()>&& entries) noexcept : entries_(std::move(entries)) {}
129  /*!***********************************************************************************************
130  * \brief Construct SmallMat from std::vector of entries.
131  *
132  * Fills the SmallMat's array of entries with the input parameter.
133  *
134  * \param entries A \c std::array containing the entries of the SmallMat.
135  ************************************************************************************************/
136  SmallMat(const std::vector<mat_entry_t>& entries)
137  {
138  hy_assert(entries.size() == size(), "std::vector and SmallMat must have compatible sizes!");
139  for (unsigned int i = 0; i < size(); ++i)
140  entries_[i] = entries[i];
141  }
142  /*!***********************************************************************************************
143  * \brief Copy constructor.
144  ************************************************************************************************/
146  // { for (unsigned int i = 0; i < size(); ++i) entries_[i] = other[i]; }
147  /*!***********************************************************************************************
148  * \brief Conversion between different floating points artithmetics.
149  ************************************************************************************************/
150  template <typename other_entry_t>
152  {
153  for (unsigned int i = 0; i < size(); ++i)
154  entries_[i] = other[i];
155  }
156  /*!***********************************************************************************************
157  * \brief Move constructor.
158  ************************************************************************************************/
160  : entries_(std::move(other.entries_))
161  {
162  }
163  /*!***********************************************************************************************
164  * \brief Copy assignment.
165  ************************************************************************************************/
168  {
169  for (unsigned int i = 0; i < size(); ++i)
170  entries_[i] = other[i];
171  return *this;
172  }
173  /*!***********************************************************************************************
174  * \brief Move assignment.
175  ************************************************************************************************/
178  {
179  std::swap(entries_, other.entries_);
180  return *this;
181  }
182 
183  // -----------------------------------------------------------------------------------------------
184  // Return array with data:
185  // -----------------------------------------------------------------------------------------------
186 
187  /*!***********************************************************************************************
188  * \brief Return data array that allows to manipulate the SmallMat.
189  ************************************************************************************************/
190  std::array<mat_entry_t, size()>& data() { return entries_; }
191  /*!***********************************************************************************************
192  * \brief Return data array of a constant SmallMat.
193  ************************************************************************************************/
194  const std::array<mat_entry_t, size()>& data() const { return entries_; }
195 
196  // -----------------------------------------------------------------------------------------------
197  // Random access operators:
198  // -----------------------------------------------------------------------------------------------
199 
200  /*!***********************************************************************************************
201  * \brief Return a column of a SmallMat.
202  *
203  * \param col An \c unsigned \c int referring to the column's index.
204  * \retval column SmallMat that consists of the column.
205  ************************************************************************************************/
206  SmallMat<n_rowsT, 1, mat_entry_t> get_column(const unsigned int col) const
207  {
208  hy_assert(col < n_colsT, "The column you requested does not exist!");
210  for (unsigned int i = 0; i < n_rowsT; ++i)
211  column[i] = operator()(i, col);
212  return column;
213  }
214  /*!***********************************************************************************************
215  * \brief Set column of a SmallMat.
216  *
217  * \param col An \c unsigned \c int referring to the column's index.
218  * \param col_vec The column that should be located at the position \c col.
219  ************************************************************************************************/
220  void set_column(const unsigned int col, const SmallMat<n_rowsT, 1, mat_entry_t> col_vec)
221  {
222  for (unsigned int i = 0; i < n_rowsT; ++i)
223  operator()(i, col) = col_vec[i];
224  }
225  /*!***********************************************************************************************
226  * \brief Return single entry of a constant SmallMat.
227  *
228  * \param row Row index of the matrix entry to be returned.
229  * \param column Column index of the matrix entry to be returned.
230  * \retval entry Matrix entry at given position.
231  ************************************************************************************************/
232  inline mat_entry_t operator()(const unsigned int row, const unsigned int column) const
233  {
234  return operator[](loc_matrix_index(row, column));
235  }
236  /*!***********************************************************************************************
237  * \brief Return reference to single entry of a SmallMat.
238  *
239  * \param row Row index of the matrix entry to be returned.
240  * \param column Column index of the matrix entry to be returned.
241  * \retval entry A reference to a \c mat_entry_t describing the matrix entry.
242  ************************************************************************************************/
243  inline mat_entry_t& operator()(const unsigned int row, const unsigned int column)
244  {
245  return operator[](loc_matrix_index(row, column));
246  }
247  /*!***********************************************************************************************
248  * \brief Return single entry of a constant SmallMat.
249  *
250  * \param index An \c unsigned \c int referring to the entry that is to be returned.
251  * \retval entry \c mat_entry_t being the entry at given index.
252  ************************************************************************************************/
253  inline mat_entry_t operator[](const unsigned int index) const
254  {
255  hy_assert(index < size(),
256  "You can only access entries of a SmallMat's entries that have non-negaitive "
257  << "index that is smaller than its size (which is " << size() << ")."
258  << " However, you tried to access the " << index << "-th entry.");
259  return entries_[index];
260  }
261  /*!***********************************************************************************************
262  * \brief Return reference to single entry of a SmallMat.
263  *
264  * \param index An \c unsigned \c int referring to the entry that is to be returned.
265  * \retval entry Reference to \c mat_entry_t being the entry at given index.
266  ************************************************************************************************/
267  inline mat_entry_t& operator[](const unsigned int index)
268  {
269  hy_assert(index < size(),
270  "You can only access entries of a SmallMat's entries that have non-negaitive "
271  << "index that is smaller than its size (which is " << size() << ")."
272  << " However, you tried to access the " << index << "-th entry.");
273  return entries_[index];
274  }
275 
276  // -----------------------------------------------------------------------------------------------
277  // Comparison operators:
278  // -----------------------------------------------------------------------------------------------
279 
280  /*!***********************************************************************************************
281  * \brief Find out whether two SmallMats have (exactly) the same entries.
282  *
283  * This function compares the SmallMat to another SmallMat and returns true if and only if both
284  * SmallMats have exactly (that is not only with respect to some rounding errors) the same
285  * entries.
286  *
287  * \param other Another \c SmallMat<n_rows,n_cols> that is to be dicriminated from.
288  * \retval isEqual A \c boolean which is true if both SmallMats have the same entries.
289  ************************************************************************************************/
291  {
292  for (unsigned int index = 0; index < size(); ++index)
293  if (entries_[index] != other[index])
294  return false;
295  return true;
296  }
297  /*!***********************************************************************************************
298  * \brief Find out whether two SmallMats do not have (exactly) the same entries.
299  *
300  * This function compares the SmallMat to another SmallMat and returns false if and only if both
301  * SmallMats have exactly (that is not only with respect to some rounding errors) the same
302  * entries.
303  *
304  * \param other Another \c SmallMat<n_rows,n_cols> that is to be dicriminated from.
305  * \retval isEqual A \c boolean which is false if both SmallMats have the same entries.
306  ************************************************************************************************/
308  {
309  for (unsigned int index = 0; index < size(); ++index)
310  if (entries_[index] != other[index])
311  return true;
312  return false;
313  }
314  /*!***********************************************************************************************
315  * \brief Find out whether the SmallMat is "smaller than" another SmallMat.
316  *
317  * This function compares the SmallMat to another SmallMat and returns true if and only if the
318  * lowest ranked entry (according to the entry index) where the both SmallMats are not equal of
319  * the given SmallMat is smaller than that of the other SmallMat. It is false, if both SmallMats
320  * are equal.
321  *
322  * \param other Another \c SmallMat<n_rows,n_cols> that is to be dicriminated from.
323  * \retval smalller A \c boolean which is true if \¢ this is strictly smaller than \c other.
324  ************************************************************************************************/
326  {
327  for (unsigned int index = 0; index < size(); ++index)
328  if (entries_[index] < other[index])
329  return true;
330  else if (entries_[index] > other[index])
331  return false;
332  return false;
333  }
334 
335  // -----------------------------------------------------------------------------------------------
336  // Operators updating a SmallMat by a scalar:
337  // -----------------------------------------------------------------------------------------------
338 
339  /*!***********************************************************************************************
340  * \brief Add scalar to a given SmallMat.
341  *
342  * \param scalar Floating point that is added to all of the SmallMat's entries.
343  * \retval this The updated SmallMat.
344  ************************************************************************************************/
346  {
347  for (unsigned int index = 0; index < size(); ++index)
348  entries_[index] += scalar;
349  return *this;
350  }
351  /*!***********************************************************************************************
352  * \brief Subtract scalar from a given SmallMat.
353  *
354  * \param scalar Floating point that is subtracted from all of the SmallMat's entries.
355  * \retval this The updated SmallMat.
356  ************************************************************************************************/
358  {
359  for (unsigned int index = 0; index < size(); ++index)
360  entries_[index] -= scalar;
361  return *this;
362  }
363  /*!***********************************************************************************************
364  * \brief Multiply SmallMat by a given scalar.
365  *
366  * \param scalar Floating point that is multiplied with all of the SmallMat's entries.
367  * \retval this The updated SmallMat.
368  ************************************************************************************************/
370  {
371  for (unsigned int index = 0; index < size(); ++index)
372  entries_[index] *= scalar;
373  return *this;
374  }
375  /*!***********************************************************************************************
376  * \brief Divide given SmallMat by a scalar.
377  *
378  * \param scalar Floating SmallMat (\f$\neq 0\f$) all entries are divided by.
379  * \retval this The updated SmallMat.
380  ************************************************************************************************/
382  {
383  if (scalar == 0.)
385  for (unsigned int index = 0; index < size(); ++index)
386  entries_[index] /= scalar;
387  return *this;
388  }
389 
390  // -----------------------------------------------------------------------------------------------
391  // Operators updating a SmallMat by another SmallMat:
392  // -----------------------------------------------------------------------------------------------
393 
394  /*!***********************************************************************************************
395  * \brief Add SmallMat to given SmallMat.
396  *
397  * \param other SmallMat whose entries are added to respective ones of \c this.
398  * \retval this The updated SmallMat.
399  ************************************************************************************************/
400  template <unsigned int n_cols_other>
403  {
404  static_assert(n_cols_other == n_colsT || n_cols_other == 1,
405  "Addition is only defined for equal matrices or matrix plus vector.");
406 
407  if constexpr (n_cols_other == n_colsT)
408  for (unsigned int index = 0; index < size(); ++index)
409  entries_[index] += other[index];
410  else if constexpr (n_cols_other == 1)
411  for (unsigned int j = 0; j < n_colsT; ++j)
412  for (unsigned int i = 0; i < n_rowsT; ++i)
413  this->operator()(i, j) += other[i];
414 
415  return *this;
416  }
417  /*!***********************************************************************************************
418  * \brief Subtract other SmallMat from SmallMat.
419  *
420  * \param other SmallMat whose entries are subtracted from the respective ones of \c this.
421  * \retval this The updated SmallMat.
422  ************************************************************************************************/
423  template <unsigned int n_cols_other>
426  {
427  static_assert(n_cols_other == n_colsT || n_cols_other == 1,
428  "Subtration is only defined for equal matrices or matrix plus vector.");
429 
430  if constexpr (n_cols_other == n_colsT)
431  for (unsigned int index = 0; index < size(); ++index)
432  entries_[index] -= other[index];
433  else if constexpr (n_cols_other == 1)
434  for (unsigned int j = 0; j < n_colsT; ++j)
435  for (unsigned int i = 0; i < n_rowsT; ++i)
436  this->operator()(i, j) -= other[i];
437 
438  return *this;
439  }
440  /*!***********************************************************************************************
441  * \brief Hadamard product with given SmallMat.
442  *
443  * \param other SmallMat whose entries are multiplied by the respective ones of \c this.
444  * \retval this The updated SmallMat.
445  ************************************************************************************************/
448  {
449  for (unsigned int index = 0; index < size(); ++index)
450  entries_[index] *= other[index];
451  return *this;
452  }
453  /*!***********************************************************************************************
454  * \brief Hadamard division by given SmallMat.
455  *
456  * \param other SmallMat whose respective entries of \c this are divided by.
457  * \retval this The updated SmallMat.
458  ************************************************************************************************/
461  {
462  for (unsigned int index = 0; index < size(); ++index)
463  {
464  if (other[index] == 0.)
466  entries_[index] /= other[index];
467  }
468  return *this;
469  }
470 }; // end of class SmallMat
471 
472 // -------------------------------------------------------------------------------------------------
473 // -------------------------------------------------------------------------------------------------
474 //
475 // STANDARD FUNCTIONS USING SMALL/DENSE MATRICES
476 //
477 // -------------------------------------------------------------------------------------------------
478 // -------------------------------------------------------------------------------------------------
479 
480 // -------------------------------------------------------------------------------------------------
481 // Create fundamental matrices:
482 // -------------------------------------------------------------------------------------------------
483 
484 /*!*************************************************************************************************
485  * \brief Create SmallMat that is a diagonal matrix with specified value on diagonal.
486  *
487  * \param diag_value Diagonal value.
488  * \retval diag_mat Diagonal matrix.
489  **************************************************************************************************/
490 template <unsigned int n_rows, unsigned int n_cols, typename mat_entry_t>
491 SmallMat<n_rows, n_cols, mat_entry_t> diagonal(const mat_entry_t diag_value)
492 {
493  constexpr unsigned int rank = std::min(n_rows, n_cols);
495  for (unsigned int i = 0; i < rank; ++i)
496  diag_mat(i, i) = diag_value;
497  return diag_mat;
498 }
499 /*!*************************************************************************************************
500  * \brief Create SmallMat that is a diagonal matrix with specified value on diagonal.
501  *
502  * \param diag Diagonal vector.
503  * \retval diag_mat Diagonal matrix.
504  **************************************************************************************************/
505 template <unsigned int n_rows, unsigned int n_cols, typename mat_entry_t, unsigned int n_vec>
507 {
508  constexpr unsigned int rank = std::min(n_rows, n_cols);
509  static_assert(n_vec <= rank, "There must not be more diagonal values than entries!");
511  for (unsigned int i = 0; i < n_vec; ++i)
512  diag_mat(i, i) = diag[i];
513  return diag_mat;
514 }
515 /*!*************************************************************************************************
516  * \brief Create SmallMat that repeats given column vector.
517  *
518  * \param rep_vec Column vector that is to be repeated.
519  * \retval rep_mat Matrix whose columns coincide with given vector.
520  **************************************************************************************************/
521 template <unsigned int n_rows, unsigned int n_cols, typename mat_entry_t>
523 {
525  for (unsigned int j = 0; j < n_cols; ++j)
526  for (unsigned int i = 0; i < n_rows; ++i)
527  rep_mat(i, j) = rep_vec[i];
528  return rep_mat;
529 }
530 /*!*************************************************************************************************
531  * \brief Create dyadic product of two small vectors.
532  *
533  * \param left Left vector in dyadic product.
534  * \param right Right vector in dyadic product.
535  * \retval dyad_prod Dyadic product of both vectors.
536  **************************************************************************************************/
537 template <unsigned int n_rows, unsigned int n_cols, typename mat_entry_t>
540 {
542  for (unsigned int j = 0; j < n_cols; ++j)
543  for (unsigned int i = 0; i < n_rows; ++i)
544  dyad_prod(i, j) = left[i] * right[j];
545  return dyad_prod;
546 }
547 /*!*************************************************************************************************
548  * \brief Transpose given matrix.
549  *
550  * \param mat Matrix to be transposed.
551  * \retval transposed Transposed of the given matrix.
552  **************************************************************************************************/
553 template <unsigned int n_rows, unsigned int n_cols, typename mat_entry_t>
555 {
557  for (unsigned int j = 0; j < n_cols; ++j)
558  for (unsigned int i = 0; i < n_rows; ++i)
559  transposed(j, i) = mat(i, j);
560  return transposed;
561 }
562 
563 // -------------------------------------------------------------------------------------------------
564 // Fundamental functions returning scalar from two SmallMats:
565 // -------------------------------------------------------------------------------------------------
566 
567 /*!*************************************************************************************************
568  * \brief Euclidean scalar product of two SmallVecs / Frobenius scalar product for two SmallMats.
569  **************************************************************************************************/
570 template <unsigned int n_rows, unsigned int n_cols, typename mat_entry_t>
573 {
574  mat_entry_t scalar_product = 0.;
575  for (unsigned int index = 0; index < left.size(); ++index)
576  scalar_product += left[index] * right[index];
577  return scalar_product;
578 }
579 
580 // -------------------------------------------------------------------------------------------------
581 // Fundamental functions returning SmallMat from two SmallMats:
582 // -------------------------------------------------------------------------------------------------
583 
584 /*!*************************************************************************************************
585  * \brief Add two small / dense matrices.
586  **************************************************************************************************/
587 template <unsigned int n_rows,
588  unsigned int n_cols_left,
589  unsigned int n_cols_right,
590  typename mat_entry_t>
591 SmallMat<n_rows, std::max(n_cols_left, n_cols_right), mat_entry_t> operator+(
594 {
595  static_assert(n_cols_left == n_cols_right || n_cols_left == 1 || n_cols_right == 1,
596  "Function only implemented for these three cases.");
597 
598  if constexpr (n_cols_left == n_cols_right || n_cols_right == 1)
599  {
601  return sum += right;
602  }
603  else if constexpr (n_cols_left == 1)
604  {
606  return sum += left;
607  }
608 }
609 /*!*************************************************************************************************
610  * \brief Subtract second small/dense matrix from first.
611  **************************************************************************************************/
612 template <unsigned int n_rows,
613  unsigned int n_cols_left,
614  unsigned int n_cols_right,
615  typename mat_entry_t>
616 SmallMat<n_rows, std::max(n_cols_left, n_cols_right), mat_entry_t> operator-(
619 {
620  static_assert(n_cols_left == n_cols_right || n_cols_left == 1 || n_cols_right == 1,
621  "Function only implemented for these three cases.");
622 
623  if constexpr (n_cols_left == n_cols_right || n_cols_right == 1)
624  {
626  return difference -= right;
627  }
628  else if constexpr (n_cols_left == 1)
629  {
631  for (unsigned int i = 0; i < n_cols_right; ++i)
632  difference.set_column(i, left - right.get_column(i));
633  return difference;
634  }
635 }
636 /*!*************************************************************************************************
637  * \brief Hadamard product of two small/dense matrices.
638  **************************************************************************************************/
639 template <unsigned int n_rows, unsigned int n_cols, typename mat_entry_t>
642 {
644  return product *= right;
645 }
646 /*!*************************************************************************************************
647  * \brief Divide first small/dense matrix element-wise by second.
648  **************************************************************************************************/
649 template <unsigned int n_rows, unsigned int n_cols, typename mat_entry_t>
652 {
654  return quotient /= right;
655 }
656 
657 // -------------------------------------------------------------------------------------------------
658 // Standard matrix--matrix multiplication:
659 // -------------------------------------------------------------------------------------------------
660 
661 /*!*************************************************************************************************
662  * \brief Standard matrix--matrix multiplication.
663  **************************************************************************************************/
664 template <unsigned int n_rowsA, unsigned int n_colsA, unsigned int n_colsB, typename mat_entry_t>
667 {
669  for (unsigned int colB = 0; colB < n_colsB; ++colB)
670  for (unsigned int colA = 0; colA < n_colsA; ++colA)
671  for (unsigned int rowA = 0; rowA < n_rowsA; ++rowA)
672  result(rowA, colB) += A(rowA, colA) * B(colA, colB);
673  return result;
674 }
675 /*!*************************************************************************************************
676  * \brief Standard matrix--matrix multiplication with non-fitting dimensions.
677  **************************************************************************************************/
678 template <unsigned int n_rowsA,
679  unsigned int n_colsA,
680  unsigned int n_rowsB,
681  unsigned int n_colsB,
682  typename mat_entry_t>
686 {
687  static constexpr unsigned int rank = std::min(n_colsA, n_rowsB);
689  for (unsigned int colB = 0; colB < n_colsB; ++colB)
690  for (unsigned int colA = 0; colA < rank; ++colA)
691  for (unsigned int rowA = 0; rowA < n_rowsA; ++rowA)
692  result(rowA, colB) += A(rowA, colA) * B(colA, colB);
693  return result;
694 }
695 /*!*************************************************************************************************
696  * \brief Transpose first small/dense matrix and multiply it with second.
697  **************************************************************************************************/
698 template <unsigned int n_rowsA, unsigned int n_colsA, unsigned int n_colsB, typename mat_entry_t>
702 {
704  for (unsigned int colB = 0; colB < n_colsB; ++colB)
705  for (unsigned int colA = 0; colA < n_colsA; ++colA)
706  for (unsigned int rowA = 0; rowA < n_rowsA; ++rowA)
707  result(colA, colB) += A(rowA, colA) * B(rowA, colB);
708  return result;
709 }
710 /*!*************************************************************************************************
711  * \brief Multiply first matrix with transposed of second second.
712  **************************************************************************************************/
713 template <unsigned int n_rowsA, unsigned int n_colsA, unsigned int n_rowsB, typename mat_entry_t>
717 {
719  for (unsigned int rowB = 0; rowB < n_rowsB; ++rowB)
720  for (unsigned int colA = 0; colA < n_colsA; ++colA)
721  for (unsigned int rowA = 0; rowA < n_rowsA; ++rowA)
722  result(colA, rowB) += A(rowA, colA) * B(rowB, rowA);
723  return result;
724 }
725 
726 // -------------------------------------------------------------------------------------------------
727 // Fundamental functions returning SmallMat from a scalar and a SmallMat:
728 // -------------------------------------------------------------------------------------------------
729 
730 /*!*************************************************************************************************
731  * \brief Add small/dense matrix to scalar.
732  **************************************************************************************************/
733 template <unsigned int n_rows, unsigned int n_cols, typename mat_entry_t>
736 {
738  return sum += scalar;
739 }
740 /*!*************************************************************************************************
741  * \brief Add scalar to small/dense matrix.
742  **************************************************************************************************/
743 template <unsigned int n_rows, unsigned int n_cols, typename mat_entry_t>
745  const mat_entry_t& scalar)
746 {
748  return sum += scalar;
749 }
750 /*!*************************************************************************************************
751  * \brief Subtract small/dense matrix from scalar.
752  **************************************************************************************************/
753 template <unsigned int n_rows, unsigned int n_cols, typename mat_entry_t>
756 {
758  for (unsigned int index = 0; index < mat.size(); ++index)
759  difference[index] = scalar - mat[index];
760  return difference;
761 }
762 /*!*************************************************************************************************
763  * \brief Subtract scalar from small/dense matrix.
764  **************************************************************************************************/
765 template <unsigned int n_rows, unsigned int n_cols, typename mat_entry_t>
767  const mat_entry_t& scalar)
768 {
770  return difference -= scalar;
771 }
772 /*!*************************************************************************************************
773  * \brief Multiply scalar with small/dense matrix.
774  **************************************************************************************************/
775 template <unsigned int n_rows, unsigned int n_cols, typename mat_entry_t>
778 {
780  return product *= scalar;
781 }
782 /*!*************************************************************************************************
783  * \brief Multiply small/dense matrix with scalar.
784  **************************************************************************************************/
785 template <unsigned int n_rows, unsigned int n_cols, typename mat_entry_t>
787  const mat_entry_t& scalar)
788 {
790  return product *= scalar;
791 }
792 /*!*************************************************************************************************
793  * \brief Divide scalar by small/dense matrix.
794  **************************************************************************************************/
795 template <unsigned int n_rows, unsigned int n_cols, typename mat_entry_t>
798 {
800  for (unsigned int index = 0; index < mat.size(); ++index)
801  {
802  if (mat[index] == 0.)
804  quotient[index] = scalar / mat[index];
805  }
806  return quotient;
807 }
808 /*!*************************************************************************************************
809  * \brief Divide small/dense matrix by scalar.
810  **************************************************************************************************/
811 template <unsigned int n_rows, unsigned int n_cols, typename mat_entry_t>
813  const mat_entry_t& scalar)
814 {
816  return quotient /= scalar;
817 }
818 
819 // -------------------------------------------------------------------------------------------------
820 // Norms of SmallMats:
821 // -------------------------------------------------------------------------------------------------
822 
823 /*!*************************************************************************************************
824  * \brief Column sum norm of a small/dense matrix.
825  **************************************************************************************************/
826 template <unsigned int n_rows, unsigned int n_cols, typename mat_entry_t>
828 {
829  if constexpr (n_cols == 1)
830  {
831  mat_entry_t norm = 0.;
832  for (unsigned int index = 0; index < n_rows; ++index)
833  norm += std::abs(mat[index]);
834  return norm;
835  }
836  else
837  {
838  mat_entry_t max_norms = 0., norm;
839  for (unsigned int col = 0; col < n_cols; ++col)
840  {
841  norm = 0.;
842  for (unsigned int row = 0; row < n_rows; ++row)
843  norm += std::abs(mat(row, col));
844  if (norm > max_norms)
845  max_norms = norm;
846  }
847  return max_norms;
848  }
849 }
850 /*!*************************************************************************************************
851  * \brief Euclidean norm of a small/dense vector.
852  **************************************************************************************************/
853 template <unsigned int n_rows, unsigned int n_cols, typename mat_entry_t>
855 {
856  static_assert(n_cols == 1, "This is only implemented for vectors.");
857  return std::sqrt(scalar_product(mat, mat));
858 }
859 /*!*************************************************************************************************
860  * \brief Row sum norm of a small/dense matrix.
861  **************************************************************************************************/
862 template <unsigned int n_rows, unsigned int n_cols, typename mat_entry_t>
864 {
865  if constexpr (n_cols == 1)
866  {
867  mat_entry_t norm = std::abs(mat[0]);
868  for (unsigned int index = 1; index < mat.size(); ++index)
869  norm = std::max(norm, std::abs(mat[index]));
870  return norm;
871  }
872  else
873  {
874  mat_entry_t max_norms = 0., norm;
875  for (unsigned int row = 0; row < n_rows; ++row)
876  {
877  norm = 0.;
878  for (unsigned int col = 0; col < n_cols; ++col)
879  norm += std::abs(mat(row, col));
880  if (norm > max_norms)
881  max_norms = norm;
882  }
883  return max_norms;
884  }
885 }
886 /*!*************************************************************************************************
887  * \brief p-norm of a small/dense vector.
888  **************************************************************************************************/
889 template <unsigned int n_rows, unsigned int n_cols, typename mat_entry_t>
890 mat_entry_t norm_p(const SmallMat<n_rows, n_cols, mat_entry_t>& mat, const mat_entry_t power)
891 {
892  static_assert(n_cols == 1, "This is only implemented for vectors.");
893  mat_entry_t norm = 0.;
894  for (unsigned int index = 0; index < mat.size(); ++index)
895  norm += std::pow(std::abs(mat[index]), power);
896  return std::pow(norm, 1. / power);
897 }
898 /*!*************************************************************************************************
899  * \brief Return product of all entries.
900  **************************************************************************************************/
901 template <unsigned int n_rows, unsigned int n_cols, typename mat_entry_t>
903 {
904  mat_entry_t product = 1.;
905  for (unsigned int index = 0; index < mat.size(); ++index)
906  product *= mat[index];
907  return product;
908 }
909 
910 // -------------------------------------------------------------------------------------------------
911 // Output of SmallMat:
912 // -------------------------------------------------------------------------------------------------
913 
914 /*!*************************************************************************************************
915  * \brief Fill \c std::ostream with small/dense matrix.
916  **************************************************************************************************/
917 template <unsigned int n_rows, unsigned int n_cols, typename mat_entry_t>
918 std::ostream& operator<<(std::ostream& stream, const SmallMat<n_rows, n_cols, mat_entry_t>& mat)
919 {
920  if constexpr (n_cols == 1)
921  {
922  for (unsigned int row = 0; row < n_rows; ++row)
923  stream << " " << mat[row] << " ";
924  stream << std::endl;
925  }
926  else
927  {
928  for (unsigned int row = 0; row < n_rows; ++row)
929  {
930  for (unsigned int col = 0; col < n_cols; ++col)
931  stream << " " << mat(row, col) << " ";
932  stream << std::endl;
933  }
934  }
935  return stream;
936 }
937 
938 // -------------------------------------------------------------------------------------------------
939 // -------------------------------------------------------------------------------------------------
940 //
941 // DERIVED CLASSES
942 //
943 // -------------------------------------------------------------------------------------------------
944 // -------------------------------------------------------------------------------------------------
945 
946 /*!*************************************************************************************************
947  * \brief A SmallSquareMat is a SmallMat, which is square.
948  **************************************************************************************************/
949 template <unsigned int n_rows, typename mat_entry_t = double>
951 /*!*************************************************************************************************
952  * \brief A SmallVec is a SmallMat of one column, where the standard mat_entry_t is double.
953  **************************************************************************************************/
954 template <unsigned int n_rows, typename mat_entry_t = double>
956 /*!*************************************************************************************************
957  * \brief A Point is a SmallMat of one column, where the standard mat_entry_t is float.
958  **************************************************************************************************/
959 template <unsigned int n_rows, typename mat_entry_t = float>
961 
962 // -------------------------------------------------------------------------------------------------
963 // -------------------------------------------------------------------------------------------------
964 //
965 // FUNCTIONS THAT REQUIRE LAPACK LIBRARY
966 //
967 // -------------------------------------------------------------------------------------------------
968 // -------------------------------------------------------------------------------------------------
969 
971 // Here, since prior include violates use of SmallMat, SmallVec, ... within the functions that are
972 // introduced in LapackWrapper.hxx!
973 
974 // -------------------------------------------------------------------------------------------------
975 // Solve linear systems of equations:
976 // -------------------------------------------------------------------------------------------------
977 
978 /*!*************************************************************************************************
979  * \brief Solve linear system of equations A * x = b <=> x = A / b.
980  **************************************************************************************************/
981 template <unsigned int n_rowsA, unsigned int n_colsB, typename mat_entry_t>
984 {
985  return Wrapper::lapack_solve<n_rowsA, n_colsB, mat_entry_t>(A.data(), b.data());
986 }
987 /*!*************************************************************************************************
988  * \brief Solve linear system of equations A * x = b <=> x = A / b.
989  **************************************************************************************************/
990 template <unsigned int n_rowsA, unsigned int n_colsB, typename mat_entry_t>
993 {
996  return helperb / helperA;
997 }
998 
999 // -------------------------------------------------------------------------------------------------
1000 // QR decomposition:
1001 // -------------------------------------------------------------------------------------------------
1002 
1003 /*!*************************************************************************************************
1004  * \brief Matrix Q of Householder QR decomposition.
1005  *
1006  * Note that Q might be different from the matrix Q attained from \c qr_decomp.
1007  **************************************************************************************************/
1008 template <unsigned int n_rows, unsigned int n_cols, typename mat_entry_t>
1010 {
1011  return Wrapper::lapack_qr_decomp_q<n_rows, n_cols, mat_entry_t>(mat.data());
1012 }
1013 /*!*************************************************************************************************
1014  * \brief Matrix Q of Householder QR decomposition.
1015  *
1016  * Note that Q might be different from the matrix Q attained from \c qr_decomp.
1017  **************************************************************************************************/
1018 template <unsigned int n_rows, unsigned int n_cols, typename mat_entry_t>
1020 {
1022  return qr_decomp_q(helper);
1023 }
1024 /*!*************************************************************************************************
1025  * \brief Normalized QR decomposition.
1026  *
1027  * Do a QR decomposition of the matrix \c mat and write result into \c mat_q (matrix Q of QR
1028  * decomposition), and \c mat (matrix R of QR decomposition). Moreover, \c mat_r is a square matrix
1029  * with \c n_cols rows and columns containing R (without some entries).
1030  *
1031  * \param mat Matrix that is to be QR decomposed.
1032  * \param mat_q Matrix containing space for Q of QR decomposition.
1033  * \param mat_r Matrix containing space for reduced R of QR decomposition.
1034  * \retval mat Matrix R of QR decomposition.
1035  * \retval mat_q Matrix Q of QR decomposition.
1036  * \retval mat_r Reduced matrix R of QR decomposition.
1037  **************************************************************************************************/
1038 template <unsigned int n_rows, unsigned int n_cols, typename mat_entry_t>
1042 {
1043  static_assert(n_cols <= n_rows, "Function only defined for these matrices!");
1044  Wrapper::lapack_qr_decomp<n_rows, n_cols, mat_entry_t>(mat.data(), mat_q.data(), mat_r.data());
1045  SmallVec<n_rows, mat_entry_t> factors(1.);
1046  bool switch_necessary = false;
1047 
1048  // Q should have determinant = +1 and not -1 (as it has for odd dimensions)!
1049  if (n_rows % 2 == 1)
1050  {
1051  if (n_cols == n_rows)
1052  factors[0] *= -1.;
1053  else
1054  factors[n_rows - 1] *= -1.;
1055  }
1056 
1057  // Diagonal entries (but first) should be positive!
1058  // The switch might be necessary to ensure that det(Q) = +1.
1059  for (unsigned int i = 1; i < n_cols; ++i)
1060  if (mat_r(i, i) < 0.)
1061  {
1062  factors[i] *= -1.;
1063  switch_necessary = !switch_necessary;
1064  }
1065 
1066  // If there is a non-positive entry, this is only allowed to be the index (0,0)!
1067  // This step ensures that Q remains with determinant = +1.
1068  if (switch_necessary)
1069  factors[0] *= -1.;
1070 
1071  // Multuply Q column-wise with the factors!
1072  for (unsigned int i = 0; i < n_rows; ++i)
1073  if (factors[i] < 0.)
1074  for (unsigned int j = 0; j < n_rows; ++j)
1075  mat_q(j, i) *= factors[i];
1076 
1077  // Multiply R row-wise with the factors!
1078  for (unsigned int i = 0; i < n_cols; ++i)
1079  if (factors[i] < 0.)
1080  for (unsigned int j = 0; j < n_cols; ++j)
1081  mat_r(i, j) *= factors[i];
1082 }
1083 /*!*************************************************************************************************
1084  * \brief Normalized QR decomposition.
1085  *
1086  * Do a QR decomposition of the matrix \c mat and write result into \c mat_q (matrix Q of QR
1087  * decomposition), and \c mat_r is a square matrix with \c n_cols rows and columns containing R
1088  * (without some entries).
1089  *
1090  * \param mat Matrix that is to be QR decomposed.
1091  * \param mat_q Matrix containing space for Q of QR decomposition.
1092  * \param mat_r Matrix containing space for reduced R of QR decomposition.
1093  * \retval mat_q Matrix Q of QR decomposition.
1094  * \retval mat_r Reduced matrix R of QR decomposition.
1095  **************************************************************************************************/
1096 template <unsigned int n_rows, unsigned int n_cols, typename mat_entry_t>
1100 {
1102  return qr_decomp(helper, mat_q, mat_r);
1103 }
1104 
1105 // -------------------------------------------------------------------------------------------------
1106 // Determinant of a rectangular matrix:
1107 // -------------------------------------------------------------------------------------------------
1108 
1109 /*!*************************************************************************************************
1110  * \brief Determinant of a rectangular system.
1111  *
1112  * Calculate the generalized determinant of a rectangular matrix. If the matrix is square, this is
1113  * the standard determinant. The determinant is determined by doing a QR decomposition based on
1114  * Householder transformations. Thus det(Q) = +1, if the number of rows if even and det(Q) = -1, if
1115  * the number of rows is odd. This number is multiplied by the diagonal entries of R.
1116  *
1117  * The matrix is destroyed using this function. Its entries might be used to generate matrices Q and
1118  * R of the QR descomposition.
1119  **************************************************************************************************/
1120 template <unsigned int n_rows, unsigned int n_cols, typename mat_entry_t>
1122 {
1123  return Wrapper::lapack_det<n_rows, n_cols, mat_entry_t>(mat.data());
1124 }
1125 /*!*************************************************************************************************
1126  * \brief Determinant of a rectangular system.
1127  *
1128  * Calculate the generalized determinant of a rectangular matrix. If the matrix is square, this is
1129  * the standard determinant. The determinant is determined by doing a QR decomposition based on
1130  * Householder transformations. Thus det(Q) = +1, if the number of rows if even and det(Q) = -1, if
1131  * the number of rows is odd. This number is multiplied by the diagonal entries of R.
1132  **************************************************************************************************/
1133 template <unsigned int n_rows, unsigned int n_cols, typename mat_entry_t>
1135 {
1137  return determinant(helper);
1138 }
SmallMat::value_type
mat_entry_t value_type
Define value_type of SmallMat as the typename of its entries!
Definition: dense_la.hxx:67
mat_times_mat_unfit
SmallMat< n_rowsA, n_colsB, mat_entry_t > mat_times_mat_unfit(const SmallMat< n_rowsA, n_colsA, mat_entry_t > &A, const SmallMat< n_rowsB, n_colsB, mat_entry_t > &B)
Standard matrix–matrix multiplication with non-fitting dimensions.
Definition: dense_la.hxx:683
SmallMat::operator+=
SmallMat< n_rowsT, n_colsT, mat_entry_t > & operator+=(const mat_entry_t scalar)
Add scalar to a given SmallMat.
Definition: dense_la.hxx:345
hy_assert.hxx
This file provides the function hy_assert.
qr_decomp
void qr_decomp(SmallMat< n_rows, n_cols, mat_entry_t > &mat, SmallSquareMat< n_rows, mat_entry_t > &mat_q, SmallSquareMat< n_cols, mat_entry_t > &mat_r)
Normalized QR decomposition.
Definition: dense_la.hxx:1039
SmallMat::operator=
SmallMat< n_rowsT, n_colsT, mat_entry_t > & operator=(SmallMat< n_rowsT, n_colsT, mat_entry_t > &&other) noexcept
Move assignment.
Definition: dense_la.hxx:176
SmallMat::SmallMat
SmallMat(const mat_entry_t entry_value)
Construct SmallMat that contains specified value.
Definition: dense_la.hxx:115
check_push_test.index
index
Definition: check_push_test.py:10
SmallMat::operator()
mat_entry_t operator()(const unsigned int row, const unsigned int column) const
Return single entry of a constant SmallMat.
Definition: dense_la.hxx:232
operator/
SmallMat< n_rows, n_cols, mat_entry_t > operator/(const mat_entry_t &scalar, const SmallMat< n_rows, n_cols, mat_entry_t > &mat)
Divide scalar by small/dense matrix.
Definition: dense_la.hxx:796
SmallMat::data
const std::array< mat_entry_t, size()> & data() const
Return data array of a constant SmallMat.
Definition: dense_la.hxx:194
dyadic_product
SmallMat< n_rows, n_cols, mat_entry_t > dyadic_product(const SmallMat< n_rows, 1, mat_entry_t > &left, const SmallMat< n_cols, 1, mat_entry_t > &right)
Create dyadic product of two small vectors.
Definition: dense_la.hxx:538
SmallMat::SmallMat
SmallMat(std::array< mat_entry_t, size()> &&entries) noexcept
Move constructor from array.
Definition: dense_la.hxx:128
operator*
SmallMat< n_rowsA, n_colsB, mat_entry_t > operator*(const SmallMat< n_rowsA, n_colsA, mat_entry_t > &A, const SmallMat< n_colsA, n_colsB, mat_entry_t > &B)
Standard matrix–matrix multiplication.
Definition: dense_la.hxx:665
rep_mat
SmallMat< n_rows, n_cols, mat_entry_t > rep_mat(const SmallMat< n_rows, 1, mat_entry_t > rep_vec)
Create SmallMat that repeats given column vector.
Definition: dense_la.hxx:522
SmallMat::SmallMat
SmallMat(SmallMat< n_rowsT, n_colsT, mat_entry_t > &&other) noexcept
Move constructor.
Definition: dense_la.hxx:159
SmallMat::entries_
std::array< mat_entry_t, size()> entries_
Array containing the entries of the SmallMat.
Definition: dense_la.hxx:73
hada_prod
SmallMat< n_rows, n_cols, mat_entry_t > hada_prod(const SmallMat< n_rows, n_cols, mat_entry_t > &left, const SmallMat< n_rows, n_cols, mat_entry_t > &right)
Hadamard product of two small/dense matrices.
Definition: dense_la.hxx:640
operator-
SmallMat< n_rows, std::max(n_cols_left, n_cols_right), mat_entry_t > operator-(const SmallMat< n_rows, n_cols_left, mat_entry_t > &left, const SmallMat< n_rows, n_cols_right, mat_entry_t > &right)
Subtract second small/dense matrix from first.
Definition: dense_la.hxx:616
SmallMat::size
static constexpr unsigned int size()
Return size a SmallMat.
Definition: dense_la.hxx:54
SmallMat::operator[]
mat_entry_t operator[](const unsigned int index) const
Return single entry of a constant SmallMat.
Definition: dense_la.hxx:253
SmallMat::operator()
mat_entry_t & operator()(const unsigned int row, const unsigned int column)
Return reference to single entry of a SmallMat.
Definition: dense_la.hxx:243
operator<<
std::ostream & operator<<(std::ostream &stream, const SmallMat< n_rows, n_cols, mat_entry_t > &mat)
Fill std::ostream with small/dense matrix.
Definition: dense_la.hxx:918
operator+
SmallMat< n_rows, std::max(n_cols_left, n_cols_right), mat_entry_t > operator+(const SmallMat< n_rows, n_cols_left, mat_entry_t > &left, const SmallMat< n_rows, n_cols_right, mat_entry_t > &right)
Add two small / dense matrices.
Definition: dense_la.hxx:591
norm_infty
mat_entry_t norm_infty(const SmallMat< n_rows, n_cols, mat_entry_t > &mat)
Row sum norm of a small/dense matrix.
Definition: dense_la.hxx:863
exception
if the work is an executable linked with the with the complete machine readable work that uses the as object code and or source so that the user can modify the Library and then relink to produce a modified executable containing the modified rather than copying library functions into the if the user installs as long as the modified version is interface compatible with the version that the work was made with c Accompany the work with a written valid for at least three to give the same user the materials specified in for a charge no more than the cost of performing this distribution d If distribution of the work is made by offering access to copy from a designated offer equivalent access to copy the above specified materials from the same place e Verify that the user has already received a copy of these materials or that you have already sent this user a copy For an the required form of the work that uses the Library must include any data and utility programs needed for reproducing the executable from it as a special exception
Definition: License.txt:320
SmallMat::SmallMat
SmallMat(const SmallMat< n_rowsT, n_colsT, mat_entry_t > &other)
Copy constructor.
Definition: dense_la.hxx:145
norm_p
mat_entry_t norm_p(const SmallMat< n_rows, n_cols, mat_entry_t > &mat, const mat_entry_t power)
p-norm of a small/dense vector.
Definition: dense_la.hxx:890
SmallMat::operator+=
SmallMat< n_rowsT, n_colsT, mat_entry_t > & operator+=(const SmallMat< n_rowsT, n_cols_other, mat_entry_t > &other)
Add SmallMat to given SmallMat.
Definition: dense_la.hxx:401
norm_1
mat_entry_t norm_1(const SmallMat< n_rows, n_cols, mat_entry_t > &mat)
Column sum norm of a small/dense matrix.
Definition: dense_la.hxx:827
diagonal
SmallMat< n_rows, n_cols, mat_entry_t > diagonal(const mat_entry_t diag_value)
Create SmallMat that is a diagonal matrix with specified value on diagonal.
Definition: dense_la.hxx:491
SmallMat::operator*=
SmallMat< n_rowsT, n_colsT, mat_entry_t > & operator*=(const SmallMat< n_rowsT, n_colsT, mat_entry_t > &other)
Hadamard product with given SmallMat.
Definition: dense_la.hxx:446
SmallMat::SmallMat
SmallMat(const std::array< mat_entry_t, size()> &entries)
Construct SmallMat from array of entries.
Definition: dense_la.hxx:123
entries_product
mat_entry_t entries_product(const SmallMat< n_rows, n_cols, mat_entry_t > &mat)
Return product of all entries.
Definition: dense_la.hxx:902
mat_times_transposed_mat
SmallMat< n_rowsA, n_rowsB, mat_entry_t > mat_times_transposed_mat(const SmallMat< n_rowsA, n_colsA, mat_entry_t > &A, const SmallMat< n_rowsB, n_colsA, mat_entry_t > &B)
Multiply first matrix with transposed of second second.
Definition: dense_la.hxx:714
SmallMat::loc_matrix_index
static unsigned int loc_matrix_index(const unsigned int row, const unsigned int column)
Translate row and column indices to local index of entry in matrix' array entries_.
Definition: dense_la.hxx:88
SmallMat::data
std::array< mat_entry_t, size()> & data()
Return data array that allows to manipulate the SmallMat.
Definition: dense_la.hxx:190
SmallMat::operator-=
SmallMat< n_rowsT, n_colsT, mat_entry_t > & operator-=(const SmallMat< n_rowsT, n_cols_other, mat_entry_t > &other)
Subtract other SmallMat from SmallMat.
Definition: dense_la.hxx:424
SmallMatDivByZeroException::what
const char * what() const
Definition: dense_la.hxx:20
SmallMat::operator=
SmallMat< n_rowsT, n_colsT, mat_entry_t > & operator=(const SmallMat< n_rowsT, n_colsT, mat_entry_t > &other)
Copy assignment.
Definition: dense_la.hxx:166
SmallMat::operator!=
bool operator!=(const SmallMat< n_rowsT, n_colsT, mat_entry_t > &other) const
Find out whether two SmallMats do not have (exactly) the same entries.
Definition: dense_la.hxx:307
SmallMat::operator-=
SmallMat< n_rowsT, n_colsT, mat_entry_t > & operator-=(const mat_entry_t scalar)
Subtract scalar from a given SmallMat.
Definition: dense_la.hxx:357
SmallMat::operator/=
SmallMat< n_rowsT, n_colsT, mat_entry_t > & operator/=(const SmallMat< n_rowsT, n_colsT, mat_entry_t > &other)
Hadamard division by given SmallMat.
Definition: dense_la.hxx:459
SmallMat::operator*=
SmallMat< n_rowsT, n_colsT, mat_entry_t > & operator*=(const mat_entry_t scalar)
Multiply SmallMat by a given scalar.
Definition: dense_la.hxx:369
scalar_product
mat_entry_t scalar_product(const SmallMat< n_rows, n_cols, mat_entry_t > &left, const SmallMat< n_rows, n_cols, mat_entry_t > &right)
Euclidean scalar product of two SmallVecs / Frobenius scalar product for two SmallMats.
Definition: dense_la.hxx:571
norm_2
mat_entry_t norm_2(const SmallMat< n_rows, n_cols, mat_entry_t > &mat)
Euclidean norm of a small/dense vector.
Definition: dense_la.hxx:854
SmallMat::SmallMat
SmallMat()
Empty constructor for a SmallMat.
Definition: dense_la.hxx:109
SmallMat::SmallMat
SmallMat(const std::vector< mat_entry_t > &entries)
Construct SmallMat from std::vector of entries.
Definition: dense_la.hxx:136
SmallMat::n_rows
static constexpr unsigned int n_rows()
Return number of rows of the matrix.
Definition: dense_la.hxx:42
SmallMat::operator==
bool operator==(const SmallMat< n_rowsT, n_colsT, mat_entry_t > &other) const
Find out whether two SmallMats have (exactly) the same entries.
Definition: dense_la.hxx:290
hy_assert
#define hy_assert(Expr, Msg)
The assertion to be used within HyperHDG — deactivate using -DNDEBUG compile flag.
Definition: hy_assert.hxx:38
SmallMat::n_cols
static constexpr unsigned int n_cols()
Return number of columns of the matrix.
Definition: dense_la.hxx:48
qr_decomp_q
SmallMat< n_rows, n_rows, mat_entry_t > qr_decomp_q(SmallMat< n_rows, n_cols, mat_entry_t > &mat)
Matrix Q of Householder QR decomposition.
Definition: dense_la.hxx:1009
transposed_mat_times_mat
SmallMat< n_colsA, n_colsB, mat_entry_t > transposed_mat_times_mat(const SmallMat< n_rowsA, n_colsA, mat_entry_t > &A, const SmallMat< n_rowsA, n_colsB, mat_entry_t > &B)
Transpose first small/dense matrix and multiply it with second.
Definition: dense_la.hxx:699
hada_divi
SmallMat< n_rows, n_cols, mat_entry_t > hada_divi(const SmallMat< n_rows, n_cols, mat_entry_t > &left, const SmallMat< n_rows, n_cols, mat_entry_t > &right)
Divide first small/dense matrix element-wise by second.
Definition: dense_la.hxx:650
SmallMat::dimensions
static constexpr std::array< unsigned int, 2 > dimensions()
Return dimensions a SmallMat.
Definition: dense_la.hxx:60
SmallMatDivByZeroException
Exception to be thrown if division by zero appears.
Definition: dense_la.hxx:18
diffusion_uniform.A
A
Definition: diffusion_uniform.py:39
SmallMat::get_column
SmallMat< n_rowsT, 1, mat_entry_t > get_column(const unsigned int col) const
Return a column of a SmallMat.
Definition: dense_la.hxx:206
lapack.hxx
This file provides the function lapack_solve.
transposed
SmallMat< n_cols, n_rows, mat_entry_t > transposed(SmallMat< n_rows, n_cols, mat_entry_t > mat)
Transpose given matrix.
Definition: dense_la.hxx:554
SmallMat::operator[]
mat_entry_t & operator[](const unsigned int index)
Return reference to single entry of a SmallMat.
Definition: dense_la.hxx:267
determinant
mat_entry_t determinant(SmallMat< n_rows, n_cols, mat_entry_t > &mat)
Determinant of a rectangular system.
Definition: dense_la.hxx:1121
SmallMat::operator/=
SmallMat< n_rowsT, n_colsT, mat_entry_t > & operator/=(const mat_entry_t scalar)
Divide given SmallMat by a scalar.
Definition: dense_la.hxx:381
SmallMat::SmallMat
SmallMat(const SmallMat< n_rowsT, n_colsT, other_entry_t > &other)
Conversion between different floating points artithmetics.
Definition: dense_la.hxx:151
SmallMat::set_column
void set_column(const unsigned int col, const SmallMat< n_rowsT, 1, mat_entry_t > col_vec)
Set column of a SmallMat.
Definition: dense_la.hxx:220
SmallMat::operator<
bool operator<(const SmallMat< n_rowsT, n_colsT, mat_entry_t > &other) const
Find out whether the SmallMat is "smaller than" another SmallMat.
Definition: dense_la.hxx:325
SmallMat
This class implements a small/dense matrix.
Definition: dense_la.hxx:34