Specialize on square matrices
This commit is contained in:
parent
1c89b24ce4
commit
932335bdc5
@ -27,7 +27,7 @@
|
|||||||
namespace math{
|
namespace math{
|
||||||
|
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t W, size_t H>
|
||||||
class matrix
|
class matrix_base
|
||||||
{
|
{
|
||||||
static_assert(W > 0, "Cannot have 0 columns matrix");
|
static_assert(W > 0, "Cannot have 0 columns matrix");
|
||||||
static_assert(H > 0, "Cannot have 0 rows matrix");
|
static_assert(H > 0, "Cannot have 0 rows matrix");
|
||||||
@ -46,37 +46,32 @@ namespace math{
|
|||||||
value_type m_data[W*H];
|
value_type m_data[W*H];
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
template<size_type... Ss>
|
template<size_t... Ss>
|
||||||
constexpr matrix(std::integer_sequence<size_type,Ss...>);
|
constexpr matrix_base(std::integer_sequence<size_type,Ss...>);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//Default construct as identity when square, zero otherwise
|
//Default construct as identity when square, zero otherwise
|
||||||
constexpr matrix();
|
constexpr matrix_base();
|
||||||
|
|
||||||
//Range initializing constructors
|
//Range initializing constructors
|
||||||
constexpr explicit matrix(detail::zero_initialize_t);
|
constexpr explicit matrix_base(detail::zero_initialize_t);
|
||||||
constexpr explicit matrix(detail::no_initialize_t);
|
constexpr explicit matrix_base(detail::no_initialize_t);
|
||||||
template<typename U = void>
|
|
||||||
constexpr explicit matrix(detail::id_initialize_t);
|
|
||||||
|
|
||||||
//Value initializing constructors
|
//Value initializing constructors
|
||||||
constexpr explicit matrix(value_type v);
|
constexpr explicit matrix_base(value_type v);
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
constexpr explicit matrix(Args&&... args);
|
constexpr explicit matrix_base(Args&&... args);
|
||||||
|
|
||||||
//Copying constructors
|
//Copying constructors
|
||||||
constexpr matrix(const matrix&) = default;
|
constexpr matrix_base(const matrix_base&) = default;
|
||||||
constexpr matrix(matrix&&) = default;
|
constexpr matrix_base(matrix_base&&) = default;
|
||||||
template<typename U>
|
template<typename U>
|
||||||
constexpr matrix(const matrix<U,Columns,Rows>& m);
|
constexpr matrix_base(const matrix_base<U,Columns,Rows>& m);
|
||||||
~matrix() = default;
|
~matrix_base() = default;
|
||||||
|
|
||||||
//Assignement
|
constexpr matrix_base& operator=(const matrix_base&) = default;
|
||||||
|
constexpr matrix_base& operator=(matrix_base&&) = default;
|
||||||
template<typename U>
|
template<typename U>
|
||||||
constexpr matrix& operator=(const matrix<U,Columns,Rows>& m);
|
constexpr matrix_base& operator=(const matrix_base<U,Columns,Rows>& m);
|
||||||
constexpr matrix& operator=(const matrix&) = default;
|
|
||||||
constexpr matrix& operator=(matrix&&) = default;
|
|
||||||
|
|
||||||
|
|
||||||
//Getters/Setters
|
//Getters/Setters
|
||||||
constexpr auto operator[](size_type x);
|
constexpr auto operator[](size_type x);
|
||||||
@ -95,14 +90,66 @@ namespace math{
|
|||||||
constexpr operator pointer();
|
constexpr operator pointer();
|
||||||
constexpr operator const_pointer()const;
|
constexpr operator const_pointer()const;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T, size_t W, size_t H>
|
||||||
|
class matrix : public matrix_base<T,W,H>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
using base = matrix_base<T,W,H>;
|
||||||
|
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<typename U>
|
||||||
|
constexpr matrix& operator=(const matrix<U,W,H>& m);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T, size_t W>
|
||||||
|
class matrix<T,W,W> : public matrix_base<T,W,W>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
using base = matrix_base<T,W,W>;
|
||||||
|
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<typename U>
|
||||||
|
constexpr matrix& operator=(const matrix<U,W,W>& m);
|
||||||
|
|
||||||
//square matrix arithmetic operations
|
//square matrix arithmetic operations
|
||||||
template<typename U = T>
|
|
||||||
constexpr value_type determinate()const;
|
constexpr value_type determinate()const;
|
||||||
template<typename U = T>
|
|
||||||
constexpr value_type trace()const;
|
constexpr value_type trace()const;
|
||||||
template<typename U = T>
|
|
||||||
constexpr matrix transpose()const;
|
constexpr matrix transpose()const;
|
||||||
template<typename U = T>
|
|
||||||
constexpr matrix inverse()const;
|
constexpr matrix inverse()const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -27,40 +27,33 @@
|
|||||||
namespace math{
|
namespace math{
|
||||||
|
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t W, size_t H>
|
||||||
template<typename matrix<T,W,H>::size_type... Ss>
|
template<size_t... Ss>
|
||||||
constexpr matrix<T,W,H>::matrix(std::integer_sequence<size_type,Ss...>):
|
constexpr matrix_base<T,W,H>::matrix_base(std::integer_sequence<size_type,Ss...>):
|
||||||
m_data{Ss...}{}
|
m_data{Ss...}{}
|
||||||
|
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t W, size_t H>
|
||||||
constexpr matrix<T,W,H>::matrix():
|
constexpr matrix_base<T,W,H>::matrix_base():
|
||||||
matrix(typename detail::default_initialization_matrix<Columns,Rows>::tuple{}){}
|
matrix_base(typename detail::default_initialization_matrix<Columns,Rows>::tuple{}){}
|
||||||
|
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t W, size_t H>
|
||||||
constexpr matrix<T,W,H>::matrix(detail::zero_initialize_t):
|
constexpr matrix_base<T,W,H>::matrix_base(detail::zero_initialize_t):
|
||||||
m_data{}{}
|
m_data{}{}
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t W, size_t H>
|
||||||
constexpr matrix<T,W,H>::matrix(detail::no_initialize_t){}
|
constexpr matrix_base<T,W,H>::matrix_base(detail::no_initialize_t){}
|
||||||
template<typename T, size_t W, size_t H>
|
|
||||||
template<typename U>
|
|
||||||
constexpr matrix<T,W,H>::matrix(detail::id_initialize_t):
|
|
||||||
matrix()
|
|
||||||
{
|
|
||||||
static_assert(Columns == Rows, "Identity initialization only supported on square matrices");
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t W, size_t H>
|
||||||
constexpr matrix<T,W,H>::matrix(value_type v){
|
constexpr matrix_base<T,W,H>::matrix_base(value_type v){
|
||||||
for(size_type i = 0;i < Columns*Rows;++i)
|
for(size_type i = 0;i < Columns*Rows;++i)
|
||||||
m_data[i] = v;
|
m_data[i] = v;
|
||||||
}
|
}
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t W, size_t H>
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
constexpr matrix<T,W,H>::matrix(Args&&... args):
|
constexpr matrix_base<T,W,H>::matrix_base(Args&&... args):
|
||||||
m_data{std::forward<Args>(args)...}{}
|
m_data{std::forward<Args>(args)...}{}
|
||||||
|
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t W, size_t H>
|
||||||
template<typename U>
|
template<typename U>
|
||||||
constexpr matrix<T,W,H>::matrix(const matrix<U,Columns,Rows>& m){
|
constexpr matrix_base<T,W,H>::matrix_base(const matrix_base<U,Columns,Rows>& m){
|
||||||
using mat = decltype(m);
|
using mat = decltype(m);
|
||||||
for(typename mat::size_type i = 0;i < mat::Columns*mat::Rows;++i)
|
for(typename mat::size_type i = 0;i < mat::Columns*mat::Rows;++i)
|
||||||
m_data[i] = m.get(i);
|
m_data[i] = m.get(i);
|
||||||
@ -68,7 +61,7 @@ namespace math{
|
|||||||
|
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t W, size_t H>
|
||||||
template<typename U>
|
template<typename U>
|
||||||
constexpr matrix<T,W,H>& matrix<T,W,H>::operator=(const matrix<U,Columns,Rows>& m){
|
constexpr matrix_base<T,W,H>& matrix_base<T,W,H>::operator=(const matrix_base<U,Columns,Rows>& m){
|
||||||
using mat = decltype(m);
|
using mat = decltype(m);
|
||||||
for(typename mat::size_type i = 0;i < mat::Columns*mat::Rows;++i)
|
for(typename mat::size_type i = 0;i < mat::Columns*mat::Rows;++i)
|
||||||
m_data[i] = m.get(i);
|
m_data[i] = m.get(i);
|
||||||
@ -77,77 +70,90 @@ namespace math{
|
|||||||
|
|
||||||
|
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t W, size_t H>
|
||||||
constexpr auto matrix<T,W,H>::operator[](size_type x){
|
constexpr auto matrix_base<T,W,H>::operator[](size_type x){
|
||||||
return detail::mat_ref_obj<value_type,Rows>{m_data, x};
|
return detail::mat_ref_obj<value_type,Rows>{m_data, x};
|
||||||
}
|
}
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t W, size_t H>
|
||||||
constexpr auto matrix<T,W,H>::operator[](size_type x)const{
|
constexpr auto matrix_base<T,W,H>::operator[](size_type x)const{
|
||||||
return detail::mat_ref_obj<const value_type,Rows>{m_data, x};
|
return detail::mat_ref_obj<const value_type,Rows>{m_data, x};
|
||||||
}
|
}
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t W, size_t H>
|
||||||
constexpr auto matrix<T,W,H>::get(size_type x, size_type y) -> reference{
|
constexpr auto matrix_base<T,W,H>::get(size_type x, size_type y) -> reference{
|
||||||
return m_data[x+(y*Rows)];
|
return m_data[x+(y*Rows)];
|
||||||
}
|
}
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t W, size_t H>
|
||||||
constexpr auto matrix<T,W,H>::get(size_type x, size_type y)const -> const_reference{
|
constexpr auto matrix_base<T,W,H>::get(size_type x, size_type y)const -> const_reference{
|
||||||
return m_data[x+(y*Rows)];
|
return m_data[x+(y*Rows)];
|
||||||
}
|
}
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t W, size_t H>
|
||||||
constexpr auto matrix<T,W,H>::get(size_type i) -> reference{
|
constexpr auto matrix_base<T,W,H>::get(size_type i) -> reference{
|
||||||
return m_data[i];
|
return m_data[i];
|
||||||
}
|
}
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t W, size_t H>
|
||||||
constexpr auto matrix<T,W,H>::get(size_type i)const -> const_reference{
|
constexpr auto matrix_base<T,W,H>::get(size_type i)const -> const_reference{
|
||||||
return m_data[i];
|
return m_data[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t W, size_t H>
|
||||||
constexpr auto matrix<T,W,H>::columns()const -> size_type{
|
constexpr auto matrix_base<T,W,H>::columns()const -> size_type{
|
||||||
return Columns;
|
return Columns;
|
||||||
}
|
}
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t W, size_t H>
|
||||||
constexpr auto matrix<T,W,H>::rows()const -> size_type{
|
constexpr auto matrix_base<T,W,H>::rows()const -> size_type{
|
||||||
return Rows;
|
return Rows;
|
||||||
}
|
}
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t W, size_t H>
|
||||||
constexpr auto matrix<T,W,H>::size()const -> size_type{
|
constexpr auto matrix_base<T,W,H>::size()const -> size_type{
|
||||||
return Columns*Rows;
|
return Columns*Rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t W, size_t H>
|
||||||
constexpr auto matrix<T,W,H>::raw() -> pointer{
|
constexpr auto matrix_base<T,W,H>::raw() -> pointer{
|
||||||
return m_data;
|
return m_data;
|
||||||
}
|
}
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t W, size_t H>
|
||||||
constexpr auto matrix<T,W,H>::raw()const -> const_pointer{
|
constexpr auto matrix_base<T,W,H>::raw()const -> const_pointer{
|
||||||
return m_data;
|
return m_data;
|
||||||
}
|
}
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t W, size_t H>
|
||||||
constexpr matrix<T,W,H>::operator pointer(){
|
constexpr matrix_base<T,W,H>::operator pointer(){
|
||||||
return m_data;
|
return m_data;
|
||||||
}
|
}
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t W, size_t H>
|
||||||
constexpr matrix<T,W,H>::operator const_pointer()const{
|
constexpr matrix_base<T,W,H>::operator const_pointer()const{
|
||||||
return m_data;
|
return m_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t W, size_t H>
|
||||||
template<typename U>
|
template<typename U>
|
||||||
constexpr auto matrix<T,W,H>::determinate()const -> value_type{
|
constexpr matrix<T,W,H>& matrix<T,W,H>::operator=(const matrix<U,W,H>& m){
|
||||||
static_assert(W == H, "Determinate can only be calculated on square matrix");
|
base::operator=(m);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, size_t W>
|
||||||
|
constexpr matrix<T,W,W>::matrix(detail::id_initialize_t):
|
||||||
|
base(){}
|
||||||
|
template<typename T, size_t W>
|
||||||
|
template<typename U>
|
||||||
|
constexpr matrix<T,W,W>& matrix<T,W,W>::operator=(const matrix<U,W,W>& m){
|
||||||
|
base::operator=(m);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, size_t W>
|
||||||
|
constexpr auto matrix<T,W,W>::determinate()const -> value_type{
|
||||||
return math::determinate(*this);
|
return math::determinate(*this);
|
||||||
}
|
}
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t W>
|
||||||
template<typename U>
|
constexpr auto matrix<T,W,W>::trace()const -> value_type{
|
||||||
constexpr auto matrix<T,W,H>::trace()const -> value_type{
|
|
||||||
static_assert(W == H, "Trace can only be calculated on square matrix");
|
|
||||||
value_type sum = 0;
|
value_type sum = 0;
|
||||||
for(size_type i = 0;i < W;++i){
|
for(size_type i = 0;i < W;++i){
|
||||||
sum += get(i, i);
|
sum += get(i, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t W>
|
||||||
template<typename U>
|
constexpr matrix<T,W,W> matrix<T,W,W>::transpose()const{
|
||||||
constexpr matrix<T,W,H> matrix<T,W,H>::transpose()const{
|
|
||||||
matrix m(no_initialize);
|
matrix m(no_initialize);
|
||||||
for(size_type i = 0;i < W;++i){
|
for(size_type i = 0;i < W;++i){
|
||||||
for(size_type j = 0;j < W;++j){
|
for(size_type j = 0;j < W;++j){
|
||||||
@ -156,10 +162,8 @@ namespace math{
|
|||||||
}
|
}
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t W>
|
||||||
template<typename U>
|
constexpr matrix<T,W,W> matrix<T,W,W>::inverse()const{
|
||||||
constexpr matrix<T,W,H> matrix<T,W,H>::inverse()const{
|
|
||||||
static_assert(W == H, "Trace can only be calculated on square matrix");
|
|
||||||
return math::inverse(*this);
|
return math::inverse(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user