YAGE  0.02
Yet Another Game Engine
matrix.hpp
Go to the documentation of this file.
1 /* ----------------------------------------------------------------------------
2  * matrix.hpp
3  *
4  * Copyright (c) 2017 Yann Herklotz Grave <ymherklotz@gmail.com> -- MIT License
5  * See file LICENSE for more details
6  * ----------------------------------------------------------------------------
7  */
8 
10 
21 #ifndef YAGE_MATH_MATRIX_HPP
22 #define YAGE_MATH_MATRIX_HPP
23 
24 #include <algorithm>
25 #include <exception>
26 #include <iostream>
27 #include <sstream>
28 #include <string>
29 #include <vector>
30 
31 namespace yage
32 {
33 
34 template <int Rows, int Cols, class Type> class Matrix;
35 
43 namespace detail
44 {
45 
54 template <int Rows, int Cols, class Type> class Row
55 {
56 private:
58  int index_;
59 
60 public:
62  : parent_(parent), index_(index)
63  {
64  }
65 
66  Type &operator[](int col)
67  {
68  // the index is the y-position of the element in the matrix
69  return parent_->data_[index_ * Cols + col];
70  }
71 
72  const Type &operator[](int col) const
73  {
74  return parent_->data_[index_ * Cols + col];
75  }
76 };
77 
78 } // detail
79 
88 template <int Rows = 4, int Cols = 4, class Type = double> class Matrix
89 {
90  // friended with the row class so that it can access protected member data
91  friend class detail::Row<Rows, Cols, Type>;
92 
93 protected:
95  std::vector<Type> data_;
96 
97 public:
99  Matrix<Rows, Cols, Type>() : data_(Rows * Cols) {}
100  Matrix<Rows, Cols, Type>(const std::vector<Type> &data) : data_(data) {}
101 
103  int rowSize() const { return Rows; }
104 
106  int colSize() const { return Cols; }
107 
115  {
116  Matrix<1, Cols, Type> rowMatrix;
117  for (int i = 0; i < Cols; ++i) {
118  rowMatrix[0][i] = data_[row][i];
119  }
120  return rowMatrix;
121  }
122 
123  // returns the column in a column matrix
125  {
126  Matrix<Rows, 1, Type> colMatrix;
127  for (int i = 0; i < Rows; ++i) {
128  colMatrix[i][0] = data_[i][col];
129  }
130  return colMatrix;
131  }
132 
134  typename std::vector<Type>::iterator begin() { return data_.begin(); }
135 
137  typename std::vector<Type>::iterator end() { return data_.end(); }
138 
142  virtual std::string toString() const
143  {
144  std::stringstream ss;
145  ss << '[';
146  for (int i = 0; i < Rows - 1; ++i) {
147  ss << '[';
148  for (int j = 0; j < Cols - 1; ++j) {
149  ss << data_[i * Cols + j] << ' ';
150  }
151  ss << data_[(Rows - 1) * Cols + Cols - 1] << "],";
152  }
153  ss << '[';
154  for (int j = 0; j < Cols - 1; ++j) {
155  ss << data_[(Rows - 1) * Cols + j] << ' ';
156  }
157  ss << data_[(Rows - 1) * Cols + Cols - 1] << "]]";
158  return ss.str();
159  }
160 
162  {
163  return detail::Row<Rows, Cols, Type>(this, row);
164  }
165 
167  {
168  // @todo got to fix this
170  row);
171  }
172 
174  {
175  std::vector<Type> out;
176  out.reserve(data_.size());
177  std::transform(data_.begin(), data_.end(), rhs.data_.begin(),
178  std::back_inserter(out),
179  [](Type a, Type b) { return a + b; });
180  data_ = std::move(out);
181  return *this;
182  }
183 
185  {
186  std::vector<Type> out;
187  out.reserve(data_.size());
188  std::transform(data_.begin(), data_.end(), rhs.begin(),
189  std::back_inserter(out),
190  [](Type a, Type b) { return a - b; });
191  data_ = std::move(out);
192  return *this;
193  }
194 };
195 
196 template <int M, int N, class T>
198 {
199  lhs += rhs;
200  return lhs;
201 }
202 
203 template <int M, int N, class T>
205 {
206  lhs -= rhs;
207  return lhs;
208 }
209 
210 template <int M, int N, class T>
212 {
213  for (auto &data : lhs) {
214  data += rhs;
215  }
216  return lhs;
217 }
218 
219 template <int M, int N, class T>
221 {
222  for (auto &data : rhs) {
223  data += lhs;
224  }
225  return rhs;
226 }
227 
228 template <int M, int N, class T>
230 {
231  for (auto &data : lhs) {
232  data -= rhs;
233  }
234  return lhs;
235 }
236 
237 template <int M, int N, class T>
239 {
240  for (auto &data : rhs) {
241  data = lhs - data;
242  }
243  return rhs;
244 }
245 
246 template <int M, int N, class T>
248 {
249  for (auto &data : lhs) {
250  data *= rhs;
251  }
252  return lhs;
253 }
254 
255 template <int M, int N, class T>
257 {
258  for (auto &data : rhs) {
259  data *= lhs;
260  }
261  return rhs;
262 }
263 
264 template <int M, int N, class T>
266 {
267  for (auto &data : lhs) {
268  data /= rhs;
269  }
270  return lhs;
271 }
272 
273 template <int M, int N, class T>
274 bool operator==(const Matrix<M, N, T> &lhs, const Matrix<M, N, T> &rhs)
275 {
276  for (int i = 0; i < M; ++i) {
277  for (int j = 0; j < N; ++j) {
278  if (lhs[i][j] != rhs[i][j]) {
279  return false;
280  }
281  }
282  }
283  return true;
284 }
285 
286 template <int M, int N, class T>
287 std::ostream &operator<<(std::ostream &os, const Matrix<M, N, T> &mat)
288 {
289  return os << mat.toString();
290 }
291 
292 template <int Rows = 2, class Type = double>
293 class Vector : public Matrix<Rows, 1, Type>
294 {
295 public:
298  : Matrix<Rows, 1, Type>(other)
299  {
300  }
301  Vector<Rows, Type>(const std::vector<Type> &data)
302  : Matrix<Rows, 1, Type>(data)
303  {
304  }
305 
306  Type &operator[](int col) { return this->data_[col]; }
307 
308  const Type &operator[](int col) const { return this->data_[col]; }
309 
310  std::string toString() const override
311  {
312  std::stringstream ss;
313  ss << "[";
314  for (std::size_t i = 0; i < this->data_.size() - 1; ++i) {
315  ss << this->data_[i] << " ";
316  }
317  ss << this->data_[this->data_.size() - 1] << "]";
318  return ss.str();
319  }
320 };
321 
326 template <class Type = double> class Vector2 : public Vector<2, Type>
327 {
328 public:
330  Vector2<Type>(const std::vector<Type> &data) : Vector<2, Type>(data) {}
331 
332  Vector2<Type>(Type x, Type y)
333  {
334  this->data_[0] = x;
335  this->data_[1] = y;
336  }
337 
339 
340  Type &x() { return this->data_[0]; }
341 
342  const Type &x() const { return this->data_[0]; }
343 
344  Type &y() { return this->data_[1]; }
345 
346  const Type &y() const { return this->data_[1]; }
347 };
348 
351 
353 namespace matrix
354 {
355 
360 template <int M, int N, class T>
362 {
363  Matrix<N, M, T> trans;
364  for (int i = 0; i < M; ++i) {
365  for (int j = 0; j < N; ++j) {
366  trans[j][i] = m[i][j];
367  }
368  }
369  return trans;
370 }
371 
376 template <int R, class T>
377 T dot(const Matrix<R, 1, T> &m1, const Matrix<R, 1, T> &m2)
378 {
379  T sum = 0;
380  for (int i = 0; i < R; ++i) {
381  sum += m1[i][0] * m2[i][0];
382  }
383  return sum;
384 }
385 
392 template <int M, int N, int P, int Q, class T>
394 {
395  if (N != P) {
396  throw std::runtime_error(
397  "Matrices don't have the right dimensions for multiplication");
398  }
399 
400  Matrix<M, Q, T> res;
401 
402  for (int i = 0; i < M; ++i) {
403  for (int j = 0; j < Q; ++j) {
404  res[i][j] = dot(transpose(m1.getRow(i)), m2.getCol(j));
405  }
406  }
407 
408  return res;
409 }
410 
411 } // matrix
412 
413 } // yage
414 
415 #endif
Matrix< M, N, T > operator/(Matrix< M, N, T > lhs, const T &rhs)
Definition: matrix.hpp:265
const Type & y() const
Definition: matrix.hpp:346
Matrix< M, N, T > operator*(Matrix< M, N, T > lhs, const T &rhs)
Definition: matrix.hpp:247
int rowSize() const
Returns the row size of the Matrix.
Definition: matrix.hpp:103
int colSize() const
Returns the column size of the Matrixxs.
Definition: matrix.hpp:106
2D Vector class.
Definition: matrix.hpp:326
bool operator==(const Matrix< M, N, T > &lhs, const Matrix< M, N, T > &rhs)
Definition: matrix.hpp:274
std::vector< Type >::iterator end()
iterator support for end
Definition: matrix.hpp:137
Matrix< Rows, 1, Type > getCol(int col) const
Definition: matrix.hpp:124
Type & operator[](int col)
Definition: matrix.hpp:306
std::vector< Type > data_
Vector containing the data of the matrix.
Definition: matrix.hpp:95
Matrix< M, Q, T > multiply(const Matrix< M, N, T > &m1, const Matrix< P, Q, T > &m2)
Multiplies two matrices together.
Definition: matrix.hpp:393
const Type & operator[](int col) const
Definition: matrix.hpp:72
Type & y()
Definition: matrix.hpp:344
detail::Row< Rows, Cols, Type > operator[](int row) const
Definition: matrix.hpp:166
Definition: matrix.hpp:54
Matrix< Rows, Cols, Type > * parent_
Definition: matrix.hpp:57
int index_
Definition: matrix.hpp:58
Matrix< N, M, T > transpose(const Matrix< M, N, T > &m)
Transposes a matrix and returns the result.
Definition: matrix.hpp:361
Matrix< Rows, Cols, Type > & operator-=(const Matrix< Rows, Cols, Type > &rhs)
Definition: matrix.hpp:184
Type & x()
Definition: matrix.hpp:340
Matrix< M, N, T > operator+(Matrix< M, N, T > lhs, const Matrix< M, N, T > &rhs)
Definition: matrix.hpp:197
Definition: matrix.hpp:293
Matrix< M, N, T > operator-(Matrix< M, N, T > lhs, const Matrix< M, N, T > &rhs)
Definition: matrix.hpp:204
Matrix< Rows, Cols, Type > & operator+=(const Matrix< Rows, Cols, Type > &rhs)
Definition: matrix.hpp:173
Type & operator[](int col)
Definition: matrix.hpp:66
Base Matrix class used by other similar classes.
Definition: matrix.hpp:34
virtual std::string toString() const
prints out the matrix, but can also be implemented by other classes to print data differently ...
Definition: matrix.hpp:142
T dot(const Matrix< R, 1, T > &m1, const Matrix< R, 1, T > &m2)
Returns the dot product between two vectors.
Definition: matrix.hpp:377
Matrix< 1, Cols, Type > getRow(int row) const
Return the row specified row as a Matrix with only one row.
Definition: matrix.hpp:114
std::string toString() const override
prints out the matrix, but can also be implemented by other classes to print data differently ...
Definition: matrix.hpp:310
const Type & x() const
Definition: matrix.hpp:342
Templated matrix class.
Definition: camera2d.hpp:17
std::vector< Type >::iterator begin()
iterator support for begin
Definition: matrix.hpp:134
detail::Row< Rows, Cols, Type > operator[](int row)
Definition: matrix.hpp:161
const Type & operator[](int col) const
Definition: matrix.hpp:308