diff options
Diffstat (limited to 'include/YAGE/Math/matrix.hpp')
-rw-r--r-- | include/YAGE/Math/matrix.hpp | 180 |
1 files changed, 109 insertions, 71 deletions
diff --git a/include/YAGE/Math/matrix.hpp b/include/YAGE/Math/matrix.hpp index e4583290..249edcc7 100644 --- a/include/YAGE/Math/matrix.hpp +++ b/include/YAGE/Math/matrix.hpp @@ -28,10 +28,10 @@ #include <string> #include <vector> -namespace yage { +namespace yage +{ -template <int Rows, int Cols, class Type> -class Matrix; +template <int Rows, int Cols, class Type> class Matrix; /** @internal Namespace for internal details. * @@ -40,7 +40,8 @@ class Matrix; * * This is the namespace used for implementation detail. */ -namespace detail { +namespace detail +{ /** @internal Internal Row class used by the Matrix class to return the * internal data structure of the Matrix. @@ -50,27 +51,31 @@ namespace detail { * * Internal Row class to return a value in the row of the matrix. */ -template <int Rows, int Cols, class Type> -class Row { +template <int Rows, int Cols, class Type> class Row +{ private: - Matrix<Rows, Cols, Type>* parent_; + Matrix<Rows, Cols, Type> *parent_; int index_; public: - Row<Rows, Cols, Type>(Matrix<Rows, Cols, Type>* parent, int index) - : parent_(parent), index_(index) {} + Row<Rows, Cols, Type>(Matrix<Rows, Cols, Type> *parent, int index) + : parent_(parent), index_(index) + { + } - Type& operator[](int col) { + Type &operator[](int col) + { // the index is the y-position of the element in the matrix return parent_->data_[index_ * Cols + col]; } - const Type& operator[](int col) const { + const Type &operator[](int col) const + { return parent_->data_[index_ * Cols + col]; } }; -} // detail +} // detail /** Base Matrix class used by other similar classes. * @@ -80,8 +85,8 @@ public: * This is the base matrix class that can be used by all the other matrix * like data structures. */ -template <int Rows = 4, int Cols = 4, class Type = double> -class Matrix { +template <int Rows = 4, int Cols = 4, class Type = double> class Matrix +{ // friended with the row class so that it can access protected member data friend class detail::Row<Rows, Cols, Type>; @@ -92,7 +97,7 @@ protected: public: /// Initializes the size of the data_ vector Matrix<Rows, Cols, Type>() : data_(Rows * Cols) {} - Matrix<Rows, Cols, Type>(const std::vector<Type>& data) : data_(data) {} + Matrix<Rows, Cols, Type>(const std::vector<Type> &data) : data_(data) {} /// Returns the row size of the Matrix int rowSize() const { return Rows; } @@ -102,11 +107,12 @@ public: /** Return the row specified row as a Matrix with only one row * - * \param[in] row Row number to be returned + * @param row Row number to be returned * * Returns the row that is specified by the row variables. */ - Matrix<1, Cols, Type> getRow(int row) const { + Matrix<1, Cols, Type> getRow(int row) const + { Matrix<1, Cols, Type> rowMatrix; for (int i = 0; i < Cols; ++i) { rowMatrix[0][i] = data_[row][i]; @@ -115,7 +121,8 @@ public: } // returns the column in a column matrix - Matrix<Rows, 1, Type> getCol(int col) const { + Matrix<Rows, 1, Type> getCol(int col) const + { Matrix<Rows, 1, Type> colMatrix; for (int i = 0; i < Rows; ++i) { colMatrix[i][0] = data_[i][col]; @@ -130,9 +137,10 @@ public: typename std::vector<Type>::iterator end() { return data_.end(); } /** prints out the matrix, but can also be implemented by other classes to - * print data differently - */ - virtual std::string toString() const { + * print data differently + */ + virtual std::string toString() const + { std::stringstream ss; ss << '['; for (int i = 0; i < Rows - 1; ++i) { @@ -150,17 +158,20 @@ public: return ss.str(); } - detail::Row<Rows, Cols, Type> operator[](int row) { + detail::Row<Rows, Cols, Type> operator[](int row) + { return detail::Row<Rows, Cols, Type>(this, row); } - detail::Row<Rows, Cols, Type> operator[](int row) const { - // TODO got to fix this - return detail::Row<Rows, Cols, Type>((Matrix<Rows, Cols, Type>*)this, + detail::Row<Rows, Cols, Type> operator[](int row) const + { + // @todo got to fix this + return detail::Row<Rows, Cols, Type>((Matrix<Rows, Cols, Type> *)this, row); } - Matrix<Rows, Cols, Type>& operator+=(const Matrix<Rows, Cols, Type>& rhs) { + Matrix<Rows, Cols, Type> &operator+=(const Matrix<Rows, Cols, Type> &rhs) + { std::vector<Type> out; out.reserve(data_.size()); std::transform(data_.begin(), data_.end(), rhs.data_.begin(), @@ -170,7 +181,8 @@ public: return *this; } - Matrix<Rows, Cols, Type>& operator-=(const Matrix<Rows, Cols, Type>& rhs) { + Matrix<Rows, Cols, Type> &operator-=(const Matrix<Rows, Cols, Type> &rhs) + { std::vector<Type> out; out.reserve(data_.size()); std::transform(data_.begin(), data_.end(), rhs.begin(), @@ -182,100 +194,121 @@ public: }; template <int M, int N, class T> -Matrix<M, N, T> operator+(Matrix<M, N, T> lhs, const Matrix<M, N, T>& rhs) { +Matrix<M, N, T> operator+(Matrix<M, N, T> lhs, const Matrix<M, N, T> &rhs) +{ lhs += rhs; return lhs; } template <int M, int N, class T> -Matrix<M, N, T> operator-(Matrix<M, N, T> lhs, const Matrix<M, N, T>& rhs) { +Matrix<M, N, T> operator-(Matrix<M, N, T> lhs, const Matrix<M, N, T> &rhs) +{ lhs -= rhs; return lhs; } template <int M, int N, class T> -Matrix<M, N, T> operator+(Matrix<M, N, T> lhs, const T& rhs) { - for (auto& data : lhs) { +Matrix<M, N, T> operator+(Matrix<M, N, T> lhs, const T &rhs) +{ + for (auto &data : lhs) { data += rhs; } return lhs; } template <int M, int N, class T> -Matrix<M, N, T> operator+(const T& lhs, Matrix<M, N, T> rhs) { - for (auto& data : rhs) { +Matrix<M, N, T> operator+(const T &lhs, Matrix<M, N, T> rhs) +{ + for (auto &data : rhs) { data += lhs; } return rhs; } template <int M, int N, class T> -Matrix<M, N, T> operator-(Matrix<M, N, T> lhs, const T& rhs) { - for (auto& data : lhs) { +Matrix<M, N, T> operator-(Matrix<M, N, T> lhs, const T &rhs) +{ + for (auto &data : lhs) { data -= rhs; } return lhs; } template <int M, int N, class T> -Matrix<M, N, T> operator-(const T& lhs, Matrix<M, N, T> rhs) { - for (auto& data : rhs) { +Matrix<M, N, T> operator-(const T &lhs, Matrix<M, N, T> rhs) +{ + for (auto &data : rhs) { data = lhs - data; } return rhs; } template <int M, int N, class T> -Matrix<M, N, T> operator*(Matrix<M, N, T> lhs, const T& rhs) { - for (auto& data : lhs) { +Matrix<M, N, T> operator*(Matrix<M, N, T> lhs, const T &rhs) +{ + for (auto &data : lhs) { data *= rhs; } return lhs; } template <int M, int N, class T> -Matrix<M, N, T> operator*(const T& lhs, Matrix<M, N, T> rhs) { - for (auto& data : rhs) { +Matrix<M, N, T> operator*(const T &lhs, Matrix<M, N, T> rhs) +{ + for (auto &data : rhs) { data *= lhs; } return rhs; } template <int M, int N, class T> -Matrix<M, N, T> operator/(Matrix<M, N, T> lhs, const T& rhs) { - for (auto& data : lhs) { +Matrix<M, N, T> operator/(Matrix<M, N, T> lhs, const T &rhs) +{ + for (auto &data : lhs) { data /= rhs; } return lhs; } template <int M, int N, class T> -bool operator==(const Matrix<M, N, T>& lhs, const Matrix<M, N, T>& rhs) { - for (int i = 0; i < M; ++i) - for (int j = 0; j < N; ++j) - if (lhs[i][j] != rhs[i][j]) return false; +bool operator==(const Matrix<M, N, T> &lhs, const Matrix<M, N, T> &rhs) +{ + for (int i = 0; i < M; ++i) { + for (int j = 0; j < N; ++j) { + if (lhs[i][j] != rhs[i][j]) { + return false; + } + } + } return true; } template <int M, int N, class T> -std::ostream& operator<<(std::ostream& os, const Matrix<M, N, T>& mat) { +std::ostream &operator<<(std::ostream &os, const Matrix<M, N, T> &mat) +{ return os << mat.toString(); } template <int Rows = 2, class Type = double> -class Vector : public Matrix<Rows, 1, Type> { +class Vector : public Matrix<Rows, 1, Type> +{ public: Vector<Rows, Type>() : Matrix<Rows, 1, Type>() {} - Vector<Rows, Type>(const Matrix<Rows, 1, Type>& other) - : Matrix<Rows, 1, Type>(other) {} - Vector<Rows, Type>(const std::vector<Type>& data) - : Matrix<Rows, 1, Type>(data) {} + Vector<Rows, Type>(const Matrix<Rows, 1, Type> &other) + : Matrix<Rows, 1, Type>(other) + { + } + Vector<Rows, Type>(const std::vector<Type> &data) + : Matrix<Rows, 1, Type>(data) + { + } - Type& operator[](int col) { return this->data_[col]; } + Type &operator[](int col) { return this->data_[col]; } - const Type& operator[](int col) const { return this->data_[col]; } + const Type &operator[](int col) const { return this->data_[col]; } - std::string toString() const override { + std::string toString() const override + { std::stringstream ss; ss << "["; for (std::size_t i = 0; i < this->data_.size() - 1; ++i) { @@ -290,40 +323,43 @@ public: * * Two dimensional vector class. */ -template <class Type = double> -class Vector2 : public Vector<2, Type> { +template <class Type = double> class Vector2 : public Vector<2, Type> +{ public: Vector2<Type>() : Vector<2, Type>() {} - Vector2<Type>(const std::vector<Type>& data) : Vector<2, Type>(data) {} + Vector2<Type>(const std::vector<Type> &data) : Vector<2, Type>(data) {} - Vector2<Type>(Type x, Type y) { + Vector2<Type>(Type x, Type y) + { this->data_[0] = x; this->data_[1] = y; } - Vector2<Type>(const Matrix<2, 1, Type>& other) : Vector<2, Type>(other) {} + Vector2<Type>(const Matrix<2, 1, Type> &other) : Vector<2, Type>(other) {} - Type& x() { return this->data_[0]; } + Type &x() { return this->data_[0]; } - const Type& x() const { return this->data_[0]; } + const Type &x() const { return this->data_[0]; } - Type& y() { return this->data_[1]; } + Type &y() { return this->data_[1]; } - const Type& y() const { return this->data_[1]; } + const Type &y() const { return this->data_[1]; } }; /// Definition of a 2D vector. using Vector2d = Vector2<double>; /** Namespace containing functions that operate on matrices. */ -namespace matrix { +namespace matrix +{ /** Transposes a matrix and returns the result * * \param[in] m input matrix. */ template <int M, int N, class T> -Matrix<N, M, T> transpose(const Matrix<M, N, T>& m) { +Matrix<N, M, T> transpose(const Matrix<M, N, T> &m) +{ Matrix<N, M, T> trans; for (int i = 0; i < M; ++i) { for (int j = 0; j < N; ++j) { @@ -338,7 +374,8 @@ Matrix<N, M, T> transpose(const Matrix<M, N, T>& m) { * \param[in] m1,m2 Input matrices. */ template <int R, class T> -T dot(const Matrix<R, 1, T>& m1, const Matrix<R, 1, T>& m2) { +T dot(const Matrix<R, 1, T> &m1, const Matrix<R, 1, T> &m2) +{ T sum = 0; for (int i = 0; i < R; ++i) { sum += m1[i][0] * m2[i][0]; @@ -353,7 +390,8 @@ T dot(const Matrix<R, 1, T>& m1, const Matrix<R, 1, T>& m2) { * Requires the two matrices to be compatible with multiplication. */ template <int M, int N, int P, int Q, class T> -Matrix<M, Q, T> multiply(const Matrix<M, N, T>& m1, const Matrix<P, Q, T>& m2) { +Matrix<M, Q, T> multiply(const Matrix<M, N, T> &m1, const Matrix<P, Q, T> &m2) +{ if (N != P) { throw std::runtime_error( "Matrices don't have the right dimensions for multiplication"); @@ -370,8 +408,8 @@ Matrix<M, Q, T> multiply(const Matrix<M, N, T>& m1, const Matrix<P, Q, T>& m2) { return res; } -} // matrix +} // matrix -} // yage +} // yage #endif |