From cf97d057ffcaae26fcd36eb68c0ad5bff70ac6e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=A4ckerlin?= Date: Tue, 23 Aug 2016 13:58:31 +0000 Subject: [PATCH] stream any size of matrix --- debian/control.in | 2 +- src/makefile.am | 4 +++ src/matrix.hxx | 74 ++++++++++++++++++++++++++++++++++++++--------- test/basic.cxx | 31 ++++++++++++++++++++ test/makefile.am | 3 +- 5 files changed, 97 insertions(+), 17 deletions(-) diff --git a/debian/control.in b/debian/control.in index 610422f..d8d0ba2 100644 --- a/debian/control.in +++ b/debian/control.in @@ -1,7 +1,7 @@ Source: @PACKAGE_NAME@ Priority: extra Maintainer: @AUTHOR@ -Build-Depends: debhelper, subversion, pkg-config, automake, libtool, autotools-dev, lsb-release , doxygen, graphviz, mscgen, libcppunit-dev +Build-Depends: debhelper, subversion, pkg-config, automake, libtool, autotools-dev, lsb-release , doxygen, graphviz, mscgen, libcppunit-dev, g++ Package: @PACKAGE_NAME@ Section: libs diff --git a/src/makefile.am b/src/makefile.am index 56e90ae..3cf24db 100644 --- a/src/makefile.am +++ b/src/makefile.am @@ -10,4 +10,8 @@ include_HEADERS = matrix.hxx +lib_LTLIBRARIES = libmatricxx.la + +libmatricxx_la_SOURCES = version.cxx + MAINTAINERCLEANFILES = makefile.in diff --git a/src/matrix.hxx b/src/matrix.hxx index 0687868..ddc07d8 100644 --- a/src/matrix.hxx +++ b/src/matrix.hxx @@ -52,13 +52,13 @@ namespace math { template class MatrixBase { - //..............................................................constants - public: + //..............................................................variables + protected: - const size_t ROWS; - const size_t COLUMNS; - const size_t SIZE; - const size_t MEM_SIZE; + size_t ROWS; + size_t COLUMNS; + size_t SIZE; + size_t MEM_SIZE; //...............................................................typedefs public: @@ -157,6 +157,14 @@ template class MatrixBase { return ConstRowVector(*this, (TYPE*)_c+row*COLUMNS); } + size_t rows() const { + return ROWS; + } + + size_t columns() const { + return COLUMNS; + } + ///} /// @name operators @@ -511,6 +519,19 @@ template class Matrix: public MatrixBase { ///@name special operations ///{ + Matrix& resize(size_t rows, size_t columns) { + if (rows!=this->ROWS||columns!=this->COLUMNS) { + delete Parent::_c; + Parent::_c = new TYPE[rows*columns]; + this->ROWS = rows; + this->COLUMNS = columns; + this->SIZE = rows*columns; + this->MEM_SIZE = sizeof(TYPE)*rows*columns; + } + memset(Parent::_c, 0, Parent::MEM_SIZE); + return *this; + } + Matrix& apply(std::function fn) { Parent::apply(fn); return *this; @@ -661,9 +682,9 @@ template template std::ostream& operator<<(std::ostream& s, const Matrix& m) { - s<<'['< TYPE val(0); std::string s; if (!in.get(c) || c!='[') throw err; - if (!std::getline(in, s, 'x') || !(std::stringstream(s)>>sz) || sz!=m.ROWS) throw err; - if (!std::getline(in, s, ']') || !(std::stringstream(s)>>sz) || sz!=m.COLUMNS) throw err; + if (!std::getline(in, s, 'x') || !(std::stringstream(s)>>sz) || sz!=m.rows()) throw err; + if (!std::getline(in, s, ']') || !(std::stringstream(s)>>sz) || sz!=m.columns()) throw err; + if (!in.get(c) || c!='{') throw err; + for (size_t row = 0; row < m.rows(); ++row) { + for (size_t column = 0; column < m.columns(); ++column) { + if (row==m.rows()-1&&column==m.columns()-1) { + if (!std::getline(in, s, '}') || !(std::stringstream(s)>>val)) throw err; + } else { + if (!std::getline(in, s, ',') || !(std::stringstream(s)>>val)) throw err; + } + m(row, column) = val; + } + } + return in; +} + +template + std::istream& operator>>(std::istream& in, Matrix& m) { + std::ios_base::failure err("illegal matrix format"); + char c(0); + size_t rows(0), columns(0); + TYPE val(0); + std::string s; + if (!in.get(c) || c!='[') throw err; + if (!std::getline(in, s, 'x') || !(std::stringstream(s)>>rows) || rows<=0) throw err; + if (!std::getline(in, s, ']') || !(std::stringstream(s)>>columns) || columns<=0) throw err; + m.resize(rows, columns); if (!in.get(c) || c!='{') throw err; - for (size_t row = 0; row < m.ROWS; ++row) { - for (size_t column = 0; column < m.COLUMNS; ++column) { - if (row==m.ROWS-1&&column==m.COLUMNS) { + for (size_t row = 0; row < m.rows(); ++row) { + for (size_t column = 0; column < m.columns(); ++column) { + if (row==m.rows()-1&&column==m.columns()-1) { if (!std::getline(in, s, '}') || !(std::stringstream(s)>>val)) throw err; } else { if (!std::getline(in, s, ',') || !(std::stringstream(s)>>val)) throw err; diff --git a/test/basic.cxx b/test/basic.cxx index d44fe72..a6233a6 100644 --- a/test/basic.cxx +++ b/test/basic.cxx @@ -274,6 +274,17 @@ class TemplateMatrixTest: public CppUnit::TestFixture { m.inv(); CPPUNIT_ASSERT_EQUAL(m.i(), m*o); CPPUNIT_ASSERT_EQUAL(res, m); + } { + Matrix m(1, 3, 1, + 1, 1, 2, + 2, 3, 4); + const Matrix res(2, 9, -5, + 0, -2, 1, + -1, -3, 2); + Matrix o(m); + m.inv(); + CPPUNIT_ASSERT_EQUAL(m.i(), m*o); + CPPUNIT_ASSERT_EQUAL(res, m); } { Matrix m(2, 1, 4, 1, -1, 1, 0, 2, @@ -720,6 +731,20 @@ class VariableMatrixTest: public CppUnit::TestFixture { CPPUNIT_ASSERT_EQUAL(res, m); } } + template + void stream() { + const Matrix m1(3, 4, + 1, 2, 3, 4, + 5, 6, 7, 8, + 1, 4, 2, 8); + Matrix m2(1, 1); + std::string res("[3x4]{1,2,3,4,5,6,7,8,1,4,2,8}"); + std::stringstream ss; + ss<>m2; + CPPUNIT_ASSERT_EQUAL(m1, m2); + } CPPUNIT_TEST_SUITE(VariableMatrixTest); CPPUNIT_TEST(initFromArray1); CPPUNIT_TEST(initFromArray1); @@ -811,6 +836,12 @@ class VariableMatrixTest: public CppUnit::TestFixture { CPPUNIT_TEST(inv); CPPUNIT_TEST(inv); CPPUNIT_TEST(inv); + CPPUNIT_TEST(stream); + CPPUNIT_TEST(stream); + CPPUNIT_TEST(stream); + CPPUNIT_TEST(stream); + CPPUNIT_TEST(stream); + CPPUNIT_TEST(stream); CPPUNIT_TEST_SUITE_END(); }; CPPUNIT_TEST_SUITE_REGISTRATION(VariableMatrixTest); diff --git a/test/makefile.am b/test/makefile.am index 7814148..8904e48 100644 --- a/test/makefile.am +++ b/test/makefile.am @@ -10,8 +10,7 @@ AM_CPPFLAGS = -I${top_srcdir}/src -I${top_builddir}/src AM_LDFLAGS = -L${abs_top_builddir}/src/.libs -LDADD = -lcppunit -#LDADD = -lmatricxx +LDADD = -lcppunit -lmatricxx check_PROGRAMS = basic TESTS = ${check_PROGRAMS}