diff options
Diffstat (limited to 'meowpp/math/Matrix.h')
-rw-r--r-- | meowpp/math/Matrix.h | 103 |
1 files changed, 68 insertions, 35 deletions
diff --git a/meowpp/math/Matrix.h b/meowpp/math/Matrix.h index b4b4853..09832d8 100644 --- a/meowpp/math/Matrix.h +++ b/meowpp/math/Matrix.h @@ -1,8 +1,6 @@ #ifndef math_Matrix_H__ #define math_Matrix_H__ -#include "utility.h" - #include "../Self.h" #include <vector> @@ -18,25 +16,32 @@ namespace meow { */ template<class Entry> class Matrix { +public: + typedef typename std::vector<Entry>::reference EntryRef ; + typedef typename std::vector<Entry>::const_reference EntryRefK; private: struct Myself { size_t rows_; size_t cols_; std::vector<Entry> entries_; - Myself(): rows_(0), cols_(0), entries_(0) { + + Myself(): + rows_(0), cols_(0), entries_(0) { + } + Myself(Myself const& b): + rows_(b.rows_), cols_(b.cols_), entries_(b.entries_) { + } + Myself(size_t r, size_t c, Entry const& e): + rows_(r), cols_(c), entries_(r * c, e) { } ~Myself() { } + size_t index(size_t r, size_t c) const { return r * cols_ + c; } - Myself& copyFrom(Myself const& m) { - rows_ = m. rows_; - cols_ = m. cols_; - entries_ = m.entries_; - return *this; - } }; + Self<Myself> const self; public: /*! @@ -45,7 +50,7 @@ public: * Create an empty matrix with size \b 0x0. * In other world, create an \b invalid matrix */ - Matrix(): self(true) { } + Matrix(): self() { } /*! * @brief constructor @@ -54,7 +59,8 @@ public: * * @param [in] m another matrix */ - Matrix(Matrix const& m): self(false) { self().copyFrom(m.self); } + Matrix(Matrix const& m): self(m.self, Self<Myself>::COPY_FROM) { + } /*! * @brief constructor @@ -65,7 +71,8 @@ public: * @param [in] c number of columns * @param [in] e inital entry */ - Matrix(size_t r, size_t c, Entry const& e): self(true) { reset(r, c, e); } + Matrix(size_t r, size_t c, Entry const& e): self(Myself(r, c, e)) { + } //! @brief destructor ~Matrix() { } @@ -152,8 +159,7 @@ public: */ size_t cols(size_t c, Entry const& e) { if (c != cols()) { - Self<Myself> const old(false); - old().copyFrom(self); + Self<Myself> const old(self, Self<Myself>::COPY_FROM); self()->entries_.resize(rows() * c); self()->cols_ = c; for (size_t i = 0, I = rows(); i < I; i++) { @@ -169,7 +175,7 @@ public: /*! * @brief resize - * + * * Resize to \a r x \a c, with new created entry be \a e * * @param [in] r number of rows @@ -193,14 +199,19 @@ public: self()->entries_[self->index(r, c)] = e; return entry(r, c); } + + //! @brief Get the entry at \a r x \a c + EntryRef entryGet(size_t r, size_t c) { + return self()->entries_[self->index(r, c)]; + } /*! * @brief Change the entries from \a rFirst x \a cFirst to \a rLast x \a cLast - * - * @param [in] rFirst - * @param [in] rLast + * + * @param [in] rFirst + * @param [in] rLast * @param [in] cFirst - * @param [in] cLast + * @param [in] cLast * @param [in] e value * @return void */ @@ -218,7 +229,7 @@ public: * @brief Return a \a rLast-rFirst+1 x \a cLast-cFirst+1 matrix * * With value be the entries from \a rFirst x \a cFirst to \a rLast x \a cLast - * + * * @param [in] rFirst * @param [in] rLast * @param [in] cFirst @@ -228,7 +239,7 @@ public: Matrix subMatrix(size_t rFirst, size_t rLast, size_t cFirst, size_t cLast) const { if (rFirst > rLast || cFirst > cLast) return Matrix(); - if (rFirst == 0 || cFirst == 0) { + if (rFirst == 0 && cFirst == 0) { Matrix ret(*this); ret.size(rLast + 1, cLast + 1, Entry(0)); return ret; @@ -340,6 +351,28 @@ public: entry(r, c, (r == c ? Entry(1) : Entry(0))); return *this; } + + /*! + * @brief Let itself be an diagonal form of original itself + */ + Matrix& diagonaled() { + triangulared(); + for (size_t i = 0, I = rows(); i < I; ++i) { + for (size_t j = i + 1, J = cols(); j < J; ++j) { + entry(i, j, Entry(0)); + } + } + return *this; + } + + /*! + * @brief Return a matrix which is a diangonal form of me + */ + Matrix diagonal() const { + Matrix ret(*this); + ret.diagonaled(); + return ret; + } /*! * @brief Return a matrix which is an inverse matrix of \a (*this) @@ -372,7 +405,7 @@ public: tmp.size(cols(), rows(), Entry(0)); return tmp; } - + //! @brief let itself become itself's inverse matrix Matrix& inversed() { copyFrom(inverse()); @@ -380,14 +413,14 @@ public: } //! @brief return itself's transpose matrix - Matrix transpose () const { + Matrix transpose() const { Matrix ret(cols(), rows(), Entry(0)); for (size_t r = 0, R = cols(); r < R; r++) for (size_t c = 0, C = rows(); c < C; c++) ret.entry(r, c, entry(c, r)); return ret; } - + //! @brief Let itself become itself's transpose matrix Matrix& transposed() { copyFrom(transpose()); @@ -400,7 +433,7 @@ public: ret.triangulared(); return ret; } - + //! @brief triangluar itself Matrix& triangulared() { for (size_t r = 0, c = 0, R = rows(), C = cols(); r < R && c < C; r++) { @@ -432,53 +465,53 @@ public: Matrix& operator=(Matrix const& m) { return copyFrom(m); } - + //! @brief same as \a entry(r,c) Entry operator()(size_t r, size_t c) const { return entry(r, c); } - + //! @brief same as \a entry(r,c,e) Entry operator()(size_t r, size_t c, Entry const& e) { return entry(r, c, e); } - + //! @brief same as \a positive() Matrix operator+() const { return positive(); } - + //! @brief same as \a negative() Matrix operator-() const { return negative(); } - + //! @brief same as \a add(m) Matrix operator+(Matrix const& m) const { return add(m); } - + //! @brief same as \a sub(m) Matrix operator-(Matrix const& m) const { return sub(m); } - + //! @brief same as \a mul(m) Matrix operator*(Matrix const& m) const { return mul(m); } - + //! @brief same as \a mul(m) Matrix operator*(Entry const& s) const { return mul(s); } - + //! @brief same as \a div(s) Matrix operator/(Entry const& s) const { return div(s); } }; -} +} // meow #endif // math_Matrix_H__ |