X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Flinal%2Fmatrix.h;h=2ad03447a9b10454f73ab982cf49f26dd25f983f;hb=HEAD;hp=94a6e0991b2d13502e2f998107d5e26f5831ad04;hpb=a3d9772a9fd483278b6248a811dc6f4ce968892b;p=libs%2Fmath.git diff --git a/source/linal/matrix.h b/source/linal/matrix.h index 94a6e09..2ad0344 100644 --- a/source/linal/matrix.h +++ b/source/linal/matrix.h @@ -2,17 +2,22 @@ #define MSP_LINAL_MATRIX_H_ #include +#include +#include "matrixops.h" #include "vector.h" namespace Msp { namespace LinAl { /** -A general mathematical matrix. +A general mathematical matrix with M rows and N columns. */ template class Matrix { +public: + typedef T ElementType; + private: T data[M*N]; @@ -22,22 +27,38 @@ public: template Matrix(const Matrix &); + static Matrix identity(); static Matrix from_columns(const Vector *); static Matrix from_rows(const Vector *); - T &element(unsigned, unsigned); - const T &element(unsigned, unsigned) const; - T &operator()(unsigned, unsigned); - const T &operator()(unsigned, unsigned) const; + unsigned rows() const { return M; } + unsigned columns() const { return N; } + + T &element(unsigned i, unsigned j) { return data[i+M*j]; } + const T &element(unsigned i, unsigned j) const { return data[i+M*j]; } + T &operator()(unsigned i, unsigned j) { return element(i, j); } + const T &operator()(unsigned i, unsigned j) const { return element(i, j); } + + Vector column(unsigned i) const { return Vector(data+M*i); } + Vector row(unsigned i) const { return Vector(data+i, M); } + + template + Matrix select(const Vector &, const Vector &) const; + + template + Matrix block(unsigned, unsigned) const; Matrix &operator*=(T); + Matrix &operator*=(const Matrix &); Matrix &operator/=(T); Matrix &operator+=(const Matrix &); Matrix &operator-=(const Matrix &); - Matrix &exchange_rows(unsigned, unsigned); - Matrix &multiply_row(unsigned, T); - Matrix &add_row(unsigned, unsigned, T); + Matrix &invert(); + + Matrix &exchange_columns(unsigned, unsigned); + Matrix &multiply_column(unsigned, T); + Matrix &add_column(unsigned, unsigned, T); }; template @@ -54,9 +75,21 @@ inline Matrix::Matrix(const T *d) template template -inline Matrix::Matrix(const Matrix &m) +inline Matrix::Matrix(const Matrix &other) +{ + for(unsigned i=0; i +inline Matrix Matrix::identity() { - std::copy(m.data, m.data+M*N, data); + static_assert(M==N, "An identity matrix must be square"); + Matrix m; + for(unsigned i=0; i @@ -66,6 +99,7 @@ inline Matrix Matrix::from_columns(const Vector *v) for(unsigned i=0; i @@ -75,30 +109,29 @@ inline Matrix Matrix::from_rows(const Vector *v) for(unsigned i=0; i -inline T &Matrix::element(unsigned i, unsigned j) -{ - return data[i+M*j]; -} - -template -inline const T &Matrix::element(unsigned i, unsigned j) const -{ - return data[i+M*j]; -} - -template -inline T &Matrix::operator()(unsigned i, unsigned j) +template +inline Matrix Matrix::select(const Vector &row_indices, const Vector &col_indices) const { - return element(i, j); + Matrix r; + for(unsigned j=0; j -inline const T &Matrix::operator()(unsigned i, unsigned j) const +template +inline Matrix Matrix::block(unsigned y, unsigned x) const { - return element(i, j); + Matrix r; + for(unsigned j=0; j @@ -109,6 +142,13 @@ inline Matrix &Matrix::operator*=(T s) return *this; } +template +inline Matrix &Matrix::operator*=(const Matrix &m) +{ + static_assert(M==N, "Multiplication-assignment is only possible on square matrices"); + return *this = *this*m; +} + template inline Matrix operator*(const Matrix &m, T s) { @@ -198,6 +238,23 @@ inline Matrix operator-(const Matrix &m1, const Matrix +inline Matrix& Matrix::invert() +{ + static_assert(M==N, "Inversion is only possible on square matrices"); + Matrix r = identity(); + gauss_jordan(*this, r); + return *this = r; +} + +template +inline Matrix invert(const Matrix &m) +{ + Matrix temp = m; + Matrix r = Matrix::identity(); + return gauss_jordan(temp, r); +} + template inline bool operator==(const Matrix &a, const Matrix &b) { @@ -209,26 +266,27 @@ inline bool operator==(const Matrix &a, const Matrix &b) } template -inline Matrix &Matrix::exchange_rows(unsigned i, unsigned j) +inline Matrix &Matrix::exchange_columns(unsigned i, unsigned j) { - for(unsigned k=0; k -inline Matrix &Matrix::multiply_row(unsigned i, T s) +inline Matrix &Matrix::multiply_column(unsigned i, T s) { - for(unsigned k=0; k -inline Matrix &Matrix::add_row(unsigned i, unsigned j, T s) +inline Matrix &Matrix::add_column(unsigned i, unsigned j, T s) { - for(unsigned k=0; k transpose(const Matrix &m) return r; } +template +inline std::ostream &operator<<(std::ostream &s, const Matrix &m) +{ + s << "Matrix" << M << 'x' << N << '('; + for(unsigned i=0; i