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() {
 | 
			
		||||
      // rule of sarrus
 | 
			
		||||
      TYPE res(0);
 | 
			
		||||
      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;
 | 
			
		||||
      }
 | 
			
		||||
      TYPE res(gauss());
 | 
			
		||||
      for (TYPE *p((TYPE*)(_c)+SIZE); --p>=(TYPE*)(_c); p-=COLUMNS) res *= *p;
 | 
			
		||||
      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
 | 
			
		||||
@@ -284,6 +290,42 @@ template<typename TYPE, size_t TROWS=0, size_t TCOLUMNS=0> class Matrix:
 | 
			
		||||
      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):
 | 
			
		||||
        Parent(rows, columns) {
 | 
			
		||||
      assert(rows>0);
 | 
			
		||||
      assert(columns>0);
 | 
			
		||||
      Parent::_c = new TYPE[rows*columns];
 | 
			
		||||
      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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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 res(Parent::COLUMNS, Parent::ROWS);
 | 
			
		||||
      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
 | 
			
		||||
  protected:
 | 
			
		||||
 | 
			
		||||
    virtual void assert_check(const Matrix& o) const {
 | 
			
		||||
      assert(o.ROWS==Parent::ROWS);
 | 
			
		||||
      assert(o.COLUMNS==Parent::COLUMNS);
 | 
			
		||||
      assert(o.ROWS==this->ROWS);
 | 
			
		||||
      assert(o.COLUMNS==this->COLUMNS);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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*) {}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										116
									
								
								test/basic.cxx
									
									
									
									
									
								
							
							
						
						
									
										116
									
								
								test/basic.cxx
									
									
									
									
									
								
							@@ -169,6 +169,53 @@ class TemplateMatrixTest: public CppUnit::TestFixture {
 | 
			
		||||
                              3, 6);
 | 
			
		||||
      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(initFromArray1<int>);
 | 
			
		||||
    CPPUNIT_TEST(initFromArray1<long>);
 | 
			
		||||
@@ -236,6 +283,22 @@ class TemplateMatrixTest: public CppUnit::TestFixture {
 | 
			
		||||
    CPPUNIT_TEST(transpose<unsigned long>);
 | 
			
		||||
    CPPUNIT_TEST(transpose<float>);
 | 
			
		||||
    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_REGISTRATION(TemplateMatrixTest);
 | 
			
		||||
@@ -400,6 +463,45 @@ class VariableMatrixTest: public CppUnit::TestFixture {
 | 
			
		||||
                          3, 6);
 | 
			
		||||
      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(initFromArray1<int>);
 | 
			
		||||
    CPPUNIT_TEST(initFromArray1<long>);
 | 
			
		||||
@@ -467,6 +569,20 @@ class VariableMatrixTest: public CppUnit::TestFixture {
 | 
			
		||||
    CPPUNIT_TEST(transpose<unsigned long>);
 | 
			
		||||
    CPPUNIT_TEST(transpose<float>);
 | 
			
		||||
    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_REGISTRATION(VariableMatrixTest);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user