summaryrefslogtreecommitdiff
path: root/a5/imatrix_nm.h
diff options
context:
space:
mode:
Diffstat (limited to 'a5/imatrix_nm.h')
-rw-r--r--a5/imatrix_nm.h182
1 files changed, 182 insertions, 0 deletions
diff --git a/a5/imatrix_nm.h b/a5/imatrix_nm.h
new file mode 100644
index 0000000..970031a
--- /dev/null
+++ b/a5/imatrix_nm.h
@@ -0,0 +1,182 @@
+// -*- c++ -*-
+#pragma once
+
+#include <utility>
+#include <valarray>
+#include <stdexcept>
+
+template<std::size_t W, std::size_t H>
+class ImatrixNM
+{
+public:
+ ImatrixNM()
+ : data(0, W * H)
+ {
+ }
+
+ ImatrixNM(ImatrixNM<W, H>&& other)
+ {
+ *this = std::move(other);
+ }
+
+ ImatrixNM(const ImatrixNM<W, H>& other)
+ {
+ *this = other;
+ }
+
+ ImatrixNM& operator=(ImatrixNM<W, H>&& other)
+ {
+ data = std::move(other.data);
+ return *this;
+ }
+
+ ImatrixNM& operator=(const ImatrixNM<W, H>& other)
+ {
+ 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];
+ }
+
+ ImatrixNM<W, H> operator+(const ImatrixNM<W, H>& other) const
+ {
+ ImatrixNM m(*this);
+ m.data += other.data;
+ return m;
+ }
+
+ ImatrixNM<W, H> operator+(int val)
+ {
+ ImatrixNM<W, H> m(*this);
+ m.data += val;
+ return m;
+ }
+
+ ImatrixNM<W, H> operator-(const ImatrixNM<W, H>& other) const
+ {
+ ImatrixNM<W, H> m(*this);
+ m.data -= other.data;
+ return m;
+ }
+
+ ImatrixNM <W, H>operator-(int val)
+ {
+ ImatrixNM<W, H> m(*this);
+ m.data -= val;
+ return m;
+ }
+
+ ImatrixNM<W, H> operator%(const ImatrixNM<W, H>& other) const
+ {
+ ImatrixNM<W, H> m(*this);
+ m.data %= other.data;
+ return m;
+ }
+
+ ImatrixNM<W, H> operator%(int val)
+ {
+ ImatrixNM m(*this);
+ m.data %= val;
+ return m;
+ }
+
+ template<std::size_t N>
+ ImatrixNM<W, N> operator*(const ImatrixNM<H, N>& other) const
+ {
+ ImatrixNM<W, N> out;
+ for(std::size_t i = 0; i < W; ++i)
+ {
+ for(std::size_t j = 0; j < N; ++j)
+ {
+ out.m(i,j) = 0;
+ for(std::size_t k = 0; k < H; ++k)
+ {
+ out.m(i,j) += m(i, j) * other.m(k, j);
+ }
+ }
+ }
+
+ return out;
+ }
+
+ ImatrixNM<W, H> operator*(int val) const
+ {
+ ImatrixNM<W, H> m(*this);
+ m.data *= val;
+ return m;
+ }
+
+ template<std::size_t N>
+ ImatrixNM<W, N> operator/(const ImatrixNM<H, N>& other) const
+ {
+ ImatrixNM<W, N> out;
+ for(std::size_t i = 0; i < W; ++i)
+ {
+ for(std::size_t j = 0; j < N; ++j)
+ {
+ out.m(i,j) = 0;
+ for(std::size_t k = 0; k < H; ++k)
+ {
+ out.m(i,j) += m(i, j) / other.m(k, j);
+ }
+ }
+ }
+
+ return out;
+ }
+
+ ImatrixNM<W, H> operator/(int val) const
+ {
+ ImatrixNM<W, H> 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<int> Row(std::size_t n) const
+ {
+ if(n >= H) throw std::out_of_range("Subscript out of range.");
+ std::vector<int> out;
+ for(std::size_t x = 0; x < W; ++x)
+ {
+ out.push_back(m(x, n));
+ }
+ return out;
+ }
+
+ std::vector<int> Column(std::size_t n) const
+ {
+ if(n >= W) throw std::out_of_range("Subscript out of range.");
+ std::vector<int> 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<int> data; // default initialized to empty
+};