From 034a5fddfb292f22659f293d72ceb576f5c61d82 Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Thu, 3 Aug 2023 16:18:00 +0200 Subject: A5: code complete --- a5/matrix.h | 136 +++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 89 insertions(+), 47 deletions(-) (limited to 'a5/matrix.h') 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 #include #include +#include -template +template +concept supports_modulo = + requires(T1 t1, T2 t2) + { + t1 % t2; + }; + +template +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 + requires supports_matrix class Matrix { public: Matrix() - : data(T{}, W * H) + : data(T{}, N * M) { } - Matrix(Matrix&& other) + Matrix(Matrix&& other) { *this = std::move(other); } - Matrix(const Matrix& other) + Matrix(const Matrix& other) { *this = other; } - Matrix& operator=(Matrix&& other) + Matrix& operator=(Matrix&& other) { data = std::move(other.data); return *this; } - Matrix& operator=(const Matrix& other) + Matrix& operator=(const Matrix& 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 operator+(const Matrix& other) const + Matrix operator+(const Matrix& other) const { Matrix m(*this); m.data += other.data; return m; } - Matrix operator+(T val) + Matrix operator+(int val) { - Matrix m(*this); - m.data += val; + Matrix m(*this); + for(auto& d : m.data) d += val; return m; } - Matrix operator-(const Matrix& other) const + Matrix operator-(const Matrix& other) const { - Matrix m(*this); + Matrix m(*this); m.data -= other.data; return m; } - Matrix operator-(T val) + Matrix operator-(int val) { - Matrix m(*this); - m.data -= val; + Matrix m(*this); + for(auto& d : m.data) d -= val; return m; } - Matrix operator%(const Matrix& other) const + Matrix operator%(const Matrix& other) const + requires(supports_modulo) { - Matrix m(*this); + Matrix m(*this); m.data %= other.data; return m; } - Matrix operator%(T val) + Matrix operator%(int val) + requires(supports_modulo) { Matrix m(*this); - m.data %= val; + for(auto& d : m.data) d %= val; return m; } - template - Matrix operator*(const Matrix& other) const + template + Matrix operator*(const Matrix& other) const { - Matrix out; - for(std::size_t i = 0; i < W; ++i) + Matrix 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 operator*(T val) + Matrix operator*(int val) { - Matrix m(*this); - m.data *= val; + Matrix m(*this); + for(auto& d : m.data) d *= val; return m; } - template - Matrix operator/(const Matrix& other) const + template + Matrix operator/(const Matrix& other) const { - Matrix out; - for(std::size_t i = 0; i < W; ++i) + Matrix 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 operator/(T val) const + Matrix operator/(int val) const { - Matrix m(*this); - m.data /= val; + Matrix m(*this); + for(auto& d : m.data) d /= val; return m; } @@ -156,9 +198,9 @@ public: std::vector 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 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 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 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)); } -- cgit v1.2.3