Fix matrix naming stuff so it's not so confusing no more

This commit is contained in:
rexy712 2020-08-16 08:20:32 -07:00
parent 932335bdc5
commit c7d5978d6d
2 changed files with 132 additions and 133 deletions

View File

@ -26,11 +26,11 @@
namespace math{
template<typename T, size_t W, size_t H>
template<typename T, size_t R, size_t C>
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<size_t... Ss>
@ -92,11 +92,11 @@ namespace math{
};
template<typename T, size_t W, size_t H>
class matrix : public matrix_base<T,W,H>
template<typename T, size_t R, size_t C>
class matrix : public matrix_base<T,R,C>
{
private:
using base = matrix_base<T,W,H>;
using base = matrix_base<T,R,C>;
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<typename U>
constexpr matrix& operator=(const matrix<U,W,H>& m);
constexpr matrix& operator=(const matrix<U,R,C>& m);
};
template<typename T, size_t W>
class matrix<T,W,W> : public matrix_base<T,W,W>
template<typename T, size_t R>
class matrix<T,R,R> : public matrix_base<T,R,R>
{
private:
using base = matrix_base<T,W,W>;
using base = matrix_base<T,R,R>;
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<typename U>
constexpr matrix& operator=(const matrix<U,W,W>& m);
constexpr matrix& operator=(const matrix<U,R,R>& m);
//square matrix arithmetic operations
constexpr value_type determinate()const;
@ -191,8 +191,8 @@ namespace math{
template<typename T>
struct is_matrix_helper {
template<typename U, size_t W, size_t H>
static std::true_type test(matrix<U,W,H>*);
template<typename U, size_t R, size_t C>
static std::true_type test(matrix_base<U,R,C>*);
static std::false_type test(void*);
static constexpr bool value = std::is_same<std::true_type,decltype(test(static_cast<std::decay_t<T>*>(nullptr)))>::value;
@ -221,36 +221,36 @@ namespace math{
}
template<typename T, typename U, size_t W, size_t H>
constexpr bool operator==(const matrix<T,W,H>& left, const matrix<U,W,H> right);
template<typename T, typename U, size_t W, size_t H>
constexpr bool operator!=(const matrix<T,W,H>& left, const matrix<U,W,H> right);
template<typename T, typename U, size_t R, size_t C>
constexpr bool operator==(const matrix_base<T,R,C>& left, const matrix_base<U,R,C> right);
template<typename T, typename U, size_t R, size_t C>
constexpr bool operator!=(const matrix_base<T,R,C>& left, const matrix_base<U,R,C> right);
template<typename T, typename U, size_t R1, size_t C1, size_t C2>
constexpr auto operator*(const matrix<T,C1,R1>& left, const matrix<U,C2,C1>& right);
template<typename T, typename U, size_t R1, size_t C1, size_t R2>
constexpr auto operator*(const matrix<T,R1,C1>& left, const matrix<U,C1,R2>& right);
template<typename T, typename U, size_t C, size_t R, std::enable_if_t<!is_matrix<U>::value,int> = 0>
constexpr auto operator*(const matrix<T,R,C>& left, U&& right);
template<typename T, typename U, size_t C, size_t R, std::enable_if_t<!is_matrix<U>::value,int> = 0>
constexpr auto operator*(U&& left, const matrix<T,R,C>& right);
template<typename T, typename U, size_t C, size_t R, std::enable_if_t<!is_matrix<U>::value,int> = 0>
constexpr auto operator/(const matrix<T,R,C>& left, U&& right);
template<typename T, typename U, size_t C, size_t R>
constexpr auto operator*(const matrix<T,C,R>& left, U&& right);
constexpr auto operator+(const matrix<T,R,C>& left, const matrix<U,R,C>& right);
template<typename T, typename U, size_t C, size_t R>
constexpr auto operator*(U&& left, const matrix<T,C,R>& right);
constexpr auto operator-(const matrix<T,R,C>& left, const matrix<U,R,C>& right);
template<typename T, typename U, size_t C, size_t R>
constexpr auto operator/(const matrix<T,C,R>& left, U&& right);
template<typename T, typename U, size_t C, size_t R>
constexpr auto operator+(const matrix<T,C,R>& left, const matrix<U,C,R>& right);
template<typename T, typename U, size_t C, size_t R>
constexpr auto operator-(const matrix<T,C,R>& left, const matrix<U,C,R>& right);
template<typename T, typename U, size_t C, size_t R>
constexpr auto operator-(const matrix<T,C,R>& left);
constexpr auto operator-(const matrix<T,R,C>& left);
template<typename T, typename U, size_t R1, size_t C1, size_t C2>
constexpr decltype(auto) operator*=(matrix<T,C1,R1>& left, const matrix<U,C2,C1>& right);
template<typename T, typename U, size_t R>
constexpr decltype(auto) operator*=(matrix<T,R,R>& left, const matrix<U,R,R>& right);
template<typename T, typename U, size_t C, size_t R, std::enable_if_t<!is_matrix<U>::value,int> = 0>
constexpr decltype(auto) operator*=(matrix<T,R,C>& left, U&& right);
template<typename T, typename U, size_t C, size_t R, std::enable_if_t<!is_matrix<U>::value,int> = 0>
constexpr decltype(auto) operator/=(matrix<T,R,C>& left, U&& right);
template<typename T, typename U, size_t C, size_t R>
constexpr decltype(auto) operator*=(matrix<T,C,R>& left, U&& right);
constexpr decltype(auto) operator+=(matrix<T,R,C>& left, const matrix<U,R,C>& right);
template<typename T, typename U, size_t C, size_t R>
constexpr decltype(auto) operator/=(matrix<T,C,R>& left, U&& right);
template<typename T, typename U, size_t C, size_t R>
constexpr decltype(auto) operator+=(matrix<T,C,R>& left, const matrix<U,C,R>& right);
template<typename T, typename U, size_t C, size_t R>
constexpr decltype(auto) operator-=(matrix<T,C,R>& left, const matrix<U,C,R>& right);
constexpr decltype(auto) operator-=(matrix<T,R,C>& left, const matrix<U,R,C>& right);
}

View File

@ -26,42 +26,42 @@
namespace math{
template<typename T, size_t W, size_t H>
template<typename T, size_t R, size_t C>
template<size_t... Ss>
constexpr matrix_base<T,W,H>::matrix_base(std::integer_sequence<size_type,Ss...>):
constexpr matrix_base<T,R,C>::matrix_base(std::integer_sequence<size_type,Ss...>):
m_data{Ss...}{}
template<typename T, size_t W, size_t H>
constexpr matrix_base<T,W,H>::matrix_base():
template<typename T, size_t R, size_t C>
constexpr matrix_base<T,R,C>::matrix_base():
matrix_base(typename detail::default_initialization_matrix<Columns,Rows>::tuple{}){}
template<typename T, size_t W, size_t H>
constexpr matrix_base<T,W,H>::matrix_base(detail::zero_initialize_t):
template<typename T, size_t R, size_t C>
constexpr matrix_base<T,R,C>::matrix_base(detail::zero_initialize_t):
m_data{}{}
template<typename T, size_t W, size_t H>
constexpr matrix_base<T,W,H>::matrix_base(detail::no_initialize_t){}
template<typename T, size_t R, size_t C>
constexpr matrix_base<T,R,C>::matrix_base(detail::no_initialize_t){}
template<typename T, size_t W, size_t H>
constexpr matrix_base<T,W,H>::matrix_base(value_type v){
template<typename T, size_t R, size_t C>
constexpr matrix_base<T,R,C>::matrix_base(value_type v){
for(size_type i = 0;i < Columns*Rows;++i)
m_data[i] = v;
}
template<typename T, size_t W, size_t H>
template<typename T, size_t R, size_t C>
template<typename... Args>
constexpr matrix_base<T,W,H>::matrix_base(Args&&... args):
constexpr matrix_base<T,R,C>::matrix_base(Args&&... args):
m_data{std::forward<Args>(args)...}{}
template<typename T, size_t W, size_t H>
template<typename T, size_t R, size_t C>
template<typename U>
constexpr matrix_base<T,W,H>::matrix_base(const matrix_base<U,Columns,Rows>& m){
constexpr matrix_base<T,R,C>::matrix_base(const matrix_base<U,Columns,Rows>& 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<typename T, size_t W, size_t H>
template<typename T, size_t R, size_t C>
template<typename U>
constexpr matrix_base<T,W,H>& matrix_base<T,W,H>::operator=(const matrix_base<U,Columns,Rows>& m){
constexpr matrix_base<T,R,C>& matrix_base<T,R,C>::operator=(const matrix_base<U,Columns,Rows>& 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<typename T, size_t W, size_t H>
constexpr auto matrix_base<T,W,H>::operator[](size_type x){
template<typename T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::operator[](size_type x){
return detail::mat_ref_obj<value_type,Rows>{m_data, x};
}
template<typename T, size_t W, size_t H>
constexpr auto matrix_base<T,W,H>::operator[](size_type x)const{
template<typename T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::operator[](size_type x)const{
return detail::mat_ref_obj<const value_type,Rows>{m_data, x};
}
template<typename T, size_t W, size_t H>
constexpr auto matrix_base<T,W,H>::get(size_type x, size_type y) -> reference{
template<typename T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::get(size_type x, size_type y) -> reference{
return m_data[x+(y*Rows)];
}
template<typename T, size_t W, size_t H>
constexpr auto matrix_base<T,W,H>::get(size_type x, size_type y)const -> const_reference{
template<typename T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::get(size_type x, size_type y)const -> const_reference{
return m_data[x+(y*Rows)];
}
template<typename T, size_t W, size_t H>
constexpr auto matrix_base<T,W,H>::get(size_type i) -> reference{
template<typename T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::get(size_type i) -> reference{
return m_data[i];
}
template<typename T, size_t W, size_t H>
constexpr auto matrix_base<T,W,H>::get(size_type i)const -> const_reference{
template<typename T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::get(size_type i)const -> const_reference{
return m_data[i];
}
template<typename T, size_t W, size_t H>
constexpr auto matrix_base<T,W,H>::columns()const -> size_type{
template<typename T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::columns()const -> size_type{
return Columns;
}
template<typename T, size_t W, size_t H>
constexpr auto matrix_base<T,W,H>::rows()const -> size_type{
template<typename T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::rows()const -> size_type{
return Rows;
}
template<typename T, size_t W, size_t H>
constexpr auto matrix_base<T,W,H>::size()const -> size_type{
template<typename T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::size()const -> size_type{
return Columns*Rows;
}
template<typename T, size_t W, size_t H>
constexpr auto matrix_base<T,W,H>::raw() -> pointer{
template<typename T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::raw() -> pointer{
return m_data;
}
template<typename T, size_t W, size_t H>
constexpr auto matrix_base<T,W,H>::raw()const -> const_pointer{
template<typename T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::raw()const -> const_pointer{
return m_data;
}
template<typename T, size_t W, size_t H>
constexpr matrix_base<T,W,H>::operator pointer(){
template<typename T, size_t R, size_t C>
constexpr matrix_base<T,R,C>::operator pointer(){
return m_data;
}
template<typename T, size_t W, size_t H>
constexpr matrix_base<T,W,H>::operator const_pointer()const{
template<typename T, size_t R, size_t C>
constexpr matrix_base<T,R,C>::operator const_pointer()const{
return m_data;
}
template<typename T, size_t W, size_t H>
template<typename T, size_t R, size_t C>
template<typename U>
constexpr matrix<T,W,H>& matrix<T,W,H>::operator=(const matrix<U,W,H>& m){
constexpr matrix<T,R,C>& matrix<T,R,C>::operator=(const matrix<U,R,C>& m){
base::operator=(m);
return *this;
}
template<typename T, size_t W>
constexpr matrix<T,W,W>::matrix(detail::id_initialize_t):
template<typename T, size_t R>
constexpr matrix<T,R,R>::matrix(detail::id_initialize_t):
base(){}
template<typename T, size_t W>
template<typename T, size_t R>
template<typename U>
constexpr matrix<T,W,W>& matrix<T,W,W>::operator=(const matrix<U,W,W>& m){
constexpr matrix<T,R,R>& matrix<T,R,R>::operator=(const matrix<U,R,R>& m){
base::operator=(m);
return *this;
}
template<typename T, size_t W>
constexpr auto matrix<T,W,W>::determinate()const -> value_type{
template<typename T, size_t R>
constexpr auto matrix<T,R,R>::determinate()const -> value_type{
return math::determinate(*this);
}
template<typename T, size_t W>
constexpr auto matrix<T,W,W>::trace()const -> value_type{
template<typename T, size_t R>
constexpr auto matrix<T,R,R>::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<typename T, size_t W>
constexpr matrix<T,W,W> matrix<T,W,W>::transpose()const{
template<typename T, size_t R>
constexpr matrix<T,R,R> matrix<T,R,R>::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<typename T, size_t W>
constexpr matrix<T,W,W> matrix<T,W,W>::inverse()const{
template<typename T, size_t R>
constexpr matrix<T,R,R> matrix<T,R,R>::inverse()const{
return math::inverse(*this);
}
@ -261,83 +261,82 @@ namespace math{
}
template<typename T, typename U, size_t W, size_t H>
constexpr bool operator==(const matrix<T,W,H>& left, const matrix<U,W,H> right){
template<typename T, typename U, size_t R, size_t C>
constexpr bool operator==(const matrix_base<T,R,C>& left, const matrix_base<U,R,C> right){
for(size_t i = 0;i < left.size();++i){
if(left.get(i) != right.get(i))
return false;
}
return true;
}
template<typename T, typename U, size_t W, size_t H>
constexpr bool operator!=(const matrix<T,W,H>& left, const matrix<U,W,H> right){
template<typename T, typename U, size_t R, size_t C>
constexpr bool operator!=(const matrix_base<T,R,C>& left, const matrix_base<U,R,C> right){
return !(left == right);
}
template<typename T, typename U, size_t R1, size_t C1, size_t C2>
constexpr auto operator*(const matrix<T,C1,R1>& left, const matrix<U,C2,C1>& right){
constexpr auto operator*(const matrix<T,R1,C1>& left, const matrix<U,C1,C2>& right){
using res_t = decltype(std::declval<T>() * std::declval<U>());
matrix<res_t,C2,R1> res(no_initialize);
matrix<res_t,R1,C2> 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<typename T, typename U, size_t C, size_t R>
constexpr auto operator*(const matrix<T,C,R>& left, U&& right){
template<typename T, typename U, size_t C, size_t R, std::enable_if_t<!is_matrix<U>::value,int>>
constexpr auto operator*(const matrix<T,R,C>& left, U&& right){
using res_t = decltype(std::declval<T>() * std::declval<U>());
matrix<res_t,C,R> res(no_initialize);
matrix<res_t,R,C> res(no_initialize);
for(size_t i = 0;i < left.size();++i){
res.get(i) = left.get(i) * std::forward<U>(right);
}
return res;
}
template<typename T, typename U, size_t C, size_t R>
constexpr auto operator*(U&& left, const matrix<T,C,R>& right){
template<typename T, typename U, size_t C, size_t R, std::enable_if_t<!is_matrix<U>::value,int>>
constexpr auto operator*(U&& left, const matrix<T,R,C>& right){
using res_t = decltype(std::declval<T>() * std::declval<U>());
matrix<res_t,C,R> res(no_initialize);
matrix<res_t,R,C> res(no_initialize);
for(size_t i = 0;i < right.size();++i){
res.get(i) = std::forward<U>(left) * right.get(i);
}
return res;
}
template<typename T, typename U, size_t C, size_t R>
constexpr auto operator/(const matrix<T,C,R>& left, U&& right){
template<typename T, typename U, size_t C, size_t R, std::enable_if_t<!is_matrix<U>::value,int>>
constexpr auto operator/(const matrix<T,R,C>& left, U&& right){
using res_t = decltype(std::declval<T>() / std::declval<U>());
matrix<res_t,C,R> res(no_initialize);
matrix<res_t,R,C> res(no_initialize);
for(size_t i = 0;i < left.size();++i){
res.get(i) = left.get(i) / std::forward<U>(right);
}
return res;
}
template<typename T, typename U, size_t C, size_t R>
constexpr auto operator+(const matrix<T,C,R>& left, const matrix<U,C,R>& right){
constexpr auto operator+(const matrix<T,R,C>& left, const matrix<U,R,C>& right){
using res_t = decltype(std::declval<T>() + std::declval<U>());
matrix<res_t,C,R> res(no_initialize);
matrix<res_t,R,C> res(no_initialize);
for(size_t i = 0;i < left.size();++i){
res.get(i) = left.get(i) + right.get(i);
}
return res;
}
template<typename T, typename U, size_t C, size_t R>
constexpr auto operator-(const matrix<T,C,R>& left, const matrix<U,C,R>& right){
constexpr auto operator-(const matrix<T,R,C>& left, const matrix<U,R,C>& right){
using res_t = decltype(std::declval<T>() - std::declval<U>());
matrix<res_t,C,R> res(no_initialize);
matrix<res_t,R,C> res(no_initialize);
for(size_t i = 0;i < left.size();++i){
res.get(i) = left.get(i) - right.get(i);
}
return res;
}
template<typename T, typename U, size_t C, size_t R>
constexpr auto operator-(const matrix<T,C,R>& left){
using res_t = decltype(std::declval<T>() - std::declval<U>());
matrix<res_t,C,R> res(no_initialize);
constexpr auto operator-(const matrix<T,R,C>& left){
using res_t = decltype(-std::declval<U>());
matrix<res_t,R,C> 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<typename T, typename U, size_t R1, size_t C1, size_t C2>
constexpr decltype(auto) operator*=(matrix<T,C1,R1>& left, const matrix<U,C2,C1>& right){
template<typename T, typename U, size_t R>
constexpr decltype(auto) operator*=(matrix<T,R,R>& left, const matrix<U,R,R>& 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<typename T, typename U, size_t C, size_t R>
constexpr decltype(auto) operator*=(matrix<T,C,R>& left, U&& right){
template<typename T, typename U, size_t C, size_t R, std::enable_if_t<!is_matrix<U>::value,int>>
constexpr decltype(auto) operator*=(matrix<T,R,C>& left, U&& right){
for(size_t i = 0;i < left.size();++i){
left.get(i) = left.get(i) * std::forward<U>(right);
}
return left;
}
template<typename T, typename U, size_t C, size_t R>
constexpr decltype(auto) operator/=(matrix<T,C,R>& left, U&& right){
template<typename T, typename U, size_t C, size_t R, std::enable_if_t<!is_matrix<U>::value,int>>
constexpr decltype(auto) operator/=(matrix<T,R,C>& left, U&& right){
for(size_t i = 0;i < left.size();++i){
left.get(i) = left.get(i) / std::forward<U>(right);
}
return left;
}
template<typename T, typename U, size_t C, size_t R>
constexpr decltype(auto) operator+=(matrix<T,C,R>& left, const matrix<U,C,R>& right){
constexpr decltype(auto) operator+=(matrix<T,R,C>& left, const matrix<U,R,C>& right){
for(size_t i = 0;i < left.size();++i){
left.get(i) = left.get(i) + right.get(i);
}
return left;
}
template<typename T, typename U, size_t C, size_t R>
constexpr decltype(auto) operator-=(matrix<T,C,R>& left, const matrix<U,C,R>& right){
constexpr decltype(auto) operator-=(matrix<T,R,C>& left, const matrix<U,R,C>& right){
for(size_t i = 0;i < left.size();++i){
left.get(i) = left.get(i) - right.get(i);
}