Fix matrix naming stuff so it's not so confusing no more
This commit is contained in:
parent
932335bdc5
commit
c7d5978d6d
@ -26,11 +26,11 @@
|
|||||||
|
|
||||||
namespace math{
|
namespace math{
|
||||||
|
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t R, size_t C>
|
||||||
class matrix_base
|
class matrix_base
|
||||||
{
|
{
|
||||||
static_assert(W > 0, "Cannot have 0 columns matrix");
|
static_assert(C > 0, "Cannot have 0 columns matrix");
|
||||||
static_assert(H > 0, "Cannot have 0 rows matrix");
|
static_assert(R > 0, "Cannot have 0 rows matrix");
|
||||||
public:
|
public:
|
||||||
using value_type = T;
|
using value_type = T;
|
||||||
using size_type = size_t;
|
using size_type = size_t;
|
||||||
@ -39,11 +39,11 @@ namespace math{
|
|||||||
using reference = value_type&;
|
using reference = value_type&;
|
||||||
using const_reference = const value_type&;
|
using const_reference = const value_type&;
|
||||||
|
|
||||||
static constexpr size_type Columns = W;
|
static constexpr size_type Columns = C;
|
||||||
static constexpr size_type Rows = H;
|
static constexpr size_type Rows = R;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
value_type m_data[W*H];
|
value_type m_data[R*C];
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
template<size_t... Ss>
|
template<size_t... Ss>
|
||||||
@ -92,11 +92,11 @@ namespace math{
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t R, size_t C>
|
||||||
class matrix : public matrix_base<T,W,H>
|
class matrix : public matrix_base<T,R,C>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
using base = matrix_base<T,W,H>;
|
using base = matrix_base<T,R,C>;
|
||||||
public:
|
public:
|
||||||
using value_type = typename base::value_type;
|
using value_type = typename base::value_type;
|
||||||
using size_type = typename base::size_type;
|
using size_type = typename base::size_type;
|
||||||
@ -116,14 +116,14 @@ namespace math{
|
|||||||
constexpr matrix& operator=(const matrix&) = default;
|
constexpr matrix& operator=(const matrix&) = default;
|
||||||
constexpr matrix& operator=(matrix&&) = default;
|
constexpr matrix& operator=(matrix&&) = default;
|
||||||
template<typename U>
|
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>
|
template<typename T, size_t R>
|
||||||
class matrix<T,W,W> : public matrix_base<T,W,W>
|
class matrix<T,R,R> : public matrix_base<T,R,R>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
using base = matrix_base<T,W,W>;
|
using base = matrix_base<T,R,R>;
|
||||||
public:
|
public:
|
||||||
using value_type = typename base::value_type;
|
using value_type = typename base::value_type;
|
||||||
using size_type = typename base::size_type;
|
using size_type = typename base::size_type;
|
||||||
@ -144,7 +144,7 @@ namespace math{
|
|||||||
constexpr matrix& operator=(const matrix&) = default;
|
constexpr matrix& operator=(const matrix&) = default;
|
||||||
constexpr matrix& operator=(matrix&&) = default;
|
constexpr matrix& operator=(matrix&&) = default;
|
||||||
template<typename U>
|
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
|
//square matrix arithmetic operations
|
||||||
constexpr value_type determinate()const;
|
constexpr value_type determinate()const;
|
||||||
@ -191,8 +191,8 @@ namespace math{
|
|||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct is_matrix_helper {
|
struct is_matrix_helper {
|
||||||
template<typename U, size_t W, size_t H>
|
template<typename U, size_t R, size_t C>
|
||||||
static std::true_type test(matrix<U,W,H>*);
|
static std::true_type test(matrix_base<U,R,C>*);
|
||||||
static std::false_type test(void*);
|
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;
|
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>
|
template<typename T, typename U, size_t R, size_t C>
|
||||||
constexpr bool operator==(const matrix<T,W,H>& left, const matrix<U,W,H> right);
|
constexpr bool operator==(const matrix_base<T,R,C>& left, const matrix_base<U,R,C> right);
|
||||||
template<typename T, typename U, size_t W, size_t H>
|
template<typename T, typename U, size_t R, size_t C>
|
||||||
constexpr bool operator!=(const matrix<T,W,H>& left, const matrix<U,W,H> right);
|
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>
|
template<typename T, typename U, size_t R1, size_t C1, size_t R2>
|
||||||
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,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>
|
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>
|
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>
|
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);
|
||||||
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);
|
|
||||||
|
|
||||||
template<typename T, typename U, size_t R1, size_t C1, size_t C2>
|
template<typename T, typename U, size_t R>
|
||||||
constexpr decltype(auto) operator*=(matrix<T,C1,R1>& left, const matrix<U,C2,C1>& right);
|
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>
|
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>
|
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, 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);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
187
include/mat.tpp
187
include/mat.tpp
@ -26,42 +26,42 @@
|
|||||||
|
|
||||||
namespace math{
|
namespace math{
|
||||||
|
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t R, size_t C>
|
||||||
template<size_t... Ss>
|
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...}{}
|
m_data{Ss...}{}
|
||||||
|
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t R, size_t C>
|
||||||
constexpr matrix_base<T,W,H>::matrix_base():
|
constexpr matrix_base<T,R,C>::matrix_base():
|
||||||
matrix_base(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 R, size_t C>
|
||||||
constexpr matrix_base<T,W,H>::matrix_base(detail::zero_initialize_t):
|
constexpr matrix_base<T,R,C>::matrix_base(detail::zero_initialize_t):
|
||||||
m_data{}{}
|
m_data{}{}
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t R, size_t C>
|
||||||
constexpr matrix_base<T,W,H>::matrix_base(detail::no_initialize_t){}
|
constexpr matrix_base<T,R,C>::matrix_base(detail::no_initialize_t){}
|
||||||
|
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t R, size_t C>
|
||||||
constexpr matrix_base<T,W,H>::matrix_base(value_type v){
|
constexpr matrix_base<T,R,C>::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 R, size_t C>
|
||||||
template<typename... Args>
|
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)...}{}
|
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>
|
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);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t R, size_t C>
|
||||||
template<typename U>
|
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);
|
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);
|
||||||
@ -69,101 +69,101 @@ namespace math{
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t R, size_t C>
|
||||||
constexpr auto matrix_base<T,W,H>::operator[](size_type x){
|
constexpr auto matrix_base<T,R,C>::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 R, size_t C>
|
||||||
constexpr auto matrix_base<T,W,H>::operator[](size_type x)const{
|
constexpr auto matrix_base<T,R,C>::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 R, size_t C>
|
||||||
constexpr auto matrix_base<T,W,H>::get(size_type x, size_type y) -> reference{
|
constexpr auto matrix_base<T,R,C>::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 R, size_t C>
|
||||||
constexpr auto matrix_base<T,W,H>::get(size_type x, size_type y)const -> const_reference{
|
constexpr auto matrix_base<T,R,C>::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 R, size_t C>
|
||||||
constexpr auto matrix_base<T,W,H>::get(size_type i) -> reference{
|
constexpr auto matrix_base<T,R,C>::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 R, size_t C>
|
||||||
constexpr auto matrix_base<T,W,H>::get(size_type i)const -> const_reference{
|
constexpr auto matrix_base<T,R,C>::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 R, size_t C>
|
||||||
constexpr auto matrix_base<T,W,H>::columns()const -> size_type{
|
constexpr auto matrix_base<T,R,C>::columns()const -> size_type{
|
||||||
return Columns;
|
return Columns;
|
||||||
}
|
}
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t R, size_t C>
|
||||||
constexpr auto matrix_base<T,W,H>::rows()const -> size_type{
|
constexpr auto matrix_base<T,R,C>::rows()const -> size_type{
|
||||||
return Rows;
|
return Rows;
|
||||||
}
|
}
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t R, size_t C>
|
||||||
constexpr auto matrix_base<T,W,H>::size()const -> size_type{
|
constexpr auto matrix_base<T,R,C>::size()const -> size_type{
|
||||||
return Columns*Rows;
|
return Columns*Rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t R, size_t C>
|
||||||
constexpr auto matrix_base<T,W,H>::raw() -> pointer{
|
constexpr auto matrix_base<T,R,C>::raw() -> pointer{
|
||||||
return m_data;
|
return m_data;
|
||||||
}
|
}
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t R, size_t C>
|
||||||
constexpr auto matrix_base<T,W,H>::raw()const -> const_pointer{
|
constexpr auto matrix_base<T,R,C>::raw()const -> const_pointer{
|
||||||
return m_data;
|
return m_data;
|
||||||
}
|
}
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t R, size_t C>
|
||||||
constexpr matrix_base<T,W,H>::operator pointer(){
|
constexpr matrix_base<T,R,C>::operator pointer(){
|
||||||
return m_data;
|
return m_data;
|
||||||
}
|
}
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t R, size_t C>
|
||||||
constexpr matrix_base<T,W,H>::operator const_pointer()const{
|
constexpr matrix_base<T,R,C>::operator const_pointer()const{
|
||||||
return m_data;
|
return m_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, size_t W, size_t H>
|
template<typename T, size_t R, size_t C>
|
||||||
template<typename U>
|
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);
|
base::operator=(m);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, size_t W>
|
template<typename T, size_t R>
|
||||||
constexpr matrix<T,W,W>::matrix(detail::id_initialize_t):
|
constexpr matrix<T,R,R>::matrix(detail::id_initialize_t):
|
||||||
base(){}
|
base(){}
|
||||||
template<typename T, size_t W>
|
template<typename T, size_t R>
|
||||||
template<typename U>
|
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);
|
base::operator=(m);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, size_t W>
|
template<typename T, size_t R>
|
||||||
constexpr auto matrix<T,W,W>::determinate()const -> value_type{
|
constexpr auto matrix<T,R,R>::determinate()const -> value_type{
|
||||||
return math::determinate(*this);
|
return math::determinate(*this);
|
||||||
}
|
}
|
||||||
template<typename T, size_t W>
|
template<typename T, size_t R>
|
||||||
constexpr auto matrix<T,W,W>::trace()const -> value_type{
|
constexpr auto matrix<T,R,R>::trace()const -> value_type{
|
||||||
value_type sum = 0;
|
value_type sum = 0;
|
||||||
for(size_type i = 0;i < W;++i){
|
for(size_type i = 0;i < R;++i){
|
||||||
sum += get(i, i);
|
sum += get(i, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
template<typename T, size_t W>
|
template<typename T, size_t R>
|
||||||
constexpr matrix<T,W,W> matrix<T,W,W>::transpose()const{
|
constexpr matrix<T,R,R> matrix<T,R,R>::transpose()const{
|
||||||
matrix m(no_initialize);
|
matrix m(no_initialize);
|
||||||
for(size_type i = 0;i < W;++i){
|
for(size_type i = 0;i < R;++i){
|
||||||
for(size_type j = 0;j < W;++j){
|
for(size_type j = 0;j < R;++j){
|
||||||
m.get(j, i) = get(i, j);
|
m.get(j, i) = get(i, j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
template<typename T, size_t W>
|
template<typename T, size_t R>
|
||||||
constexpr matrix<T,W,W> matrix<T,W,W>::inverse()const{
|
constexpr matrix<T,R,R> matrix<T,R,R>::inverse()const{
|
||||||
return math::inverse(*this);
|
return math::inverse(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,83 +261,82 @@ namespace math{
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename T, typename U, size_t W, size_t H>
|
template<typename T, typename U, size_t R, size_t C>
|
||||||
constexpr bool operator==(const matrix<T,W,H>& left, const matrix<U,W,H> right){
|
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){
|
for(size_t i = 0;i < left.size();++i){
|
||||||
if(left.get(i) != right.get(i))
|
if(left.get(i) != right.get(i))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
template<typename T, typename U, size_t W, size_t H>
|
template<typename T, typename U, size_t R, size_t C>
|
||||||
constexpr bool operator!=(const matrix<T,W,H>& left, const matrix<U,W,H> right){
|
constexpr bool operator!=(const matrix_base<T,R,C>& left, const matrix_base<U,R,C> right){
|
||||||
return !(left == right);
|
return !(left == right);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename U, size_t R1, size_t C1, size_t C2>
|
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>());
|
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;
|
size_t index = 0;
|
||||||
for(size_t i = 0;i < right.rows();++i){
|
for(size_t i = 0;i < left.rows();++i){
|
||||||
for(size_t j = 0;j < left.rows();++j){
|
for(size_t j = 0;j < right.columns();++j){
|
||||||
for(size_t k = 0;k < left.columns();++k){
|
for(size_t k = 0;k < right.rows();++k){
|
||||||
res.get(index) += left[j][k] * right[i][k];
|
res.get(index) += left[i][k] * right[k][j];
|
||||||
}
|
}
|
||||||
++index;
|
++index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
template<typename T, typename U, size_t C, size_t R>
|
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,C,R>& left, U&& right){
|
constexpr auto operator*(const matrix<T,R,C>& left, U&& right){
|
||||||
using res_t = decltype(std::declval<T>() * std::declval<U>());
|
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){
|
for(size_t i = 0;i < left.size();++i){
|
||||||
res.get(i) = left.get(i) * std::forward<U>(right);
|
res.get(i) = left.get(i) * std::forward<U>(right);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
template<typename T, typename U, size_t C, size_t R>
|
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,C,R>& right){
|
constexpr auto operator*(U&& left, const matrix<T,R,C>& right){
|
||||||
using res_t = decltype(std::declval<T>() * std::declval<U>());
|
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){
|
for(size_t i = 0;i < right.size();++i){
|
||||||
res.get(i) = std::forward<U>(left) * right.get(i);
|
res.get(i) = std::forward<U>(left) * right.get(i);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
template<typename T, typename U, size_t C, size_t R>
|
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,C,R>& left, U&& right){
|
constexpr auto operator/(const matrix<T,R,C>& left, U&& right){
|
||||||
using res_t = decltype(std::declval<T>() / std::declval<U>());
|
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){
|
for(size_t i = 0;i < left.size();++i){
|
||||||
res.get(i) = left.get(i) / std::forward<U>(right);
|
res.get(i) = left.get(i) / std::forward<U>(right);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
template<typename T, typename U, size_t C, size_t R>
|
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>());
|
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){
|
for(size_t i = 0;i < left.size();++i){
|
||||||
res.get(i) = left.get(i) + right.get(i);
|
res.get(i) = left.get(i) + right.get(i);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
template<typename T, typename U, size_t C, size_t R>
|
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>());
|
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){
|
for(size_t i = 0;i < left.size();++i){
|
||||||
res.get(i) = left.get(i) - right.get(i);
|
res.get(i) = left.get(i) - right.get(i);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
template<typename T, typename U, size_t C, size_t R>
|
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){
|
||||||
using res_t = decltype(std::declval<T>() - std::declval<U>());
|
using res_t = decltype(-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){
|
for(size_t i = 0;i < left.size();++i){
|
||||||
res.get(i) = -left.get(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>
|
template<typename T, typename U, size_t R>
|
||||||
constexpr decltype(auto) operator*=(matrix<T,C1,R1>& left, const matrix<U,C2,C1>& right){
|
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
|
//have to evaluate entire expression first since matrix multiplication depends on reusing many elements
|
||||||
//cannot be expression templatized, TODO
|
//cannot be expression templatized, TODO
|
||||||
return (left = (left * right));
|
return (left = (left * right));
|
||||||
}
|
}
|
||||||
template<typename T, typename U, size_t C, size_t R>
|
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,C,R>& left, U&& right){
|
constexpr decltype(auto) operator*=(matrix<T,R,C>& left, U&& right){
|
||||||
for(size_t i = 0;i < left.size();++i){
|
for(size_t i = 0;i < left.size();++i){
|
||||||
left.get(i) = left.get(i) * std::forward<U>(right);
|
left.get(i) = left.get(i) * std::forward<U>(right);
|
||||||
}
|
}
|
||||||
return left;
|
return left;
|
||||||
}
|
}
|
||||||
template<typename T, typename U, size_t C, size_t R>
|
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,C,R>& left, U&& right){
|
constexpr decltype(auto) operator/=(matrix<T,R,C>& left, U&& right){
|
||||||
for(size_t i = 0;i < left.size();++i){
|
for(size_t i = 0;i < left.size();++i){
|
||||||
left.get(i) = left.get(i) / std::forward<U>(right);
|
left.get(i) = left.get(i) / std::forward<U>(right);
|
||||||
}
|
}
|
||||||
return left;
|
return left;
|
||||||
}
|
}
|
||||||
template<typename T, typename U, size_t C, size_t R>
|
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){
|
for(size_t i = 0;i < left.size();++i){
|
||||||
left.get(i) = left.get(i) + right.get(i);
|
left.get(i) = left.get(i) + right.get(i);
|
||||||
}
|
}
|
||||||
return left;
|
return left;
|
||||||
}
|
}
|
||||||
template<typename T, typename U, size_t C, size_t R>
|
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){
|
for(size_t i = 0;i < left.size();++i){
|
||||||
left.get(i) = left.get(i) - right.get(i);
|
left.get(i) = left.get(i) - right.get(i);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user