From 932335bdc54f7faa8c804bfe7299e737e3ba64cd Mon Sep 17 00:00:00 2001 From: rexy712 Date: Sun, 16 Aug 2020 06:47:52 -0700 Subject: [PATCH] Specialize on square matrices --- include/mat.hpp | 95 ++++++++++++++++++++++++++++++++++++------------- include/mat.tpp | 90 ++++++++++++++++++++++++---------------------- 2 files changed, 118 insertions(+), 67 deletions(-) diff --git a/include/mat.hpp b/include/mat.hpp index 4a1097d..5ceda3c 100644 --- a/include/mat.hpp +++ b/include/mat.hpp @@ -27,7 +27,7 @@ namespace math{ template - class matrix + class matrix_base { static_assert(W > 0, "Cannot have 0 columns matrix"); static_assert(H > 0, "Cannot have 0 rows matrix"); @@ -46,37 +46,32 @@ namespace math{ value_type m_data[W*H]; protected: - template - constexpr matrix(std::integer_sequence); - + template + constexpr matrix_base(std::integer_sequence); public: //Default construct as identity when square, zero otherwise - constexpr matrix(); + constexpr matrix_base(); //Range initializing constructors - constexpr explicit matrix(detail::zero_initialize_t); - constexpr explicit matrix(detail::no_initialize_t); - template - constexpr explicit matrix(detail::id_initialize_t); + constexpr explicit matrix_base(detail::zero_initialize_t); + constexpr explicit matrix_base(detail::no_initialize_t); //Value initializing constructors - constexpr explicit matrix(value_type v); + constexpr explicit matrix_base(value_type v); template - constexpr explicit matrix(Args&&... args); + constexpr explicit matrix_base(Args&&... args); //Copying constructors - constexpr matrix(const matrix&) = default; - constexpr matrix(matrix&&) = default; + constexpr matrix_base(const matrix_base&) = default; + constexpr matrix_base(matrix_base&&) = default; template - constexpr matrix(const matrix& m); - ~matrix() = default; + constexpr matrix_base(const matrix_base& m); + ~matrix_base() = default; - //Assignement + constexpr matrix_base& operator=(const matrix_base&) = default; + constexpr matrix_base& operator=(matrix_base&&) = default; template - constexpr matrix& operator=(const matrix& m); - constexpr matrix& operator=(const matrix&) = default; - constexpr matrix& operator=(matrix&&) = default; - + constexpr matrix_base& operator=(const matrix_base& m); //Getters/Setters constexpr auto operator[](size_type x); @@ -95,14 +90,66 @@ namespace math{ constexpr operator pointer(); constexpr operator const_pointer()const; + }; + + template + class matrix : public matrix_base + { + private: + using base = matrix_base; + public: + using value_type = typename base::value_type; + using size_type = typename base::size_type; + using pointer = typename base::pointer; + using const_pointer = typename base::const_pointer; + using reference = typename base::reference; + using const_reference = typename base::const_reference; + + public: + using base::base; + + constexpr matrix(const matrix&) = default; + constexpr matrix(matrix&&) = default; + ~matrix() = default; + + //Assignement + constexpr matrix& operator=(const matrix&) = default; + constexpr matrix& operator=(matrix&&) = default; + template + constexpr matrix& operator=(const matrix& m); + }; + + template + class matrix : public matrix_base + { + private: + using base = matrix_base; + public: + using value_type = typename base::value_type; + using size_type = typename base::size_type; + using pointer = typename base::pointer; + using const_pointer = typename base::const_pointer; + using reference = typename base::reference; + using const_reference = typename base::const_reference; + + public: + using base::base; + + constexpr matrix(const matrix&) = default; + constexpr matrix(matrix&&) = default; + constexpr explicit matrix(detail::id_initialize_t); + ~matrix() = default; + + //Assignement + constexpr matrix& operator=(const matrix&) = default; + constexpr matrix& operator=(matrix&&) = default; + template + constexpr matrix& operator=(const matrix& m); + //square matrix arithmetic operations - template constexpr value_type determinate()const; - template constexpr value_type trace()const; - template constexpr matrix transpose()const; - template constexpr matrix inverse()const; }; diff --git a/include/mat.tpp b/include/mat.tpp index 9bd9de7..db80b83 100644 --- a/include/mat.tpp +++ b/include/mat.tpp @@ -27,40 +27,33 @@ namespace math{ template - template::size_type... Ss> - constexpr matrix::matrix(std::integer_sequence): + template + constexpr matrix_base::matrix_base(std::integer_sequence): m_data{Ss...}{} template - constexpr matrix::matrix(): - matrix(typename detail::default_initialization_matrix::tuple{}){} + constexpr matrix_base::matrix_base(): + matrix_base(typename detail::default_initialization_matrix::tuple{}){} template - constexpr matrix::matrix(detail::zero_initialize_t): + constexpr matrix_base::matrix_base(detail::zero_initialize_t): m_data{}{} template - constexpr matrix::matrix(detail::no_initialize_t){} - template - template - constexpr matrix::matrix(detail::id_initialize_t): - matrix() - { - static_assert(Columns == Rows, "Identity initialization only supported on square matrices"); - } + constexpr matrix_base::matrix_base(detail::no_initialize_t){} template - constexpr matrix::matrix(value_type v){ + constexpr matrix_base::matrix_base(value_type v){ for(size_type i = 0;i < Columns*Rows;++i) m_data[i] = v; } template template - constexpr matrix::matrix(Args&&... args): + constexpr matrix_base::matrix_base(Args&&... args): m_data{std::forward(args)...}{} template template - constexpr matrix::matrix(const matrix& m){ + constexpr matrix_base::matrix_base(const matrix_base& m){ using mat = decltype(m); for(typename mat::size_type i = 0;i < mat::Columns*mat::Rows;++i) m_data[i] = m.get(i); @@ -68,7 +61,7 @@ namespace math{ template template - constexpr matrix& matrix::operator=(const matrix& m){ + constexpr matrix_base& matrix_base::operator=(const matrix_base& m){ using mat = decltype(m); for(typename mat::size_type i = 0;i < mat::Columns*mat::Rows;++i) m_data[i] = m.get(i); @@ -77,77 +70,90 @@ namespace math{ template - constexpr auto matrix::operator[](size_type x){ + constexpr auto matrix_base::operator[](size_type x){ return detail::mat_ref_obj{m_data, x}; } template - constexpr auto matrix::operator[](size_type x)const{ + constexpr auto matrix_base::operator[](size_type x)const{ return detail::mat_ref_obj{m_data, x}; } template - constexpr auto matrix::get(size_type x, size_type y) -> reference{ + constexpr auto matrix_base::get(size_type x, size_type y) -> reference{ return m_data[x+(y*Rows)]; } template - constexpr auto matrix::get(size_type x, size_type y)const -> const_reference{ + constexpr auto matrix_base::get(size_type x, size_type y)const -> const_reference{ return m_data[x+(y*Rows)]; } template - constexpr auto matrix::get(size_type i) -> reference{ + constexpr auto matrix_base::get(size_type i) -> reference{ return m_data[i]; } template - constexpr auto matrix::get(size_type i)const -> const_reference{ + constexpr auto matrix_base::get(size_type i)const -> const_reference{ return m_data[i]; } template - constexpr auto matrix::columns()const -> size_type{ + constexpr auto matrix_base::columns()const -> size_type{ return Columns; } template - constexpr auto matrix::rows()const -> size_type{ + constexpr auto matrix_base::rows()const -> size_type{ return Rows; } template - constexpr auto matrix::size()const -> size_type{ + constexpr auto matrix_base::size()const -> size_type{ return Columns*Rows; } template - constexpr auto matrix::raw() -> pointer{ + constexpr auto matrix_base::raw() -> pointer{ return m_data; } template - constexpr auto matrix::raw()const -> const_pointer{ + constexpr auto matrix_base::raw()const -> const_pointer{ return m_data; } template - constexpr matrix::operator pointer(){ + constexpr matrix_base::operator pointer(){ return m_data; } template - constexpr matrix::operator const_pointer()const{ + constexpr matrix_base::operator const_pointer()const{ return m_data; } + template template - constexpr auto matrix::determinate()const -> value_type{ - static_assert(W == H, "Determinate can only be calculated on square matrix"); + constexpr matrix& matrix::operator=(const matrix& m){ + base::operator=(m); + return *this; + } + + template + constexpr matrix::matrix(detail::id_initialize_t): + base(){} + template + template + constexpr matrix& matrix::operator=(const matrix& m){ + base::operator=(m); + return *this; + } + + template + constexpr auto matrix::determinate()const -> value_type{ return math::determinate(*this); } - template - template - constexpr auto matrix::trace()const -> value_type{ - static_assert(W == H, "Trace can only be calculated on square matrix"); + template + constexpr auto matrix::trace()const -> value_type{ value_type sum = 0; for(size_type i = 0;i < W;++i){ sum += get(i, i); } } - template - template - constexpr matrix matrix::transpose()const{ + template + constexpr matrix matrix::transpose()const{ matrix m(no_initialize); for(size_type i = 0;i < W;++i){ for(size_type j = 0;j < W;++j){ @@ -156,10 +162,8 @@ namespace math{ } return m; } - template - template - constexpr matrix matrix::inverse()const{ - static_assert(W == H, "Trace can only be calculated on square matrix"); + template + constexpr matrix matrix::inverse()const{ return math::inverse(*this); }