stream any size of matrix

master
Marc Wäckerlin 8 years ago
parent 740b210135
commit cf97d057ff
  1. 2
      debian/control.in
  2. 4
      src/makefile.am
  3. 74
      src/matrix.hxx
  4. 31
      test/basic.cxx
  5. 3
      test/makefile.am

2
debian/control.in vendored

@ -1,7 +1,7 @@
Source: @PACKAGE_NAME@ Source: @PACKAGE_NAME@
Priority: extra Priority: extra
Maintainer: @AUTHOR@ 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@ Package: @PACKAGE_NAME@
Section: libs Section: libs

@ -10,4 +10,8 @@
include_HEADERS = matrix.hxx include_HEADERS = matrix.hxx
lib_LTLIBRARIES = libmatricxx.la
libmatricxx_la_SOURCES = version.cxx
MAINTAINERCLEANFILES = makefile.in MAINTAINERCLEANFILES = makefile.in

@ -52,13 +52,13 @@ namespace math {
template<typename TYPE, typename ARRAY=TYPE*> class MatrixBase { template<typename TYPE, typename ARRAY=TYPE*> class MatrixBase {
//..............................................................constants //..............................................................variables
public: protected:
const size_t ROWS; size_t ROWS;
const size_t COLUMNS; size_t COLUMNS;
const size_t SIZE; size_t SIZE;
const size_t MEM_SIZE; size_t MEM_SIZE;
//...............................................................typedefs //...............................................................typedefs
public: public:
@ -157,6 +157,14 @@ template<typename TYPE, typename ARRAY=TYPE*> class MatrixBase {
return ConstRowVector(*this, (TYPE*)_c+row*COLUMNS); return ConstRowVector(*this, (TYPE*)_c+row*COLUMNS);
} }
size_t rows() const {
return ROWS;
}
size_t columns() const {
return COLUMNS;
}
///} ///}
/// @name operators /// @name operators
@ -511,6 +519,19 @@ template<typename TYPE> class Matrix<TYPE, 0, 0>: public MatrixBase<TYPE> {
///@name special operations ///@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<void(TYPE&)> fn) { Matrix& apply(std::function<void(TYPE&)> fn) {
Parent::apply(fn); Parent::apply(fn);
return *this; return *this;
@ -661,9 +682,9 @@ template<typename TYPE, size_t ROWS, size_t COLUMNS>
template<typename TYPE, size_t ROWS, size_t COLUMNS> template<typename TYPE, size_t ROWS, size_t COLUMNS>
std::ostream& operator<<(std::ostream& s, const Matrix<TYPE, ROWS, COLUMNS>& m) { std::ostream& operator<<(std::ostream& s, const Matrix<TYPE, ROWS, COLUMNS>& m) {
s<<'['<<ROWS<<'x'<<COLUMNS<<"]{"; s<<'['<<m.rows()<<'x'<<m.columns()<<"]{";
for (size_t row = 0; row < m.ROWS; ++row) { for (size_t row = 0; row < m.rows(); ++row) {
for (size_t column = 0; column < m.COLUMNS; ++column) { for (size_t column = 0; column < m.columns(); ++column) {
if (row!=0||column!=0) s<<','; if (row!=0||column!=0) s<<',';
s<<m(row, column); s<<m(row, column);
} }
@ -679,12 +700,37 @@ template<typename TYPE, size_t ROWS, size_t COLUMNS>
TYPE val(0); TYPE val(0);
std::string s; std::string s;
if (!in.get(c) || c!='[') throw err; 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, '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, ']') || !(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<typename TYPE>
std::istream& operator>>(std::istream& in, Matrix<TYPE, 0, 0>& 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; if (!in.get(c) || c!='{') throw err;
for (size_t row = 0; row < m.ROWS; ++row) { for (size_t row = 0; row < m.rows(); ++row) {
for (size_t column = 0; column < m.COLUMNS; ++column) { for (size_t column = 0; column < m.columns(); ++column) {
if (row==m.ROWS-1&&column==m.COLUMNS) { if (row==m.rows()-1&&column==m.columns()-1) {
if (!std::getline(in, s, '}') || !(std::stringstream(s)>>val)) throw err; if (!std::getline(in, s, '}') || !(std::stringstream(s)>>val)) throw err;
} else { } else {
if (!std::getline(in, s, ',') || !(std::stringstream(s)>>val)) throw err; if (!std::getline(in, s, ',') || !(std::stringstream(s)>>val)) throw err;

@ -274,6 +274,17 @@ class TemplateMatrixTest: public CppUnit::TestFixture {
m.inv(); m.inv();
CPPUNIT_ASSERT_EQUAL(m.i(), m*o); CPPUNIT_ASSERT_EQUAL(m.i(), m*o);
CPPUNIT_ASSERT_EQUAL(res, m); CPPUNIT_ASSERT_EQUAL(res, m);
} {
Matrix<T,3,3> m(1, 3, 1,
1, 1, 2,
2, 3, 4);
const Matrix<T,3,3> res(2, 9, -5,
0, -2, 1,
-1, -3, 2);
Matrix<T,3,3> o(m);
m.inv();
CPPUNIT_ASSERT_EQUAL(m.i(), m*o);
CPPUNIT_ASSERT_EQUAL(res, m);
} { } {
Matrix<T,4,4> m(2, 1, 4, 1, Matrix<T,4,4> m(2, 1, 4, 1,
-1, 1, 0, 2, -1, 1, 0, 2,
@ -720,6 +731,20 @@ class VariableMatrixTest: public CppUnit::TestFixture {
CPPUNIT_ASSERT_EQUAL(res, m); CPPUNIT_ASSERT_EQUAL(res, m);
} }
} }
template<typename T>
void stream() {
const Matrix<T> m1(3, 4,
1, 2, 3, 4,
5, 6, 7, 8,
1, 4, 2, 8);
Matrix<T> m2(1, 1);
std::string res("[3x4]{1,2,3,4,5,6,7,8,1,4,2,8}");
std::stringstream ss;
ss<<m1;
CPPUNIT_ASSERT_EQUAL(res, ss.str());
ss>>m2;
CPPUNIT_ASSERT_EQUAL(m1, m2);
}
CPPUNIT_TEST_SUITE(VariableMatrixTest); CPPUNIT_TEST_SUITE(VariableMatrixTest);
CPPUNIT_TEST(initFromArray1<int>); CPPUNIT_TEST(initFromArray1<int>);
CPPUNIT_TEST(initFromArray1<long>); CPPUNIT_TEST(initFromArray1<long>);
@ -811,6 +836,12 @@ class VariableMatrixTest: public CppUnit::TestFixture {
CPPUNIT_TEST(inv<float>); CPPUNIT_TEST(inv<float>);
CPPUNIT_TEST(inv<double>); CPPUNIT_TEST(inv<double>);
CPPUNIT_TEST(inv<long double>); CPPUNIT_TEST(inv<long double>);
CPPUNIT_TEST(stream<int>);
CPPUNIT_TEST(stream<long>);
CPPUNIT_TEST(stream<unsigned>);
CPPUNIT_TEST(stream<unsigned long>);
CPPUNIT_TEST(stream<float>);
CPPUNIT_TEST(stream<double>);
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
}; };
CPPUNIT_TEST_SUITE_REGISTRATION(VariableMatrixTest); CPPUNIT_TEST_SUITE_REGISTRATION(VariableMatrixTest);

@ -10,8 +10,7 @@
AM_CPPFLAGS = -I${top_srcdir}/src -I${top_builddir}/src AM_CPPFLAGS = -I${top_srcdir}/src -I${top_builddir}/src
AM_LDFLAGS = -L${abs_top_builddir}/src/.libs AM_LDFLAGS = -L${abs_top_builddir}/src/.libs
LDADD = -lcppunit LDADD = -lcppunit -lmatricxx
#LDADD = -lmatricxx
check_PROGRAMS = basic check_PROGRAMS = basic
TESTS = ${check_PROGRAMS} TESTS = ${check_PROGRAMS}

Loading…
Cancel
Save