#pragma once #include #include #include template struct Matrix { public: Matrix() : elements{} {}; Matrix(T scalar) { std::fill(elements, elements + R * C, scalar); }; template Matrix(Args... args): elements{ args... } {}; Matrix(T values[R * C]) { std::copy(values, values + R * C, elements); }; static Matrix identity() { Matrix result{}; for (int i = 0; i < R; i++) { result(i, i) = 1; } return result; } Vector row(size_t index) { return { &elements[index * C] }; } Vector col(size_t index) { Vector result{}; for (int i = 0; i < R; i++) { result[i] = this->operator()(index, i); } return result; } Matrix operator+(Matrix other) { Matrix result{}; for (int i = 0; i < R * C; i++) { result.elements[i] = elements[i] + other.elements[i]; } return result; } Matrix operator*(float scalar) { Matrix result{}; for (int i = 0; i < R * C; i++) { result.elements[i] = elements[i] * scalar; } return result; } template Matrix operator*(Matrix other) { Matrix result{}; for (int y = 0; y < R; y++) { for (int x = 0; x < N; x++) { auto r = row(y); auto c = other.col(x); auto dot = r * c; result(x, y) = dot; } } return result; } Vector operator*(Vector vector) { Matrix matrix(vector.elements); matrix = this->operator*(matrix); return { matrix.elements }; } auto& operator()(size_t x, size_t y) { return elements[y * C + x]; } std::string string() { std::stringstream str{}; for (int x = 0; x < R; x++) { for (int y = 0; y < C; y++) { str << this->operator()(x, y) << " "; } str << "\n"; } return str.str(); } T elements[R * C]; };