/** * @file Slice.hpp * * A simple matrix template library. * * @author Julian Kent < julian@auterion.com > */ #pragma once #include "math.hpp" namespace matrix { template class Matrix; template class Vector; template class Slice { public: Slice(size_t x0, size_t y0, const Matrix* data) : _x0(x0), _y0(y0), _data(const_cast*>(data)) { static_assert(P <= M, "Slice rows bigger than backing matrix"); static_assert(Q <= N, "Slice cols bigger than backing matrix"); } Type operator()(size_t i, size_t j) const { return (*_data)(_x0 + i, _y0 + j); } Type &operator()(size_t i, size_t j) { return (*_data)(_x0 + i, _y0 + j); } template Slice& operator=(const Slice& other) { Slice& self = *this; for (size_t i = 0; i < P; i++) { for (size_t j = 0; j < Q; j++) { self(i, j) = other(i, j); } } return self; } Slice& operator=(const Matrix& other) { Slice& self = *this; for (size_t i = 0; i < P; i++) { for (size_t j = 0; j < Q; j++) { self(i, j) = other(i, j); } } return self; } // allow assigning vectors to a slice that are in the axis template // make this a template function since it only exists for some instantiations Slice& operator=(const Vector& other) { Slice& self = *this; for (size_t j = 0; j < Q; j++) { self(0, j) = other(j); } return self; } template const Slice slice(size_t x0, size_t y0) const { return Slice(x0 + _x0, y0 + _y0, _data); } template Slice slice(size_t x0, size_t y0) { return Slice(x0 + _x0, y0 + _y0, _data); } void copyTo(Type dst[M*N]) const { const Slice &self = *this; for (size_t i = 0; i < M; i++) { for (size_t j = 0; j < N; j++) { dst[i*N+j] = self(i, j); } } } void copyToColumnMajor(Type dst[M*N]) const { const Slice &self = *this; for (size_t i = 0; i < M; i++) { for (size_t j = 0; j < N; j++) { dst[i+(j*M)] = self(i, j); } } } Type norm_squared() { Slice& self = *this; Type accum(0); for (size_t i = 0; i < P; i++) { for (size_t j = 0; j < Q; j++) { accum += self(i, j)*self(i, j); } } return accum; } Type norm() { return matrix::sqrt(norm_squared()); } bool longerThan(Type testVal) { return norm_squared() > testVal*testVal; } private: size_t _x0, _y0; Matrix* _data; }; }