From d8fea7f2b4abda430ebfe65aa65002cab2e9ce42 Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Thu, 3 Aug 2023 08:06:18 +0200 Subject: A5: WIP --- a5/imatrix.h | 204 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 204 insertions(+) create mode 100644 a5/imatrix.h (limited to 'a5/imatrix.h') diff --git a/a5/imatrix.h b/a5/imatrix.h new file mode 100644 index 0000000..f96cb0c --- /dev/null +++ b/a5/imatrix.h @@ -0,0 +1,204 @@ +// -*- c++ -*- +#pragma once + +#include +#include +#include + +class Imatrix +{ +public: + Imatrix() = default; + + explicit Imatrix(std::size_t w, std::size_t h) + : data(0, w * h) + , w(w) + , h(h) + { + } + + Imatrix(Imatrix&& other) + { + *this = std::move(other); + } + + Imatrix(const Imatrix& other) + { + *this = other; + } + + Imatrix& operator=(Imatrix&& other) + { + w = other.w; + other.w = 0; + h = other.h; + other.h = 0; + data = std::move(other.data); + return *this; + } + + Imatrix& operator=(const Imatrix& other) + { + w = other.w; + h = other.h; + data = other.data; + return *this; + } + + int& 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]; + } + + const int& 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]; + } + + + Imatrix operator+(const Imatrix& other) const + { + if(w != other.w || h != other.h) + throw std::invalid_argument("Dimension mismatch"); + Imatrix m(*this); + m.data += other.data; + return m; + } + + Imatrix operator+(int val) const + { + Imatrix m(*this); + m.data += val; + return m; + } + + Imatrix operator-(const Imatrix& other) const + { + if(w != other.w || h != other.h) + throw std::invalid_argument("Dimension mismatch"); + Imatrix m(*this); + m.data -= other.data; + return m; + } + + Imatrix operator-(int val) + { + Imatrix m(*this); + m.data -= val; + return m; + } + + Imatrix operator%(const Imatrix& other) const + { + if(w != other.w || h != other.h) + throw std::invalid_argument("Dimension mismatch"); + Imatrix m(*this); + m.data %= other.data; + return m; + } + + Imatrix operator%(int val) const + { + Imatrix m(*this); + m.data %= val; + return m; + } + + Imatrix operator*(const Imatrix& other) const + { + if(w != other.h || h != other.w) + throw std::invalid_argument("Dimension mismatch"); + + Imatrix out(w, other.h); + for(std::size_t i = 0; i < w; ++i) + { + for(std::size_t j = 0; j < other.h; ++j) + { + out.m(i,j) = 0; + for(std::size_t k = 0; k < other.w; ++k) + { + out.m(i,j) += m(i, j) * other.m(k, j); + } + } + } + + return out; + } + + Imatrix operator*(int val) const + { + Imatrix m(*this); + m.data *= val; + return m; + } + + Imatrix operator/(const Imatrix& other) const + { + if(w != other.h || h != other.w) + throw std::invalid_argument("Dimension mismatch"); + + Imatrix out(w, other.h); + for(std::size_t i = 0; i < w; ++i) + { + for(std::size_t j = 0; j < other.h; ++j) + { + out.m(i,j) = 0; + for(std::size_t k = 0; k < other.w; ++k) + { + out.m(i,j) += m(i, j) / other.m(k, j); + } + } + } + + return out; + } + + Imatrix operator/(int val) const + { + Imatrix m(*this); + m.data /= val; + return m; + } + + struct pos_t + { + std::size_t x; + std::size_t y; + }; + + void Move(pos_t from, pos_t to) + { + m(to.x, to.x) = m(from.x, from.x); + m(from.x, from.y) = 0; + } + + std::vector Row(std::size_t n) const + { + if(n >= h) throw std::out_of_range("Subscript out of range."); + std::vector out; + for(std::size_t x = 0; x < w; ++x) + { + out.push_back(m(x, n)); + } + return out; + } + + std::vector Column(std::size_t n) const + { + if(n >= w) throw std::out_of_range("Subscript out of range."); + std::vector out; + for(std::size_t y = 0; y < h; ++y) + { + out.push_back(m(n, y)); + } + return out; + } + +private: + // Invariant; at all times data contains w * h initialized data members + std::valarray data; // default initialized to empty + std::size_t w{}; // default initialized to 0 + std::size_t h{}; // default initialized to 0 +}; -- cgit v1.2.3