#pragma once namespace mm { template class diag_component; template class multi_diag_matrix; } /* * Optimized case of square matrix * It's a matrix only composed by a diagonal */ template class mm::diag_component { public: virtual int dimension() const = 0; }; template class mm::diag_vector { public: // TODO, define constructor virtual int dimension() const override { return N; } private: std::array vector; }; template class mm::multi_diag_matrix { public: using type = T; template friend class mm::multi_diag_matrix; multi_diag_matrix() : shared_zero(0) {} ~multi_diag_matrix(); // copyable and movable multi_diag_matrix(const multi_diag_matrix& other); multi_diag_matrix(multi_diag_matrix&& other); // copy from another matrix template multi_diag_matrix(const multi_diag_matrix& other); // standard access data T& at(std::size_t row, std::size_t col); 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); // swap two diagonals void swap_diags(std::size_t k, std::size_t l); // diagonal construction or substitution template void put_diag(const mm::diag_vector& diag) { //static_assert((Diag <= -N) || (Diag >= N), static_assert(K < 1, "Diagonal number must be bounded between ]-N,N[") auto exist = diagonals.find(Diag); if (exist != diagonals.end()) // copy *exists = diag; else // create and copy diagonals.insert(new mm::diag_vector(diag)); } // mathematical operations virtual multi_diag_matrix transposed() const; inline multi_diag_matrix td() const { return transposed(); } // multiplication rhs and lhs // TODO, need super class matrix abstraction and auto return type // A * M, TODO abstraction virtual method template basic_matrix rhs_mult(const mm::basic_matrix& A) const; // M * A, TODO abstraction virtual method template basic_matrix lhs_mult(const mm::basic_matrix& A) const; protected: template multi_diag_matrix(ConstIterator begin, ConstIterator end); private: // return an arbitrary zero in non-const mode T shared_zero; // ordered set of diagonals std::unordered_map*> diagonals; }; template T& mm::multi_diag_matrix::at(std::size_t row, std::size_t col) { assert(row < N); // "out of row bound" assert(col < N); // "out of column bound" const int k = row - col; auto diag = diagonals.find(k); const int line = (k > 0) ? col : row; return (diag == diagonals.end()) ? (shared_zero = 0) : (*diag)[line]; } template const T& mm::multi_diag_matrix::at(std::size_t row, std::size_t col) const { assert(row < N); // "out of row bound" assert(col < N); // "out of column bound" const int k = row - col; auto diag = diagonals.find(k); const int line = (k > 0) ? col : row; return (diag == diagonals.end()) ? 0 : (*diag)[line]; } template auto mm::multi_diag_matrix::operator[](std::size_t index) { assert(index < N) // TODO, single row mapping } template mm::basic_matrix mm::multi_diag_matrix::rhs_mult(const mm::basic_matrix& A) const { // TODO } template mm::basic_matrix mm::multi_diag_matrix::lhs_mult(const mm::basic_matrix& A) const { mm::basic_matrix out; }