From 0189f28f43f9582796b1c9f0b0959324713b78d0 Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 23 Oct 2020 15:10:57 +0300 Subject: [PATCH] PIMathMatrix add trace, assert for non square matrix, assert in operator * --- libs/main/math/pimathmatrix.h | 70 ++++++++++++++++---------------- tests/math/testpimathmatrix.cpp | 12 ------ tests/math/testpimathmatrixt.cpp | 14 ------- 3 files changed, 34 insertions(+), 62 deletions(-) diff --git a/libs/main/math/pimathmatrix.h b/libs/main/math/pimathmatrix.h index 94cf9480..f1fedb55 100644 --- a/libs/main/math/pimathmatrix.h +++ b/libs/main/math/pimathmatrix.h @@ -393,6 +393,20 @@ public: return ret; } + /** + * @brief Trace of the matrix is calculated. Works only with square matrix, nonzero matrices and invertible matrix + * + * @return matrix trace + */ + Type trace() const { + static_assert(Rows == Cols, "Works only with square matrix"); + Type ret = Type(0); + for (uint i = 0; i < Cols; ++i) { + ret += m[i][i]; + } + return ret; + } + /** * @brief Transforming matrix to upper triangular. Works only with square matrix, nonzero matrices and invertible matrix * @@ -400,10 +414,7 @@ public: * @return copy of transformed upper triangular matrix */ _CMatrix &toUpperTriangular(bool *ok = 0) { - if (Cols != Rows) { - if (ok != 0) *ok = false; - return *this; - } + static_assert(Rows == Cols, "Works only with square matrix"); _CMatrix smat(*this); bool ndet; uint crow; @@ -443,7 +454,7 @@ public: * @return copy of inverted matrix */ _CMatrix &invert(bool *ok = 0) { - static_assert(Cols == Rows, "Only square matrix invertable"); + static_assert(Rows == Cols, "Works only with square matrix"); _CMatrix mtmp = _CMatrix::identity(), smat(*this); bool ndet; uint crow; @@ -972,8 +983,8 @@ public: Type determinant(bool *ok = 0) const { _CMatrix m(*this); bool k; - Type ret = Type(0); m.toUpperTriangular(&k); + Type ret = Type(0); if (ok) *ok = k; if (!k) return ret; ret = Type(1); @@ -987,19 +998,14 @@ public: /** * @brief Trace of the matrix is calculated. Works only with square matrix, nonzero matrices and invertible matrix * - * @param ok is a parameter with which we can find out if the method worked correctly * @return matrix trace */ - Type trace(bool *ok = 0) const { + Type trace() const { + assert(isSquare()); Type ret = Type(0); - if (!isSquare()) { - if (ok != 0) *ok = false; - return ret; - } for (uint i = 0; i < _V2D::cols_; ++i) { ret += _V2D::element(i, i); } - if (ok != 0) *ok = true; return ret; } @@ -1010,10 +1016,7 @@ public: * @return copy of transformed upper triangular matrix */ _CMatrix &toUpperTriangular(bool *ok = 0) { - if (!isSquare()) { - if (ok != 0) *ok = false; - return *this; - } + assert(isSquare()); _CMatrix smat(*this); bool ndet; uint crow; @@ -1054,10 +1057,7 @@ public: * @return copy of inverted matrix */ _CMatrix &invert(bool *ok = 0, PIMathVector *sv = 0) { - if (!isSquare()) { - if (ok != 0) *ok = false; - return *this; - } + assert(isSquare()); _CMatrix mtmp = _CMatrix::identity(_V2D::cols_, _V2D::rows_), smat(*this); bool ndet; uint crow; @@ -1196,14 +1196,13 @@ inline PIByteArray &operator>>(PIByteArray &s, PIMathMatrix &v) { template inline PIMathMatrix operator*(const PIMathMatrix &fm, const PIMathMatrix &sm) { - uint cr = fm.cols(), rows0 = fm.rows(), cols1 = sm.cols(); - PIMathMatrix tm(cols1, rows0); - if (fm.cols() != sm.rows()) return tm; + assert(fm.cols() == sm.rows()); + PIMathMatrix tm(sm.cols(), fm.rows()); Type t; - for (uint j = 0; j < rows0; ++j) { - for (uint i = 0; i < cols1; ++i) { + for (uint j = 0; j < fm.rows(); ++j) { + for (uint i = 0; i < sm.cols(); ++i) { t = Type(0); - for (uint k = 0; k < cr; ++k) + for (uint k = 0; k < fm.cols(); ++k) t += fm.element(j, k) * sm.element(k, i); tm.element(j, i) = t; } @@ -1221,13 +1220,12 @@ inline PIMathMatrix operator*(const PIMathMatrix &fm, template inline PIMathVector operator*(const PIMathMatrix &fm, const PIMathVector &sv) { - uint c = fm.cols(), r = fm.rows(); - PIMathVector tv(r); - if (c != sv.size()) return tv; + assert(fm.cols() == sv.size()); + PIMathVector tv(fm.rows()); Type t; - for (uint j = 0; j < r; ++j) { + for (uint j = 0; j < fm.rows(); ++j) { t = Type(0); - for (uint i = 0; i < c; ++i) + for (uint i = 0; i < fm.cols(); ++i) t += fm.element(j, i) * sv[i]; tv[j] = t; } @@ -1244,12 +1242,12 @@ inline PIMathVector operator*(const PIMathMatrix &fm, template inline PIMathVector operator*(const PIMathVector &sv, const PIMathMatrix &fm) { - uint c = fm.cols(), r = fm.rows(); - PIMathVector tv(c); + PIMathVector tv(fm.cols()); + assert(fm.rows() == sv.size()); Type t; - for (uint j = 0; j < c; ++j) { + for (uint j = 0; j < fm.cols(); ++j) { t = Type(0); - for (uint i = 0; i < r; ++i) + for (uint i = 0; i < fm.rows(); ++i) t += fm.element(i, j) * sv[i]; tv[j] = t; } diff --git a/tests/math/testpimathmatrix.cpp b/tests/math/testpimathmatrix.cpp index 05de2e14..94f3076b 100644 --- a/tests/math/testpimathmatrix.cpp +++ b/tests/math/testpimathmatrix.cpp @@ -355,12 +355,6 @@ TEST(PIMathMatrix_Test, determinantIfSquare) { ASSERT_DOUBLE_EQ(d, i); } -TEST(PIMathMatrix_Test, determinantIfNotSquare) { - PIMathMatrix matrix(3, 5, 1.0); - matrix.element(1,1) = 5.0; - ASSERT_FALSE(matrix.determinant()); -} - TEST(PIMathMatrix_Test, trace) { PIMathMatrix matrix(3, 3, 0.0); double t; @@ -383,12 +377,6 @@ TEST(PIMathMatrix_Test, trace) { ASSERT_DOUBLE_EQ(t, i); } -TEST(PIMathMatrix_Test, traceIfNotSquare) { - PIMathMatrix matrix(3, 5, 1.0); - matrix.element(1,1) = 5.0; - ASSERT_FALSE(matrix.trace()); -} - TEST(PIMathMatrix_Test, toUpperTriangular) { PIMathMatrix matrix(3, 3, 0.0); double d1, d2 = 1; diff --git a/tests/math/testpimathmatrixt.cpp b/tests/math/testpimathmatrixt.cpp index 210ad947..5f3a20bf 100644 --- a/tests/math/testpimathmatrixt.cpp +++ b/tests/math/testpimathmatrixt.cpp @@ -356,20 +356,6 @@ TEST(PIMathMatrixT_Test, determinantIfSquare) { ASSERT_DOUBLE_EQ(i, d); } -TEST(PIMathMatrixT_Test, determinantIfNotSquare) { - PIMathMatrixT matr; - matr.element(0,0) = 3; - matr.element(0,1) = 6; - matr.element(0,2) = 8; - matr.element(1,0) = 2; - matr.element(1,1) = 1; - matr.element(1,2) = 4; - matr.element(2,0) = 6; - matr.element(2,1) = 2; - matr.element(2,2) = 5; - ASSERT_FALSE(matr.determinant()); -} - TEST(PIMathMatrixT_Test, invert) { PIMathMatrixT matrix1; PIMathMatrixT matrix2;