inverse does not work yet
This commit is contained in:
52
ChangeLog
52
ChangeLog
@@ -1,52 +0,0 @@
|
|||||||
2016-08-19 14:52
|
|
||||||
|
|
||||||
* COPYING, INSTALL, ax_cxx_compile_stdcxx_11.m4,
|
|
||||||
ax_init_standard_project.m4, bootstrap.sh, makefile_test.inc.am,
|
|
||||||
src/matrix.hxx, test/basic.cxx: more operators more tests
|
|
||||||
|
|
||||||
2016-08-18 22:03
|
|
||||||
|
|
||||||
* COPYING, ChangeLog, INSTALL, src/matrix.hxx: more operators
|
|
||||||
|
|
||||||
2016-08-17 07:26
|
|
||||||
|
|
||||||
* configure.ac: only requires c++11
|
|
||||||
|
|
||||||
2016-08-16 14:41
|
|
||||||
|
|
||||||
* COPYING, INSTALL, ax_init_standard_project.m4, configure.ac,
|
|
||||||
src/matrix.hxx, test/basic.cxx: remove redundancy, collect common
|
|
||||||
functionality in base class
|
|
||||||
|
|
||||||
2016-08-08 20:03
|
|
||||||
|
|
||||||
* src/matrix.hxx, test/basic.cxx: more operator, more checks passed
|
|
||||||
|
|
||||||
2016-08-03 18:43
|
|
||||||
|
|
||||||
* configure.ac, test/makefile.am: all tests passed
|
|
||||||
|
|
||||||
2016-08-03 18:39
|
|
||||||
|
|
||||||
* COPYING, ChangeLog, INSTALL, ax_cxx_compile_stdcxx_11.m4,
|
|
||||||
ax_init_standard_project.m4, configure.ac, examples/makefile.am,
|
|
||||||
examples/matrix-sample.cxx, src/makefile.am, src/matrix.hxx,
|
|
||||||
test/basic.cxx, test/makefile.am: first approach including first
|
|
||||||
tests
|
|
||||||
|
|
||||||
2016-07-30 08:50
|
|
||||||
|
|
||||||
* ., AUTHORS, ChangeLog, NEWS, README, autogen.sh, ax_check_qt.m4,
|
|
||||||
ax_cxx_compile_stdcxx_11.m4, ax_init_standard_project.m4,
|
|
||||||
bootstrap.sh, build-in-docker.conf, build-in-docker.sh,
|
|
||||||
build-resource-file.sh, configure.ac, debian,
|
|
||||||
debian/changelog.in, debian/compat, debian/control.in,
|
|
||||||
debian/docs, debian/libmatricxx-dev.install,
|
|
||||||
debian/libmatricxx.install, debian/rules, doc, doc/doxyfile.in,
|
|
||||||
doc/makefile.am, examples, examples/makefile.am,
|
|
||||||
libmatricxx.desktop.in, libmatricxx.spec.in,
|
|
||||||
mac-create-app-bundle.sh, makefile.am, resolve-debbuilddeps.sh,
|
|
||||||
resolve-rpmbuilddeps.sh, sql-to-dot.sed, src,
|
|
||||||
src/libmatricxx.pc.in, src/makefile.am, src/version.cxx,
|
|
||||||
src/version.hxx, test, test/makefile.am: initial project
|
|
||||||
|
|
||||||
|
112
src/matrix.hxx
112
src/matrix.hxx
@@ -177,26 +177,32 @@ template<typename TYPE, typename ARRAY=TYPE*> class MatrixBase {
|
|||||||
///{
|
///{
|
||||||
|
|
||||||
TYPE det() {
|
TYPE det() {
|
||||||
// rule of sarrus
|
TYPE res(gauss());
|
||||||
TYPE res(0);
|
for (TYPE *p((TYPE*)(_c)+SIZE); --p>=(TYPE*)(_c); p-=COLUMNS) res *= *p;
|
||||||
assert(ROWS==COLUMNS); // not really necessary
|
|
||||||
// 1) terms to add
|
|
||||||
for (size_t i(0); i<COLUMNS; ++i) {
|
|
||||||
TYPE term(1);
|
|
||||||
for (size_t j(0); j<ROWS; ++j)
|
|
||||||
term *= at((i+j)%COLUMNS, j);
|
|
||||||
res += term;
|
|
||||||
}
|
|
||||||
// 2) terms to subtract
|
|
||||||
for (size_t i(0); i<COLUMNS; ++i) {
|
|
||||||
TYPE term(1);
|
|
||||||
for (size_t j(0); j<ROWS; ++j)
|
|
||||||
term *= at((i+j)%COLUMNS, ROWS-j-1);
|
|
||||||
res -= term;
|
|
||||||
}
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TYPE gauss() {
|
||||||
|
/// calculate using gauss algorithmus
|
||||||
|
/// @see http://www.mathebibel.de/determinante-berechnen-nach-gauss
|
||||||
|
/// 1. normalize first line to first value
|
||||||
|
TYPE lambda(at(0, 0));
|
||||||
|
at(0, 0) = 1;
|
||||||
|
for (TYPE *p((TYPE*)(_c)+COLUMNS); p>(TYPE*)(_c)+1;) *--p/=lambda;
|
||||||
|
/// 2. nullify lower triangle
|
||||||
|
for (size_t column(0); column<COLUMNS-1; ++column) {
|
||||||
|
for (size_t row(column+1); row<ROWS; ++row) {
|
||||||
|
TYPE pivot(at(row, column));
|
||||||
|
if (pivot!=0) {
|
||||||
|
at(row, column) = 0;
|
||||||
|
for (size_t pos(column+1); pos<COLUMNS; ++pos)
|
||||||
|
at(row, pos) -= pivot*at(0, pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lambda;
|
||||||
|
}
|
||||||
|
|
||||||
///}
|
///}
|
||||||
|
|
||||||
//................................................................methods
|
//................................................................methods
|
||||||
@@ -284,6 +290,42 @@ template<typename TYPE, size_t TROWS=0, size_t TCOLUMNS=0> class Matrix:
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Matrix i() {
|
||||||
|
Matrix res;
|
||||||
|
for (size_t row(0); row<TROWS&&row<TCOLUMNS; ++row) res(row, row) = 1;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
Matrix& inv() {
|
||||||
|
/// calculate using gauss-jordan algorithmus
|
||||||
|
/// @see http://www.mathebibel.de/inverse-matrix-berechnen-nach-gauss-jordan
|
||||||
|
Matrix o(*this); // left side
|
||||||
|
*this = i(); // right side
|
||||||
|
/// 1. lower left part
|
||||||
|
for (size_t row(0); row<this->ROWS; ++row)
|
||||||
|
if (rows<this->COLUMNS) {
|
||||||
|
/// 2. normalize first line to first value
|
||||||
|
TYPE pivot(o(row, row));
|
||||||
|
if (pivot!=1) {
|
||||||
|
o(row, row) = 1;
|
||||||
|
for (size_t column(row+1); column<this->COLUMNS; ++column) o(row, column)/=pivot;
|
||||||
|
for (size_t column(row); column<this->COLUMNS; ++column) this->at(row, column)/=pivot;
|
||||||
|
}
|
||||||
|
/// 3. nullify lower triangle
|
||||||
|
for (size_t row(column+1); row<this->ROWS; ++row) {
|
||||||
|
TYPE pivot(o(row, column));
|
||||||
|
if (pivot!=0) {
|
||||||
|
o(row, column) = 0;
|
||||||
|
for (size_t pos(column+1); pos<this->COLUMNS; ++pos) o(row, pos) -= pivot*o(0, pos);
|
||||||
|
for (size_t pos(column); pos<this->COLUMNS; ++pos) this->at(row, pos) -= pivot*this->at(0, pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// 4. nullify the upper triangle
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
///}
|
///}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -306,6 +348,8 @@ template<typename TYPE> class Matrix<TYPE, 0, 0>: public MatrixBase<TYPE> {
|
|||||||
|
|
||||||
Matrix(size_t rows, size_t columns):
|
Matrix(size_t rows, size_t columns):
|
||||||
Parent(rows, columns) {
|
Parent(rows, columns) {
|
||||||
|
assert(rows>0);
|
||||||
|
assert(columns>0);
|
||||||
Parent::_c = new TYPE[rows*columns];
|
Parent::_c = new TYPE[rows*columns];
|
||||||
memset(Parent::_c, 0, Parent::MEM_SIZE);
|
memset(Parent::_c, 0, Parent::MEM_SIZE);
|
||||||
}
|
}
|
||||||
@@ -347,14 +391,6 @@ template<typename TYPE> class Matrix<TYPE, 0, 0>: public MatrixBase<TYPE> {
|
|||||||
return Parent::operator=(o);
|
return Parent::operator=(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
Matrix t() const {
|
|
||||||
Matrix res(Parent::COLUMNS, Parent::ROWS);
|
|
||||||
for (size_t row(0); row<Parent::ROWS; ++row)
|
|
||||||
for (size_t column(0); column<Parent::COLUMNS; ++column)
|
|
||||||
res(column, row) = this->at(row, column);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
Matrix operator-() const {
|
Matrix operator-() const {
|
||||||
Matrix res(Parent::COLUMNS, Parent::ROWS);
|
Matrix res(Parent::COLUMNS, Parent::ROWS);
|
||||||
for (TYPE *to((TYPE*)(res._c)+Parent::SIZE); to>(TYPE*)(Parent::_c); --to)
|
for (TYPE *to((TYPE*)(res._c)+Parent::SIZE); to>(TYPE*)(Parent::_c); --to)
|
||||||
@@ -374,16 +410,36 @@ template<typename TYPE> class Matrix<TYPE, 0, 0>: public MatrixBase<TYPE> {
|
|||||||
|
|
||||||
///}
|
///}
|
||||||
|
|
||||||
|
///@name special operations
|
||||||
|
///{
|
||||||
|
|
||||||
|
Matrix t() const {
|
||||||
|
Matrix res(this->COLUMNS, this->ROWS);
|
||||||
|
for (size_t row(0); row<this->ROWS; ++row)
|
||||||
|
for (size_t column(0); column<this->COLUMNS; ++column)
|
||||||
|
res(column, row) = this->at(row, column);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
Matrix i() const {
|
||||||
|
Matrix res(this->ROWS, this->COLUMNS);
|
||||||
|
for (size_t row(0); row<this->ROWS&&row<this->COLUMNS; ++row)
|
||||||
|
res(row, row) = 1;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
///}
|
||||||
|
|
||||||
//................................................................methods
|
//................................................................methods
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual void assert_check(const Matrix& o) const {
|
virtual void assert_check(const Matrix& o) const {
|
||||||
assert(o.ROWS==Parent::ROWS);
|
assert(o.ROWS==this->ROWS);
|
||||||
assert(o.COLUMNS==Parent::COLUMNS);
|
assert(o.COLUMNS==this->COLUMNS);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool check(const Matrix& o) const {
|
virtual bool check(const Matrix& o) const {
|
||||||
return o.ROWS==Parent::ROWS && o.COLUMNS==Parent::COLUMNS;
|
return o.ROWS==this->ROWS && o.COLUMNS==this->COLUMNS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void copy_args(TYPE*) {}
|
void copy_args(TYPE*) {}
|
||||||
|
116
test/basic.cxx
116
test/basic.cxx
@@ -169,6 +169,53 @@ class TemplateMatrixTest: public CppUnit::TestFixture {
|
|||||||
3, 6);
|
3, 6);
|
||||||
CPPUNIT_ASSERT_EQUAL(res, m.t());
|
CPPUNIT_ASSERT_EQUAL(res, m.t());
|
||||||
}
|
}
|
||||||
|
template<typename T>
|
||||||
|
void gauss() {
|
||||||
|
Matrix<T,3,3> m(2, -2, 4,
|
||||||
|
-2, 1, -6,
|
||||||
|
1, 0, -2);
|
||||||
|
const Matrix<T,3,3> res(1, -1, 2,
|
||||||
|
0, -1, -2,
|
||||||
|
0, 0, -6);
|
||||||
|
T lambda(m.gauss());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(res, m);
|
||||||
|
CPPUNIT_ASSERT_EQUAL((T)2, lambda);
|
||||||
|
}
|
||||||
|
template<typename T>
|
||||||
|
void det() {
|
||||||
|
Matrix<T,3,3> m(2, -2, 4,
|
||||||
|
-2, 1, -6,
|
||||||
|
1, 0, -2);
|
||||||
|
CPPUNIT_ASSERT_EQUAL((T)12, m.det());
|
||||||
|
}
|
||||||
|
template<typename T>
|
||||||
|
void i() {
|
||||||
|
const Matrix<T,3,3> m1(1, 0, 0,
|
||||||
|
0, 1, 0,
|
||||||
|
0, 0, 1);
|
||||||
|
const Matrix<T,3,2> m2(1, 0,
|
||||||
|
0, 1,
|
||||||
|
0, 0);
|
||||||
|
const Matrix<T,2,3> m3(1, 0, 0,
|
||||||
|
0, 1, 0);
|
||||||
|
CPPUNIT_ASSERT_EQUAL(m1, m1.i());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(m2, m2.i());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(m3, m3.i());
|
||||||
|
}
|
||||||
|
template<typename T>
|
||||||
|
void inv() {
|
||||||
|
Matrix<T,3,3> m(2, -1, 0,
|
||||||
|
1, 2, -2,
|
||||||
|
0, -1, 1);
|
||||||
|
const Matrix<T,3,3> res(0.5, 0, 0,
|
||||||
|
-0.2, 0.4, 0,
|
||||||
|
-1, 2, 5);
|
||||||
|
// const Matrix<T,3,3> res(0, 1, 2,
|
||||||
|
// -1, 2, 4,
|
||||||
|
// -1, 2, 5);
|
||||||
|
m.inv();
|
||||||
|
CPPUNIT_ASSERT_EQUAL(res, m);
|
||||||
|
}
|
||||||
CPPUNIT_TEST_SUITE(TemplateMatrixTest);
|
CPPUNIT_TEST_SUITE(TemplateMatrixTest);
|
||||||
CPPUNIT_TEST(initFromArray1<int>);
|
CPPUNIT_TEST(initFromArray1<int>);
|
||||||
CPPUNIT_TEST(initFromArray1<long>);
|
CPPUNIT_TEST(initFromArray1<long>);
|
||||||
@@ -236,6 +283,22 @@ class TemplateMatrixTest: public CppUnit::TestFixture {
|
|||||||
CPPUNIT_TEST(transpose<unsigned long>);
|
CPPUNIT_TEST(transpose<unsigned long>);
|
||||||
CPPUNIT_TEST(transpose<float>);
|
CPPUNIT_TEST(transpose<float>);
|
||||||
CPPUNIT_TEST(transpose<double>);
|
CPPUNIT_TEST(transpose<double>);
|
||||||
|
CPPUNIT_TEST(gauss<int>);
|
||||||
|
CPPUNIT_TEST(gauss<long>);
|
||||||
|
CPPUNIT_TEST(gauss<float>);
|
||||||
|
CPPUNIT_TEST(gauss<double>);
|
||||||
|
CPPUNIT_TEST(det<int>);
|
||||||
|
CPPUNIT_TEST(det<long>);
|
||||||
|
CPPUNIT_TEST(det<float>);
|
||||||
|
CPPUNIT_TEST(det<double>);
|
||||||
|
CPPUNIT_TEST(i<int>);
|
||||||
|
CPPUNIT_TEST(i<long>);
|
||||||
|
CPPUNIT_TEST(i<unsigned>);
|
||||||
|
CPPUNIT_TEST(i<unsigned long>);
|
||||||
|
CPPUNIT_TEST(i<float>);
|
||||||
|
CPPUNIT_TEST(i<double>);
|
||||||
|
CPPUNIT_TEST(inv<float>);
|
||||||
|
CPPUNIT_TEST(inv<double>);
|
||||||
CPPUNIT_TEST_SUITE_END();
|
CPPUNIT_TEST_SUITE_END();
|
||||||
};
|
};
|
||||||
CPPUNIT_TEST_SUITE_REGISTRATION(TemplateMatrixTest);
|
CPPUNIT_TEST_SUITE_REGISTRATION(TemplateMatrixTest);
|
||||||
@@ -400,6 +463,45 @@ class VariableMatrixTest: public CppUnit::TestFixture {
|
|||||||
3, 6);
|
3, 6);
|
||||||
CPPUNIT_ASSERT_EQUAL(res, m.t());
|
CPPUNIT_ASSERT_EQUAL(res, m.t());
|
||||||
}
|
}
|
||||||
|
template<typename T>
|
||||||
|
void gauss() {
|
||||||
|
Matrix<T> m(3, 3,
|
||||||
|
2, -2, 4,
|
||||||
|
-2, 1, -6,
|
||||||
|
1, 0, -2);
|
||||||
|
const Matrix<T> res(3,3,
|
||||||
|
1, -1, 2,
|
||||||
|
0, -1, -2,
|
||||||
|
0, 0, -6);
|
||||||
|
T lambda(m.gauss());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(res, m);
|
||||||
|
CPPUNIT_ASSERT_EQUAL((T)2, lambda);
|
||||||
|
}
|
||||||
|
template<typename T>
|
||||||
|
void det() {
|
||||||
|
Matrix<T> m(3, 3,
|
||||||
|
2, -2, 4,
|
||||||
|
-2, 1, -6,
|
||||||
|
1, 0, -2);
|
||||||
|
CPPUNIT_ASSERT_EQUAL((T)12, m.det());
|
||||||
|
}
|
||||||
|
template<typename T>
|
||||||
|
void i() {
|
||||||
|
const Matrix<T> m1(3, 3,
|
||||||
|
1, 0, 0,
|
||||||
|
0, 1, 0,
|
||||||
|
0, 0, 1);
|
||||||
|
const Matrix<T> m2(3, 2,
|
||||||
|
1, 0,
|
||||||
|
0, 1,
|
||||||
|
0, 0);
|
||||||
|
const Matrix<T> m3(2, 3,
|
||||||
|
1, 0, 0,
|
||||||
|
0, 1, 0);
|
||||||
|
CPPUNIT_ASSERT_EQUAL(m1, m1.i());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(m2, m2.i());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(m3, m3.i());
|
||||||
|
}
|
||||||
CPPUNIT_TEST_SUITE(VariableMatrixTest);
|
CPPUNIT_TEST_SUITE(VariableMatrixTest);
|
||||||
CPPUNIT_TEST(initFromArray1<int>);
|
CPPUNIT_TEST(initFromArray1<int>);
|
||||||
CPPUNIT_TEST(initFromArray1<long>);
|
CPPUNIT_TEST(initFromArray1<long>);
|
||||||
@@ -467,6 +569,20 @@ class VariableMatrixTest: public CppUnit::TestFixture {
|
|||||||
CPPUNIT_TEST(transpose<unsigned long>);
|
CPPUNIT_TEST(transpose<unsigned long>);
|
||||||
CPPUNIT_TEST(transpose<float>);
|
CPPUNIT_TEST(transpose<float>);
|
||||||
CPPUNIT_TEST(transpose<double>);
|
CPPUNIT_TEST(transpose<double>);
|
||||||
|
CPPUNIT_TEST(gauss<int>);
|
||||||
|
CPPUNIT_TEST(gauss<long>);
|
||||||
|
CPPUNIT_TEST(gauss<float>);
|
||||||
|
CPPUNIT_TEST(gauss<double>);
|
||||||
|
CPPUNIT_TEST(det<int>);
|
||||||
|
CPPUNIT_TEST(det<long>);
|
||||||
|
CPPUNIT_TEST(det<float>);
|
||||||
|
CPPUNIT_TEST(det<double>);
|
||||||
|
CPPUNIT_TEST(i<int>);
|
||||||
|
CPPUNIT_TEST(i<long>);
|
||||||
|
CPPUNIT_TEST(i<unsigned>);
|
||||||
|
CPPUNIT_TEST(i<unsigned long>);
|
||||||
|
CPPUNIT_TEST(i<float>);
|
||||||
|
CPPUNIT_TEST(i<double>);
|
||||||
CPPUNIT_TEST_SUITE_END();
|
CPPUNIT_TEST_SUITE_END();
|
||||||
};
|
};
|
||||||
CPPUNIT_TEST_SUITE_REGISTRATION(VariableMatrixTest);
|
CPPUNIT_TEST_SUITE_REGISTRATION(VariableMatrixTest);
|
||||||
|
Reference in New Issue
Block a user