diff --git a/include/mat.hpp b/include/mat.hpp index 5ceda3c..d9c03e1 100644 --- a/include/mat.hpp +++ b/include/mat.hpp @@ -26,11 +26,11 @@ namespace math{ - template + template class matrix_base { - static_assert(W > 0, "Cannot have 0 columns matrix"); - static_assert(H > 0, "Cannot have 0 rows matrix"); + static_assert(C > 0, "Cannot have 0 columns matrix"); + static_assert(R > 0, "Cannot have 0 rows matrix"); public: using value_type = T; using size_type = size_t; @@ -39,11 +39,11 @@ namespace math{ using reference = value_type&; using const_reference = const value_type&; - static constexpr size_type Columns = W; - static constexpr size_type Rows = H; + static constexpr size_type Columns = C; + static constexpr size_type Rows = R; protected: - value_type m_data[W*H]; + value_type m_data[R*C]; protected: template @@ -92,11 +92,11 @@ namespace math{ }; - template - class matrix : public matrix_base + template + class matrix : public matrix_base { private: - using base = matrix_base; + using base = matrix_base; public: using value_type = typename base::value_type; using size_type = typename base::size_type; @@ -116,14 +116,14 @@ namespace math{ constexpr matrix& operator=(const matrix&) = default; constexpr matrix& operator=(matrix&&) = default; template - constexpr matrix& operator=(const matrix& m); + constexpr matrix& operator=(const matrix& m); }; - template - class matrix : public matrix_base + template + class matrix : public matrix_base { private: - using base = matrix_base; + using base = matrix_base; public: using value_type = typename base::value_type; using size_type = typename base::size_type; @@ -144,7 +144,7 @@ namespace math{ constexpr matrix& operator=(const matrix&) = default; constexpr matrix& operator=(matrix&&) = default; template - constexpr matrix& operator=(const matrix& m); + constexpr matrix& operator=(const matrix& m); //square matrix arithmetic operations constexpr value_type determinate()const; @@ -191,8 +191,8 @@ namespace math{ template struct is_matrix_helper { - template - static std::true_type test(matrix*); + template + static std::true_type test(matrix_base*); static std::false_type test(void*); static constexpr bool value = std::is_same*>(nullptr)))>::value; @@ -221,36 +221,36 @@ namespace math{ } - template - constexpr bool operator==(const matrix& left, const matrix right); - template - constexpr bool operator!=(const matrix& left, const matrix right); + template + constexpr bool operator==(const matrix_base& left, const matrix_base right); + template + constexpr bool operator!=(const matrix_base& left, const matrix_base right); - template - constexpr auto operator*(const matrix& left, const matrix& right); + template + constexpr auto operator*(const matrix& left, const matrix& right); + template::value,int> = 0> + constexpr auto operator*(const matrix& left, U&& right); + template::value,int> = 0> + constexpr auto operator*(U&& left, const matrix& right); + template::value,int> = 0> + constexpr auto operator/(const matrix& left, U&& right); template - constexpr auto operator*(const matrix& left, U&& right); + constexpr auto operator+(const matrix& left, const matrix& right); template - constexpr auto operator*(U&& left, const matrix& right); + constexpr auto operator-(const matrix& left, const matrix& right); template - constexpr auto operator/(const matrix& left, U&& right); - template - constexpr auto operator+(const matrix& left, const matrix& right); - template - constexpr auto operator-(const matrix& left, const matrix& right); - template - constexpr auto operator-(const matrix& left); + constexpr auto operator-(const matrix& left); - template - constexpr decltype(auto) operator*=(matrix& left, const matrix& right); + template + constexpr decltype(auto) operator*=(matrix& left, const matrix& right); + template::value,int> = 0> + constexpr decltype(auto) operator*=(matrix& left, U&& right); + template::value,int> = 0> + constexpr decltype(auto) operator/=(matrix& left, U&& right); template - constexpr decltype(auto) operator*=(matrix& left, U&& right); + constexpr decltype(auto) operator+=(matrix& left, const matrix& right); template - constexpr decltype(auto) operator/=(matrix& left, U&& right); - template - constexpr decltype(auto) operator+=(matrix& left, const matrix& right); - template - constexpr decltype(auto) operator-=(matrix& left, const matrix& right); + constexpr decltype(auto) operator-=(matrix& left, const matrix& right); } diff --git a/include/mat.tpp b/include/mat.tpp index db80b83..733e409 100644 --- a/include/mat.tpp +++ b/include/mat.tpp @@ -26,42 +26,42 @@ namespace math{ - template + template template - constexpr matrix_base::matrix_base(std::integer_sequence): + constexpr matrix_base::matrix_base(std::integer_sequence): m_data{Ss...}{} - template - constexpr matrix_base::matrix_base(): + template + constexpr matrix_base::matrix_base(): matrix_base(typename detail::default_initialization_matrix::tuple{}){} - template - constexpr matrix_base::matrix_base(detail::zero_initialize_t): + template + constexpr matrix_base::matrix_base(detail::zero_initialize_t): m_data{}{} - template - constexpr matrix_base::matrix_base(detail::no_initialize_t){} + template + constexpr matrix_base::matrix_base(detail::no_initialize_t){} - template - constexpr matrix_base::matrix_base(value_type v){ + template + constexpr matrix_base::matrix_base(value_type v){ for(size_type i = 0;i < Columns*Rows;++i) m_data[i] = v; } - template + template template - constexpr matrix_base::matrix_base(Args&&... args): + constexpr matrix_base::matrix_base(Args&&... args): m_data{std::forward(args)...}{} - template + template template - constexpr matrix_base::matrix_base(const matrix_base& 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); } - template + template template - constexpr matrix_base& matrix_base::operator=(const matrix_base& 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); @@ -69,101 +69,101 @@ namespace math{ } - template - constexpr auto matrix_base::operator[](size_type x){ + template + constexpr auto matrix_base::operator[](size_type x){ return detail::mat_ref_obj{m_data, x}; } - template - constexpr auto matrix_base::operator[](size_type x)const{ + template + constexpr auto matrix_base::operator[](size_type x)const{ return detail::mat_ref_obj{m_data, x}; } - template - constexpr auto matrix_base::get(size_type x, size_type y) -> reference{ + template + constexpr auto matrix_base::get(size_type x, size_type y) -> reference{ return m_data[x+(y*Rows)]; } - template - constexpr auto matrix_base::get(size_type x, size_type y)const -> const_reference{ + template + constexpr auto matrix_base::get(size_type x, size_type y)const -> const_reference{ return m_data[x+(y*Rows)]; } - template - constexpr auto matrix_base::get(size_type i) -> reference{ + template + constexpr auto matrix_base::get(size_type i) -> reference{ return m_data[i]; } - template - constexpr auto matrix_base::get(size_type i)const -> const_reference{ + template + constexpr auto matrix_base::get(size_type i)const -> const_reference{ return m_data[i]; } - template - constexpr auto matrix_base::columns()const -> size_type{ + template + constexpr auto matrix_base::columns()const -> size_type{ return Columns; } - template - constexpr auto matrix_base::rows()const -> size_type{ + template + constexpr auto matrix_base::rows()const -> size_type{ return Rows; } - template - constexpr auto matrix_base::size()const -> size_type{ + template + constexpr auto matrix_base::size()const -> size_type{ return Columns*Rows; } - template - constexpr auto matrix_base::raw() -> pointer{ + template + constexpr auto matrix_base::raw() -> pointer{ return m_data; } - template - constexpr auto matrix_base::raw()const -> const_pointer{ + template + constexpr auto matrix_base::raw()const -> const_pointer{ return m_data; } - template - constexpr matrix_base::operator pointer(){ + template + constexpr matrix_base::operator pointer(){ return m_data; } - template - constexpr matrix_base::operator const_pointer()const{ + template + constexpr matrix_base::operator const_pointer()const{ return m_data; } - template + template template - constexpr matrix& matrix::operator=(const matrix& m){ + constexpr matrix& matrix::operator=(const matrix& m){ base::operator=(m); return *this; } - template - constexpr matrix::matrix(detail::id_initialize_t): + template + constexpr matrix::matrix(detail::id_initialize_t): base(){} - template + template template - constexpr matrix& matrix::operator=(const matrix& m){ + constexpr matrix& matrix::operator=(const matrix& m){ base::operator=(m); return *this; } - template - constexpr auto matrix::determinate()const -> value_type{ + template + constexpr auto matrix::determinate()const -> value_type{ return math::determinate(*this); } - template - constexpr auto matrix::trace()const -> value_type{ + template + constexpr auto matrix::trace()const -> value_type{ value_type sum = 0; - for(size_type i = 0;i < W;++i){ + for(size_type i = 0;i < R;++i){ sum += get(i, i); } } - 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){ + for(size_type i = 0;i < R;++i){ + for(size_type j = 0;j < R;++j){ m.get(j, i) = get(i, j); } } return m; } - template - constexpr matrix matrix::inverse()const{ + template + constexpr matrix matrix::inverse()const{ return math::inverse(*this); } @@ -261,83 +261,82 @@ namespace math{ } - template - constexpr bool operator==(const matrix& left, const matrix right){ + template + constexpr bool operator==(const matrix_base& left, const matrix_base right){ for(size_t i = 0;i < left.size();++i){ if(left.get(i) != right.get(i)) return false; } return true; } - template - constexpr bool operator!=(const matrix& left, const matrix right){ + template + constexpr bool operator!=(const matrix_base& left, const matrix_base right){ return !(left == right); } template - constexpr auto operator*(const matrix& left, const matrix& right){ + constexpr auto operator*(const matrix& left, const matrix& right){ using res_t = decltype(std::declval() * std::declval()); - matrix res(no_initialize); + matrix res(zero_initialize); size_t index = 0; - for(size_t i = 0;i < right.rows();++i){ - for(size_t j = 0;j < left.rows();++j){ - for(size_t k = 0;k < left.columns();++k){ - res.get(index) += left[j][k] * right[i][k]; + for(size_t i = 0;i < left.rows();++i){ + for(size_t j = 0;j < right.columns();++j){ + for(size_t k = 0;k < right.rows();++k){ + res.get(index) += left[i][k] * right[k][j]; } ++index; } } - return res; } - template - constexpr auto operator*(const matrix& left, U&& right){ + template::value,int>> + constexpr auto operator*(const matrix& left, U&& right){ using res_t = decltype(std::declval() * std::declval()); - matrix res(no_initialize); + matrix res(no_initialize); for(size_t i = 0;i < left.size();++i){ res.get(i) = left.get(i) * std::forward(right); } return res; } - template - constexpr auto operator*(U&& left, const matrix& right){ + template::value,int>> + constexpr auto operator*(U&& left, const matrix& right){ using res_t = decltype(std::declval() * std::declval()); - matrix res(no_initialize); + matrix res(no_initialize); for(size_t i = 0;i < right.size();++i){ res.get(i) = std::forward(left) * right.get(i); } return res; } - template - constexpr auto operator/(const matrix& left, U&& right){ + template::value,int>> + constexpr auto operator/(const matrix& left, U&& right){ using res_t = decltype(std::declval() / std::declval()); - matrix res(no_initialize); + matrix res(no_initialize); for(size_t i = 0;i < left.size();++i){ res.get(i) = left.get(i) / std::forward(right); } return res; } template - constexpr auto operator+(const matrix& left, const matrix& right){ + constexpr auto operator+(const matrix& left, const matrix& right){ using res_t = decltype(std::declval() + std::declval()); - matrix res(no_initialize); + matrix res(no_initialize); for(size_t i = 0;i < left.size();++i){ res.get(i) = left.get(i) + right.get(i); } return res; } template - constexpr auto operator-(const matrix& left, const matrix& right){ + constexpr auto operator-(const matrix& left, const matrix& right){ using res_t = decltype(std::declval() - std::declval()); - matrix res(no_initialize); + matrix res(no_initialize); for(size_t i = 0;i < left.size();++i){ res.get(i) = left.get(i) - right.get(i); } return res; } template - constexpr auto operator-(const matrix& left){ - using res_t = decltype(std::declval() - std::declval()); - matrix res(no_initialize); + constexpr auto operator-(const matrix& left){ + using res_t = decltype(-std::declval()); + matrix res(no_initialize); for(size_t i = 0;i < left.size();++i){ res.get(i) = -left.get(i); } @@ -345,35 +344,35 @@ namespace math{ } - template - constexpr decltype(auto) operator*=(matrix& left, const matrix& right){ + template + constexpr decltype(auto) operator*=(matrix& left, const matrix& right){ //have to evaluate entire expression first since matrix multiplication depends on reusing many elements //cannot be expression templatized, TODO return (left = (left * right)); } - template - constexpr decltype(auto) operator*=(matrix& left, U&& right){ + template::value,int>> + constexpr decltype(auto) operator*=(matrix& left, U&& right){ for(size_t i = 0;i < left.size();++i){ left.get(i) = left.get(i) * std::forward(right); } return left; } - template - constexpr decltype(auto) operator/=(matrix& left, U&& right){ + template::value,int>> + constexpr decltype(auto) operator/=(matrix& left, U&& right){ for(size_t i = 0;i < left.size();++i){ left.get(i) = left.get(i) / std::forward(right); } return left; } template - constexpr decltype(auto) operator+=(matrix& left, const matrix& right){ + constexpr decltype(auto) operator+=(matrix& left, const matrix& right){ for(size_t i = 0;i < left.size();++i){ left.get(i) = left.get(i) + right.get(i); } return left; } template - constexpr decltype(auto) operator-=(matrix& left, const matrix& right){ + constexpr decltype(auto) operator-=(matrix& left, const matrix& right){ for(size_t i = 0;i < left.size();++i){ left.get(i) = left.get(i) - right.get(i); }