summaryrefslogtreecommitdiff
path: root/a5/matrix.h
diff options
context:
space:
mode:
Diffstat (limited to 'a5/matrix.h')
-rw-r--r--a5/matrix.h136
1 files changed, 89 insertions, 47 deletions
diff --git a/a5/matrix.h b/a5/matrix.h
index af83683..6d880e2 100644
--- a/a5/matrix.h
+++ b/a5/matrix.h
@@ -4,33 +4,71 @@
#include <utility>
#include <valarray>
#include <stdexcept>
+#include <concepts>
-template<typename T, std::size_t W, std::size_t H>
+template<typename T1, typename T2>
+concept supports_modulo =
+ requires(T1 t1, T2 t2)
+ {
+ t1 % t2;
+ };
+
+template<typename T>
+concept supports_matrix =
+ requires(T a, T b, int i)
+ {
+ a * b;
+ a / b;
+ a + b;
+ a - b;
+
+ a * i;
+ a / i;
+ a + i;
+ a - i;
+
+ a *= b;
+ a /= b;
+ a += b;
+ a -= b;
+
+ a *= i;
+ a /= i;
+ a += i;
+ a -= i;
+
+ a = b;
+ a = {};
+ };
+
+
+template<typename T, std::size_t N, std::size_t M>
+ requires supports_matrix<T>
class Matrix
{
public:
Matrix()
- : data(T{}, W * H)
+ : data(T{}, N * M)
{
}
- Matrix(Matrix<T, W, H>&& other)
+ Matrix(Matrix<T, N, M>&& other)
{
*this = std::move(other);
}
- Matrix(const Matrix<T, W, H>& other)
+ Matrix(const Matrix<T, N, M>& other)
{
*this = other;
}
- Matrix& operator=(Matrix<T, W, H>&& other)
+ Matrix& operator=(Matrix<T, N, M>&& other)
{
data = std::move(other.data);
return *this;
}
- Matrix& operator=(const Matrix<T, W, H>& other)
+ Matrix& operator=(const Matrix<T, N, M>& other)
{
data = other.data;
return *this;
@@ -38,70 +76,74 @@ public:
T& m(std::size_t x, std::size_t y)
{
- if(x >= W || y >= H) throw std::out_of_range("Subscript out of range.");
- return data[x + y * W];
+ if(x >= N) throw std::out_of_range("Subscript x out of range.");
+ if(y >= M) throw std::out_of_range("Subscript y out of range.");
+ return data[x + y * N];
}
const T& m(std::size_t x, std::size_t y) const
{
- if(x >= W || y >= H) throw std::out_of_range("Subscript out of range.");
- return data[x + y * W];
+ if(x >= N) throw std::out_of_range("Subscript x out of range.");
+ if(y >= M) throw std::out_of_range("Subscript y out of range.");
+ return data[x + y * N];
}
- Matrix<T, W, H> operator+(const Matrix<T, W, H>& other) const
+ Matrix<T, N, M> operator+(const Matrix<T, N, M>& other) const
{
Matrix m(*this);
m.data += other.data;
return m;
}
- Matrix<T, W, H> operator+(T val)
+ Matrix<T, N, M> operator+(int val)
{
- Matrix<T, W, H> m(*this);
- m.data += val;
+ Matrix<T, N, M> m(*this);
+ for(auto& d : m.data) d += val;
return m;
}
- Matrix<T, W, H> operator-(const Matrix<T, W, H>& other) const
+ Matrix<T, N, M> operator-(const Matrix<T, N, M>& other) const
{
- Matrix<T, W, H> m(*this);
+ Matrix<T, N, M> m(*this);
m.data -= other.data;
return m;
}
- Matrix <T, W, H>operator-(T val)
+ Matrix <T, N, M> operator-(int val)
{
- Matrix<T, W, H> m(*this);
- m.data -= val;
+ Matrix<T, N, M> m(*this);
+ for(auto& d : m.data) d -= val;
return m;
}
- Matrix<T, W, H> operator%(const Matrix<T, W, H>& other) const
+ Matrix<T, N, M> operator%(const Matrix<T, N, M>& other) const
+ requires(supports_modulo<T,T>)
{
- Matrix<T, W, H> m(*this);
+ Matrix<T, N, M> m(*this);
m.data %= other.data;
return m;
}
- Matrix<T, W, H> operator%(T val)
+ Matrix<T, N, M> operator%(int val)
+ requires(supports_modulo<T,int>)
{
Matrix m(*this);
- m.data %= val;
+ for(auto& d : m.data) d %= val;
return m;
}
- template<std::size_t N>
- Matrix<T, W, N> operator*(const Matrix<T, H, N>& other) const
+ template<std::size_t R>
+ Matrix<T, N, R> operator*(const Matrix<T, M, R>& other) const
{
- Matrix<T, W, N> out;
- for(std::size_t i = 0; i < W; ++i)
+ Matrix<T, N, R> out;
+ for(std::size_t i = 0; i < N; ++i)
{
- for(std::size_t j = 0; j < N; ++j)
+ for(std::size_t j = 0; j < R; ++j)
{
out.m(i,j) = {};
- for(std::size_t k = 0; k < H; ++k)
+ for(std::size_t k = 0; k < M; ++k)
{
- out.m(i,j) += m(i, j) * other.m(k, j);
+ out.m(i,j) += m(i,k) * other.m(k,j);
}
}
}
@@ -109,25 +151,25 @@ public:
return out;
}
- Matrix<T, W, H> operator*(T val)
+ Matrix<T, N, M> operator*(int val)
{
- Matrix<T, W, H> m(*this);
- m.data *= val;
+ Matrix<T, N, M> m(*this);
+ for(auto& d : m.data) d *= val;
return m;
}
- template<std::size_t N>
- Matrix<T, W, N> operator/(const Matrix<T, H, N>& other) const
+ template<std::size_t R>
+ Matrix<T, N, R> operator/(const Matrix<T, M, R>& other) const
{
- Matrix<T, W, N> out;
- for(std::size_t i = 0; i < W; ++i)
+ Matrix<T, N, R> out;
+ for(std::size_t i = 0; i < N; ++i)
{
- for(std::size_t j = 0; j < N; ++j)
+ for(std::size_t j = 0; j < R; ++j)
{
out.m(i,j) = {};
- for(std::size_t k = 0; k < H; ++k)
+ for(std::size_t k = 0; k < M; ++k)
{
- out.m(i,j) += m(i, j) / other.m(k, j);
+ out.m(i,j) += m(i,k) / other.m(k,j);
}
}
}
@@ -135,10 +177,10 @@ public:
return out;
}
- Matrix<T, W, H> operator/(T val) const
+ Matrix<T, N, M> operator/(int val) const
{
- Matrix<T, W, H> m(*this);
- m.data /= val;
+ Matrix<T, N, M> m(*this);
+ for(auto& d : m.data) d /= val;
return m;
}
@@ -156,9 +198,9 @@ public:
std::vector<T> Row(std::size_t n) const
{
- if(n >= H) throw std::out_of_range("Subscript out of range.");
+ if(n >= M) throw std::out_of_range("Subscript out of range.");
std::vector<T> out;
- for(std::size_t x = 0; x < W; ++x)
+ for(std::size_t x = 0; x < N; ++x)
{
out.push_back(m(x, n));
}
@@ -167,9 +209,9 @@ public:
std::vector<T> Column(std::size_t n) const
{
- if(n >= W) throw std::out_of_range("Subscript out of range.");
+ if(n >= N) throw std::out_of_range("Subscript out of range.");
std::vector<T> out;
- for(std::size_t y = 0; y < H; ++y)
+ for(std::size_t y = 0; y < M; ++y)
{
out.push_back(m(n, y));
}