From 1a8ec165031af3b860028ef1b360acc8e7baf9e6 Mon Sep 17 00:00:00 2001 From: TravisBot <> Date: Thu, 21 Sep 2017 23:32:46 +0000 Subject: Rebuilding documentation --- yage/math/CMakeLists.txt | 1 + yage/math/math.h | 14 ++ yage/math/matrix.h | 424 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 439 insertions(+) create mode 100644 yage/math/CMakeLists.txt create mode 100644 yage/math/math.h create mode 100644 yage/math/matrix.h (limited to 'yage/math') diff --git a/yage/math/CMakeLists.txt b/yage/math/CMakeLists.txt new file mode 100644 index 00000000..761ab59f --- /dev/null +++ b/yage/math/CMakeLists.txt @@ -0,0 +1 @@ +set(YAGE_MATH_SOURCES) diff --git a/yage/math/math.h b/yage/math/math.h new file mode 100644 index 00000000..b729dbe6 --- /dev/null +++ b/yage/math/math.h @@ -0,0 +1,14 @@ +/* ---------------------------------------------------------------------------- + * math.h + * + * Copyright (c) 2017 Yann Herklotz Grave -- MIT License + * See file LICENSE for more details + * ---------------------------------------------------------------------------- + */ + +#ifndef YAGE_MATH_H +#define YAGE_MATH_H + +#include "matrix.h" + +#endif diff --git a/yage/math/matrix.h b/yage/math/matrix.h new file mode 100644 index 00000000..3df1509d --- /dev/null +++ b/yage/math/matrix.h @@ -0,0 +1,424 @@ +/* ---------------------------------------------------------------------------- + * matrix.h + * + * Copyright (c) 2017 Yann Herklotz Grave -- MIT License + * See file LICENSE for more details + * ---------------------------------------------------------------------------- + */ + +/** @file + */ + +#ifndef YAGE_MATH_MATRIX_H +#define YAGE_MATH_MATRIX_H + +#include +#include +#include +#include +#include +#include + +namespace yage +{ + +template +class Matrix; + +/** @internal Namespace for internal details. + * + * Details Namespace + * ================ + * + * This is the namespace used for implementation details. + */ +namespace details +{ + +/** @internal Internal Row class used by the Matrix class to return the + * internal data structure of the Matrix. + * + * Row + * === + * + * Internal Row class to return a value in the row of the matrix. + */ +template +class Row +{ +private: + Matrix *parent_; + int index_; + +public: + Row(Matrix *parent, int index) + : parent_(parent), index_(index) + { + } + + 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 + { + return parent_->data_[index_ * Cols + col]; + } +}; + +} // namespace details + +/** Base Matrix class used by other similar classes. + */ +template +class Matrix +{ + // friended with the row class so that it can access protected member data. + friend class details::Row; + +protected: + /// Vector containing the data of the matrix. + std::vector data_; + +public: + /// Initializes the size of the data_ vector. + Matrix() : data_(Rows * Cols) {} + Matrix(const std::vector &data) : data_(data) {} + + /// Returns the row size of the Matrix. + int rowSize() const { return Rows; } + + /// Returns the column size of the Matrix. + int colSize() const { return Cols; } + + /** Return the row specified row as a Matrix with only one row. + * + * @param row Row number to be returned. + * @return The row that is specified by the row variables. + */ + 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]; + } + return rowMatrix; + } + + /** Get a specific column in a column vector. + * + * @param col Column number to be returned. + * @return Column Matrix of the selected column. + */ + Matrix getCol(int col) const + { + Matrix colMatrix; + for (int i = 0; i < Rows; ++i) { + colMatrix[i][0] = data_[i][col]; + } + return colMatrix; + } + + /** Iterator support for the start. + * + * @return Iterator pointing to the start of the data. + */ + typename std::vector::iterator begin() { return data_.begin(); } + + /** Iterator support for the end. + * + * @return Iterator pointing to the end of the data. + */ + typename std::vector::iterator end() { return data_.end(); } + + /** Prints out the matrix, but can also be implemented by other classes to + * print data differently. + * + * @bug When printing certain matrices, it omits a row or column. Still + * need to determine under which conditions. + */ + virtual std::string toString() const + { + std::stringstream ss; + ss << '['; + for (int i = 0; i < Rows - 1; ++i) { + ss << '['; + for (int j = 0; j < Cols - 1; ++j) { + ss << data_[i * Cols + j] << ' '; + } + ss << data_[(Rows - 1) * Cols + Cols - 1] << "],"; + } + ss << '['; + for (int j = 0; j < Cols - 1; ++j) { + ss << data_[(Rows - 1) * Cols + j] << ' '; + } + ss << data_[(Rows - 1) * Cols + Cols - 1] << "]]"; + return ss.str(); + } + + details::Row operator[](int row) + { + return details::Row(this, row); + } + + details::Row operator[](int row) const + { + return details::Row((Matrix *)this, + row); + } + + Matrix &operator+=(const Matrix &rhs) + { + std::vector out; + out.reserve(data_.size()); + std::transform(data_.begin(), data_.end(), rhs.data_.begin(), + std::back_inserter(out), + [](Type a, Type b) { return a + b; }); + data_ = std::move(out); + return *this; + } + + Matrix &operator-=(const Matrix &rhs) + { + std::vector out; + out.reserve(data_.size()); + std::transform(data_.begin(), data_.end(), rhs.begin(), + std::back_inserter(out), + [](Type a, Type b) { return a - b; }); + data_ = std::move(out); + return *this; + } +}; + +template +Matrix operator+(Matrix lhs, const Matrix &rhs) +{ + lhs += rhs; + return lhs; +} + +template +Matrix operator-(Matrix lhs, const Matrix &rhs) +{ + lhs -= rhs; + return lhs; +} + +template +Matrix operator+(Matrix lhs, const T &rhs) +{ + for (auto &data : lhs) { + data += rhs; + } + return lhs; +} + +template +Matrix operator+(const T &lhs, Matrix rhs) +{ + for (auto &data : rhs) { + data += lhs; + } + return rhs; +} + +template +Matrix operator-(Matrix lhs, const T &rhs) +{ + for (auto &data : lhs) { + data -= rhs; + } + return lhs; +} + +template +Matrix operator-(const T &lhs, Matrix rhs) +{ + for (auto &data : rhs) { + data = lhs - data; + } + return rhs; +} + +template +Matrix operator*(Matrix lhs, const T &rhs) +{ + for (auto &data : lhs) { + data *= rhs; + } + return lhs; +} + +template +Matrix operator*(const T &lhs, Matrix rhs) +{ + for (auto &data : rhs) { + data *= lhs; + } + return rhs; +} + +template +Matrix operator/(Matrix lhs, const T &rhs) +{ + for (auto &data : lhs) { + data /= rhs; + } + return lhs; +} + +template +bool operator==(const Matrix &lhs, const Matrix &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 +std::ostream &operator<<(std::ostream &os, const Matrix &mat) +{ + return os << mat.toString(); +} + +template +class Vector : public Matrix +{ +public: + Vector() : Matrix() {} + Vector(const Matrix &other) + : Matrix(other) + { + } + + Vector(const std::vector &data) + : Matrix(data) + { + } + + Type &operator[](int col) { return this->data_[col]; } + + const Type &operator[](int col) const { return this->data_[col]; } + + std::string toString() const override + { + std::stringstream ss; + ss << "["; + for (std::size_t i = 0; i < this->data_.size() - 1; ++i) { + ss << this->data_[i] << " "; + } + ss << this->data_[this->data_.size() - 1] << "]"; + return ss.str(); + } +}; + +/** 2D Vector class. + * + * Two dimensional vector class. + */ +template +class Vector2 : public Vector<2, Type> +{ +public: + Vector2() : Vector<2, Type>() {} + Vector2(const std::vector &data) : Vector<2, Type>(data) {} + + Vector2(Type x, Type y) + { + this->data_[0] = x; + this->data_[1] = y; + } + + Vector2(const Matrix<2, 1, Type> &other) : Vector<2, Type>(other) {} + + Type &x() { return this->data_[0]; } + + const Type &x() const { return this->data_[0]; } + + Type &y() { return this->data_[1]; } + + const Type &y() const { return this->data_[1]; } +}; + +/** Definition of a 2D vector. + */ +using Vector2d = Vector2; + +/** Namespace containing functions that operate on matrices. + * + * Implementations defined here are meant to operate on anything that inherits + * from the base Matrix class. + */ +namespace matrix +{ + +/** Transposes a matrix and returns the result + * + * @param m input matrix. + */ +template +Matrix transpose(const Matrix &m) +{ + Matrix trans; + for (int i = 0; i < M; ++i) { + for (int j = 0; j < N; ++j) { + trans[j][i] = m[i][j]; + } + } + return trans; +} + +/** Returns the dot product between two vectors + * + * @param m1,m2 Input matrices. + */ +template +T dot(const Matrix &m1, const Matrix &m2) +{ + T sum = 0; + for (int i = 0; i < R; ++i) { + sum += m1[i][0] * m2[i][0]; + } + return sum; +} + +/** Multiplies two matrices together. + * + * @param m1,m2 Matrix inputs + * + * Requires the two matrices to be compatible with multiplication. + */ +template +Matrix multiply(const Matrix &m1, const Matrix &m2) +{ + /// @todo Think if this should be a static_assert. + if (N != P) { + throw std::runtime_error( + "Matrices don't have the right dimensions for multiplication"); + } + + Matrix res; + + /// Performs multiplication by getting the rows and columns, transposing + /// one of them and then doting the result. + for (int i = 0; i < M; ++i) { + for (int j = 0; j < Q; ++j) { + res[i][j] = dot(transpose(m1.getRow(i)), m2.getCol(j)); + } + } + + return res; +} + +} // namespace matrix + +} // namespace yage + +#endif -- cgit