[eigen] Sparse Module Patch

[ Thread Index | Date Index | More lists.tuxfamily.org/eigen Archives ]


Hi,

I've added a simple test for the Sparse Module. Right now it just initializes 
and accesses a Sparse Matrix, but I found some bugs in 
SparseMatrix::coeff/coeffRef thanks to it.

I attach the diff. Please review it carefully as I'm not an experienced 
programmer. 

Thank you :)

Daniel
Index: test/CMakeLists.txt
===================================================================
--- test/CMakeLists.txt	(revision 850444)
+++ test/CMakeLists.txt	(working copy)
@@ -111,5 +111,6 @@
 EI_ADD_TEST(regression)
 EI_ADD_TEST(svd)
 EI_ADD_TEST(ioformat)
+EI_ADD_TEST(sparse)
 
 ENDIF(BUILD_TESTS)
Index: test/sparse.cpp
===================================================================
--- test/sparse.cpp	(revision 0)
+++ test/sparse.cpp	(revision 0)
@@ -0,0 +1,65 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Daniel Gomez Ferro <dgomezferro@xxxxxxxxx>
+//
+// Eigen is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 3 of the License, or (at your option) any later version.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#include "main.h"
+#include <Eigen/Sparse>
+
+void test_sparse()
+{
+  int rows = 4, cols = 4;
+  SparseMatrix<double> m(rows, cols);
+
+  m.startFill(rows);
+  m.fill(0, 2) = 2;
+  m.fill(1, 2) = 1;
+  m.fill(0, 3) = 5;
+  m.endFill();
+
+  m.coeffRef(0, 2) = 3;
+  VERIFY_RAISES_ASSERT( m.coeffRef(0, 0) = 5 );
+  VERIFY_IS_MUCH_SMALLER_THAN( m.coeff(0, 0), 0.000001 );
+  VERIFY_IS_MUCH_SMALLER_THAN( m.coeff(0, 1), 0.000001 );
+  VERIFY_IS_MUCH_SMALLER_THAN( m.coeff(2, 1), 0.000001 );
+  VERIFY_IS_APPROX( m.coeff(0, 2), 3.0 );
+  VERIFY_IS_APPROX( m.coeff(1, 2), 1.0 );
+  VERIFY_IS_APPROX( m.coeff(0, 3), 5.0 );
+
+  Matrix4d dm;
+  double r;
+  m.startFill(rows*cols);
+  for(int i=0; i<cols; i++) {
+    for(int j=0; j<rows; j++) {
+      r = rand();
+      m.fill(j, i) = r;
+      dm(j, i) = r;
+    }
+  }
+  m.endFill();
+
+  for(int i=0; i<cols; i++) {
+    for(int j=0; j<rows; j++) {
+      VERIFY_IS_APPROX( m.coeff(j, i), dm(j, i) );
+    }
+  }
+}
Index: Eigen/src/Sparse/SparseMatrix.h
===================================================================
--- Eigen/src/Sparse/SparseMatrix.h	(revision 850444)
+++ Eigen/src/Sparse/SparseMatrix.h	(working copy)
@@ -85,11 +85,11 @@
       const int inner = RowMajor ? col : row;
 
       int id = m_outerIndex[outer];
-      int end = m_outerIndex[outer+1]-1;
-      if (m_data.index(end)==inner)
-        return m_data.value(end);
+      int end = m_outerIndex[outer+1];
+      if (id==end)
+        return Scalar(0);
       const int* r = std::lower_bound(&m_data.index(id),&m_data.index(end),inner);
-      return (*r==inner) ? m_data.value(*r) : Scalar(0);
+      return (*r==inner) ? m_data.value(r-&m_data.index(0)) : Scalar(0);
     }
 
     inline Scalar& coeffRef(int row, int col)
@@ -99,9 +99,10 @@
 
       int id = m_outerIndex[outer];
       int end = m_outerIndex[outer+1];
+      ei_assert(end>id);
       int* r = std::lower_bound(&m_data.index(id),&m_data.index(end),inner);
       ei_assert(*r==inner);
-      return m_data.value(*r);
+      return m_data.value(r-&m_data.index(0));
     }
 
   public:


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/