From c170c4c84ac8d76ad0c75ed3d702c304be441679 Mon Sep 17 00:00:00 2001 From: ancarola Date: Sat, 29 Jun 2019 23:42:46 +0200 Subject: Finally compiles --- include/mm/mmmatrix.hpp | 330 +++++++++++++++++++++++++++++------------------- 1 file changed, 198 insertions(+), 132 deletions(-) diff --git a/include/mm/mmmatrix.hpp b/include/mm/mmmatrix.hpp index 7834a3e..9910273 100644 --- a/include/mm/mmmatrix.hpp +++ b/include/mm/mmmatrix.hpp @@ -23,8 +23,32 @@ namespace mm { template class basic_matrix; + /* specialization of basic_matrix for Rows == Cols */ + template + class square_interface; + + /* + * Most general type of matrix iterator + * IterType = Row, Column, Diagonal + * Grid = constness of mm::basic_matrix + */ + template + class vector_iterator; + + /* + * Access methods interface + */ + + template + class access; + + /* specialisations */ + + template + class matrix; // simple matrix format + template - class transposed_matrix; + class t_matrix; // transposed matrix format /* specialization of basic_matrx for Cols = 1 */ template @@ -32,50 +56,41 @@ namespace mm { /* specialization of basic_matrx for Rows = 1 */ template - class col_vec; + class col_vec; // transposed version of row_vec - /* shorter name for basic_matrix */ - template - class matrix; - - /* specialization of basic_matrix for Rows == Cols */ template class square_matrix; - template - class diagonal_matrix; + template + class t_square_matrix; - /* - * Iterators - */ + /* specialisation of a square_matrix for a sub-diagonal composed matrix */ + template + class diag_matrix; - /* - * Most abstract type of iterator - * IterType = Row, Col, Diag - * Grid = constness of mm::basic_matrix - */ - template class Grid> - class vector_iterator; + template + class t_diag_matrix; } +// TODO, short term solution #define MM_ROW_ITER 0 #define MM_COL_ITER 1 #define MM_DIAG_ITER 2 -template class Grid> +template class mm::vector_iterator { std::size_t index; // variable index - Grid& M; + Grid& M; const int position; // fixed index, negative too for diagonal iterator public: - template class OGrid> + template friend class vector_iterator; - vector_iterator(Grid& M, int position, std::size_t index = 0); + vector_iterator(Grid& M, int position, std::size_t index = 0); mm::vector_iterator operator++() { @@ -130,27 +145,75 @@ public: namespace mm { template - using row_iterator = vector_iterator; + using row_iterator = vector_iterator>; template - using col_iterator = vector_iterator; + using col_iterator = vector_iterator>; template - using const_row_iterator = vector_iterator; + using const_row_iterator = vector_iterator>>; template - using const_col_iterator = vector_iterator; + using const_col_iterator = vector_iterator>>; template - using diag_iterator = vector_iterator; + using diag_iterator = vector_iterator>; template - using const_diag_iterator = vector_iterator; + using const_diag_iterator = vector_iterator>>; } +/* + * Accessors + */ +template +class mm::access +{ +public: + + //access(mm::basic_matrix& ref) : M(ref) {} + + T& at(std::size_t row, std::size_t col); + const T& at(std::size_t row, std::size_t col) const; + + auto operator[](std::size_t index); + auto operator[](std::size_t index) const; + +//private: +// mm::basic_matrix& M; +protected: + std::array data; +}; /* - * Matrix class + * Square interface + */ + +template +class mm::square_interface { +public: + + //square_interface(mm:basic_matrix& _M) : M(_M) {} + + T trace(); + inline T tr() { return trace(); } + + // TODO, determinant + + /// in place inverse + // TODO, det != 0 + // TODO, use gauss jordan for invertible ones + //void invert();, TODO, section algorithm + +//private: +// mm:basic_matrix& M; // one information more than mm::matrix ! +protected: + std::array data; +}; + + +/* + * Matrix class, no access methods */ template @@ -161,9 +224,6 @@ public: template friend class mm::basic_matrix; - template - friend class mm::vector_iterator; - static constexpr std::size_t rows = Rows; static constexpr std::size_t cols = Cols; @@ -181,26 +241,19 @@ public: basic_matrix(const basic_matrix& other); // access data, basic definition - virtual T& at(std::size_t row, std::size_t col); - virtual const T& at(std::size_t row, std::size_t col) const; + //virtual T& at(std::size_t row, std::size_t col); + //virtual const T& at(std::size_t row, std::size_t col) const; // allows to access a matrix M at row j col k with M[j][k] - auto operator[](std::size_t index); - - virtual auto row_begin(std::size_t index) - { - return mm::row_iterator(*this, static_cast(index)); - } + //auto operator[](std::size_t index); void swap_rows(std::size_t x, std::size_t y); void swap_cols(std::size_t x, std::size_t y); // mathematical operations - // TODO, simply switch iteration mode //virtual basic_matrix transposed() const; //inline basic_matrix td() const { return transposed(); } - /// downcast to square matrix static inline constexpr bool is_square() { return (Rows == Cols); } inline constexpr square_matrix to_square() const { @@ -208,7 +261,6 @@ public: return static_cast>(*this); } - /// downcast to row_vector static inline constexpr bool is_row_vec() { return (Cols == 1); } inline constexpr row_vec to_row_vec() const { @@ -227,7 +279,7 @@ protected: template basic_matrix(ConstIterator begin, ConstIterator end); -private: +//private: std::array data; }; @@ -290,7 +342,7 @@ mm::basic_matrix::basic_matrix( /* member functions */ -template +/*template T& mm::basic_matrix::at(std::size_t row, std::size_t col) { assert(row < Rows); // "out of row bound" assert(col < Cols); // "out of column bound" @@ -311,14 +363,14 @@ auto mm::basic_matrix::operator[](std::size_t index) { if constexpr (is_row_vec() || is_col_vec()) { return data.at(index); } else { - return row_begin(index); + return mm::row_iterator(*this, static_cast(index)); - /*return row_vec( - data.cbegin() + (index * Cols), - data.cbegin() + ((index + 1) * Cols) + 1 - );*/ + //return row_vec( + // data.cbegin() + (index * Cols), + // data.cbegin() + ((index + 1) * Cols) + 1 + ); } -} +}*/ template @@ -351,8 +403,8 @@ mm::basic_matrix mm::basic_matrix::transposed() const { }*/ -/* operator overloading */ -template +/* TODO, operator overloading */ +/*template mm::basic_matrix operator+( const mm::basic_matrix& a, const mm::basic_matrix& b @@ -424,93 +476,55 @@ std::ostream& operator<<(std::ostream& os, const mm::basic_matrix } return os; -} - - +}*/ /* * derivated classes */ -/* row vector specialization */ -template -class mm::row_vec : public mm::basic_matrix { -public: - using mm::basic_matrix::basic_matrix; -}; - -/* column vector specialization */ -template -class mm::col_vec : public mm::basic_matrix { -public: - using mm::basic_matrix::basic_matrix; -}; - -/* general specialization (alias) */ +// simple format matrix template -class mm::matrix : public mm::basic_matrix { +class mm::matrix : public mm::basic_matrix, virtual public mm::access +{ public: using mm::basic_matrix::basic_matrix; }; -/* - * transposed matrix format - */ - +// transposed matrix template -class mm::transposed_matrix : public mm::basic_matrix +class mm::t_matrix : public mm::basic_matrix, virtual public mm::access { public: using mm::basic_matrix::basic_matrix; +}; - virtual T& at(std::size_t row, std::size_t col) override - { - return mm::basic_matrix::at(col, row); - } +/* row vector specialization */ +template +class mm::row_vec : public mm::matrix { +public: + using mm::matrix::matrix; - virtual const T& at(std::size_t row, std::size_t col) const override - { - return mm::basic_matrix::at(col, row); - } + // TODO, begin, end +}; - // allows to access a matrix M at row j col k with M[j][k] - virtual auto row_begin(std::size_t index) override - { - return mm::col_iterator(*this, static_cast(index)); - } +/* column vector specialization */ +template +class mm::col_vec : public mm::t_matrix { +public: + using mm::t_matrix::t_matrix; + + // TODO, begin, end }; /* square matrix specialization */ template -class mm::square_matrix : public mm::basic_matrix { +class mm::square_matrix : public mm::matrix , virtual public mm::square_interface { public: - using mm::basic_matrix::basic_matrix; - - /// in place transpose - //void transpose(); - //inline void t() { transpose(); } - - T trace(); - inline T tr() { return trace(); } - - /// in place inverse - // TODO, det != 0 - // TODO, use gauss jordan for invertible ones - void invert(); - - - // TODO, downcast to K-diagonal, user defined cast - /*template - operator mm::diagonal_matrix() const - { - // it's always possible to do it bidirectionally, - // without loosing information - return reinterpret_cast>(*this); - }*/ + using mm::matrix::matrix; // get the identity of size N static inline constexpr square_matrix identity() { - square_matrix i; + mm::square_matrix i; for (unsigned row = 0; row < N; row++) for (unsigned col = 0; col < N; col++) i.at(row, col) = (row == col) ? 1 : 0; @@ -519,12 +533,18 @@ public: } }; +template +class mm::t_square_matrix : virtual public mm::t_matrix, virtual public mm::square_interface { +public: + using mm::t_matrix::t_matrix; +}; + /* * K-diagonal square matrix format * K is bounded between ]-N, N[ */ -template +/*template class mm::diagonal_matrix : public mm::square_matrix { public: @@ -532,7 +552,7 @@ public: // TODO, redefine at, operator[] // TODO, matrix multiplication -}; +};*/ /*template void mm::square_matrix::transpose() { @@ -541,20 +561,10 @@ void mm::square_matrix::transpose() { std::swap(this->at(row, col), this->at(col, row)); }*/ -template -T mm::square_matrix::trace() { - - T sum = 0; - for (mm::diag_iterator it(*this, 0); it.ok(); ++it) - sum += *it; - - return sum; -} - /* Iterators implementation */ -template class Grid> -mm::vector_iterator::vector_iterator(Grid& _M, int pos, std::size_t i) +template +mm::vector_iterator::vector_iterator(Grid& _M, int pos, std::size_t i) : index(i), M(_M), position(pos) { if constexpr (IterType == MM_ROW_ITER) { @@ -566,7 +576,7 @@ mm::vector_iterator::vector_iterator(Grid class Grid> +template T& mm::vector_iterator::operator*() const { if constexpr (IterType == MM_ROW_ITER) @@ -579,7 +589,7 @@ T& mm::vector_iterator::operator*() const M.data[index * Cols + (index - position)]; } -template class Grid> +template T& mm::vector_iterator::operator[](std::size_t i) { if constexpr (IterType == MM_ROW_ITER) @@ -592,3 +602,59 @@ T& mm::vector_iterator::operator[](std::size_t i) M.data[i * Cols + (i - position)]; } +/* + * Accessors implementation + */ + +template +T& mm::access::at(std::size_t row, std::size_t col) +{ + if constexpr (Regular) + return data[row * Cols + col]; + else + return data[col * Cols + row]; // transpose +} + +template +const T& mm::access::at(std::size_t row, std::size_t col) const +{ + if constexpr (Regular) + return data[row * Cols + col]; + else + return data[col * Cols + row]; // transpose +} + +template +auto mm::access::operator[](std::size_t index) +{ + if constexpr (this->is_row_vec() || this->is_col_vec()) + return data.at(index); + else if (Regular) + return mm::row_iterator(*this, static_cast(index)); + else + return mm::col_iterator(*this, static_cast(index)); +} + +template +auto mm::access::operator[](std::size_t index) const +{ + if constexpr (this->is_row_vec() || this->is_col_vec()) + return data.at(index); + else if (Regular) + return mm::const_row_iterator(*this, static_cast(index)); + else + return mm::const_col_iterator(*this, static_cast(index)); +} + +/* Square interface implementation */ + +template +T mm::square_interface::trace() +{ + T sum = 0; + for (mm::diag_iterator it(*this, 0); it.ok(); ++it) + sum += *it; + + return sum; +} + -- cgit v1.2.1