YAP
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Matrix.h
Go to the documentation of this file.
1 /* YAP - Yet another PWA toolkit
2  Copyright 2015, Technische Universitaet Muenchen,
3  Authors: Daniel Greenwald, Johannes Rauch
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 
20 
21 #ifndef yap_Matrix_h
22 #define yap_Matrix_h
23 
24 #include "fwd/Matrix.h"
25 
26 #include "Exceptions.h"
27 #include "MathUtilities.h"
28 
29 #include <array>
30 #include <string>
31 #include <type_traits>
32 #include <vector>
33 
34 namespace yap {
35 
40 template <typename T, size_t R, size_t C>
41 class Matrix : public std::array<std::array<T, C>, R>
42 {
43 public:
45  constexpr Matrix(const std::array<std::array<T, C>, R>& m) noexcept : std::array<std::array<T, C>, R>(m) {}
46 
50  Matrix(T element = 0)
51  {
52  for (size_t i = 0; i < this->size(); ++i)
53  this->at(i).fill(element);
54  }
55 
57  using std::array<std::array<T, C>, R>::operator=;
58 };
59 
61 template <typename T, size_t R, size_t C>
62 std::string to_string(const Matrix<T, R, C>& M)
63 {
64  if (M.empty() or M.front().empty())
65  return "(empty)";
66  std::string s = "(";
67  for (const auto& row : M) {
68  s += "(";
69  for (const auto& elt : row)
70  s += std::to_string(elt) + ", ";
71  s.erase(s.size() - 2, 2);
72  s += "), ";
73  }
74  s.erase(s.size() - 2, 2);
75  s += ")";
76  return s;
77 }
78 
80 template <typename T, size_t N>
81 const SquareMatrix<T, N> zeroMatrix()
82 {
83  SquareMatrix<T, N> u;
84  for (size_t i = 0; i < N; ++i)
85  for (size_t j = 0; j < N; ++j)
86  u[i][j] = (T)(0);
87  return u;
88 }
89 
91 template <typename T, size_t R, size_t C>
93 {
95  for (size_t r = 0; r < R; ++r)
96  for (size_t c = 0; c < C; ++c)
97  u[r][c] = (T)(0);
98  return u;
99 }
100 
102 template <typename T, size_t N>
103 const SquareMatrix<T, N> unitMatrix()
104 {
105  SquareMatrix<T, N> u;
106  for (size_t i = 0; i < N; ++i)
107  for (size_t j = 0; j < N; ++j)
108  u[i][j] = (T)(i == j);
109  return u;
110 }
111 
113 template <typename T, size_t N>
114 const SquareMatrix<T, N> diagonalMatrix(std::array<T, N> d)
115 {
116  SquareMatrix<T, N> D = zeroMatrix<T, N, N>();
117  for (size_t i = 0; i < N; ++i)
118  D[i][i] = d[i];
119  return D;
120 }
121 
124 template <typename T, size_t N>
125 const SquareMatrix<T, N> symmetricMatrix(std::initializer_list<T> elements)
126 {
127  size_t diag(0), i(0), j(0);
128 
129  SquareMatrix<T, N> D = zeroMatrix<T, N, N>();
130  for (const T& el : elements) {
131  if (j>=N)
132  throw exceptions::Exception("too many elements given", "symmetricMatrix");
133 
134  D[i][j] = el;
135  D[j++][i++] = el;
136 
137  if (j>=N) {
138  i = 0;
139  j = ++diag;
140  }
141  }
142 
143  return D;
144 }
145 
147 template <typename T, size_t R, size_t C>
149 {
150  Matrix<T, C, R> res;
151  for (size_t r = 0; r < R; ++r)
152  for (size_t c = 0; c < C; ++c)
153  res[c][r] = M[r][c];
154  return res;
155 }
156 
158 template <typename T, size_t R, size_t C>
160 { return -1 * M; }
161 
163 template <typename T, size_t R, size_t K, size_t C>
164 typename std::enable_if < (R != 1) or (C != 1), Matrix<T, R, C> >::type
165 const operator*(const Matrix<T, R, K>& A, const Matrix<T, K, C>& B)
166 {
167  Matrix<T, R, C> res = zeroMatrix<T, R, C>();
168  for (size_t r = 0; r < R; ++r)
169  for (size_t c = 0; c < C; ++c)
170  for (size_t k = 0; k < K; ++k)
171  res[r][c] += A[r][k] * B[k][c];
172  return res;
173 }
174 
181 template <typename T1, typename T2, size_t R, size_t K, size_t C>
183 -> const typename std::enable_if < (R != 1) or (C != 1), Matrix<typename std::remove_cv<decltype(operator*(A[0][0], B[0][0]))>::type, R, C> >::type
184 {
186  for (size_t r = 0; r < R; ++r)
187  for (size_t c = 0; c < C; ++c)
188  for (size_t k = 0; k < K; ++k)
189  res[r][c] += A[r][k] * B[k][c];
190  return res;
191 }
192 
194 template <typename T, size_t K>
195 const T operator*(const Matrix<T, 1, K>& A, const Matrix<T, K, 1>& B)
196 {
197  T res(0);
198  for (size_t k = 0; k < K; ++k)
199  res += A[0][k] * B[k][0];
200  return res;
201 }
202 
204 template <typename T, size_t R, size_t C>
206 {
207  for (auto& row : M)
208  for (auto& elt : row)
209  elt *= c;
210  return M;
211 }
212 
214 template <typename T1, typename T2, size_t R, size_t C>
216 {
217  for (auto& row : M)
218  for (auto& elt : row)
219  elt *= c;
220  return M;
221 }
222 
224 template <typename T, size_t R, size_t C>
225 const Matrix<T, R, C> operator*(const T& c, const Matrix<T, R, C>& M)
226 { auto m = M; m *= c; return m; }
227 
229 template <typename T1, typename T2, size_t R, size_t C>
230 const Matrix<T2, R, C> operator*(const T1& c, const Matrix<T2, R, C>& M)
231 { auto m = M; m *= c; return m; }
232 
234 template <typename T1, typename T2, size_t R, size_t C>
235 const Matrix<T2, R, C> operator*(const Matrix<T1, R, C>& M, const T2& c)
236 { return c * M; }
237 
239 template <typename T, size_t R, size_t C>
241 {
242  for (size_t r = 0; r < R; ++r)
243  for (size_t c = 0; c < C; ++c)
244  lhs[r][c] += rhs[r][c];
245  return lhs;
246 }
247 
249 template <typename T, size_t R, size_t C>
251 { auto m = lhs; m += rhs; return m; }
252 
254 template <typename T, size_t R, size_t C>
256 {
257  for (size_t r = 0; r < R; ++r)
258  for (size_t c = 0; c < C; ++c)
259  lhs[r][c] -= rhs[r][c];
260  return lhs;
261 }
262 
264 template <typename T, size_t R, size_t C>
266 { auto m = lhs; m -= rhs; return m; }
267 
271 template <typename T, size_t N>
272 const SquareMatrix < T, N - 1 > minor_matrix(const SquareMatrix<T, N>& M, size_t r, size_t c)
273 {
274  SquareMatrix < T, N - 1 > m;
275  for (size_t i = 0; i < N; ++i)
276  if (i != r)
277  for (size_t j = 0; j < N; ++j)
278  if (j != c)
279  m[i - (size_t)(i > r)][j - (size_t)(j > c)] = M[i][j];
280  return m;
281 }
282 
286 template <typename T, size_t N>
287 const T minor_det(const SquareMatrix<T, N>& M, size_t r, size_t c)
288 { return det(minor_matrix(M, r, c)); }
289 
293 template <typename T, size_t N>
294 const T cofactor(const SquareMatrix<T, N>& M, size_t r, size_t c)
295 { return pow_negative_one(r + c) * M[r][c] * minor_det(M, r, c); }
296 
299 template <typename T, size_t N>
300 const T det(SquareMatrix<T, N> M)
301 {
302  switch (N) {
303  case 0:
304  throw exceptions::Exception("zero-size matric", "determinant");
305  case 1:
306  return M[0][0];
307  case 2:
308  return M[0][0] * M[1][1] - M[0][1] * M[1][0];
309  case 3:
310  return M[0][0] * M[1][1] * M[2][2]
311  + M[0][1] * M[1][2] * M[2][0]
312  + M[0][2] * M[1][0] * M[2][1]
313  - M[0][2] * M[1][1] * M[2][0]
314  - M[0][0] * M[1][2] * M[2][1]
315  - M[0][1] * M[1][0] * M[2][2];
316  default:
317  T d(0);
318  for (size_t i = 0; i < N; ++i)
319  d += cofactor(M, i, 0);
320  return d;
321  }
322 }
323 
325 template <typename T, size_t M, size_t N>
326 const SquareMatrix<T, M> diagonal_minor(const SquareMatrix<T, N> m, std::vector<size_t> indices)
327 {
328  if (indices.size() != M)
329  throw exceptions::Exception("wrong number of indices provided", "diagonal_minor");
330 
331  SquareMatrix<T, M> dm;
332  for (size_t r = 0; r < indices.size(); ++r)
333  for (size_t c = 0; c < indices.size(); ++c)
334  dm[indices[r]][indices[c]] = m[r][c];
335  return dm;
336 }
337 
339 template <typename T, size_t N>
340 const T trace(const SquareMatrix<T, N>& M)
341 {
342  T t(0);
343  for (size_t i = 0; i < N; ++i)
344  t += M[i][i];
345  return t;
346 }
347 
348 }
349 #endif
const T det(SquareMatrix< T, N > M)
Definition: Matrix.h:300
Matrix(T element=0)
Definition: Matrix.h:50
Matrix< T, R, C > & operator+=(Matrix< T, R, C > &lhs, const Matrix< T, R, C > &rhs)
addition assignment
Definition: Matrix.h:240
const Matrix< T, C, R > transpose(const Matrix< T, R, C > &M)
transpose a matrix
Definition: Matrix.h:148
const SquareMatrix< T, N > zeroMatrix()
zero square matrix
Definition: Matrix.h:81
const SquareMatrix< T, N > diagonalMatrix(std::array< T, N > d)
diagonal matrix
Definition: Matrix.h:114
const size_t size(const ParameterVector &V)
Definition: Parameter.h:283
const SquareMatrix< T, N > symmetricMatrix(std::initializer_list< T > elements)
Definition: Matrix.h:125
const DataIterator operator-(const DataIterator &lhs, DataIterator::difference_type n)
subraction operator
Definition: DataPartition.h:139
const SquareMatrix< T, N-1 > minor_matrix(const SquareMatrix< T, N > &M, size_t r, size_t c)
Definition: Matrix.h:272
Base class for handling YAP exceptions.
Definition: Exceptions.h:39
const SquareMatrix< T, M > diagonal_minor(const SquareMatrix< T, N > m, std::vector< size_t > indices)
diagonal minor matrix
Definition: Matrix.h:326
const CoordinateSystem< T, N > operator*(const SquareMatrix< T, N > &M, const CoordinateSystem< T, N > &C)
Definition: CoordinateSystem.h:62
constexpr Matrix(const std::array< std::array< T, C >, R > &m) noexcept
Constructor.
Definition: Matrix.h:45
Matrix< T, R, C > & operator-=(Matrix< T, R, C > &lhs, const Matrix< T, R, C > &rhs)
subtraction assignment
Definition: Matrix.h:255
Matrix< T, R, C > & operator*=(Matrix< T, R, C > &M, const T &c)
assignment by multiplication by a single element
Definition: Matrix.h:205
const T minor_det(const SquareMatrix< T, N > &M, size_t r, size_t c)
Definition: Matrix.h:287
std::string to_string(const CachedValue::Status &S)
streaming operator for CachedValue::Status
Definition: CachedValue.cxx:27
const SquareMatrix< T, N > unitMatrix()
unit matrix
Definition: Matrix.h:103
const DataIterator operator+(DataIterator lhs, DataIterator::difference_type n)
addition operator
Definition: DataPartition.h:131
Definition: Matrix.h:41
std::string to_string(const Matrix< T, R, C > &M)
Definition: Matrix.h:62
const T trace(const SquareMatrix< T, N > &M)
trace
Definition: Matrix.h:340
const T cofactor(const SquareMatrix< T, N > &M, size_t r, size_t c)
Definition: Matrix.h:294
constexpr int pow_negative_one(int exponent)
optimized function for (-1)^n
Definition: MathUtilities.h:44