Add tests for matrix reduction of complex examples
[libstick.git] / include / libstick-0.1 / booleanmatrix.h
index 774aeb73095c6abb2738d49d9f6d8ad63f88ddbc..1fb4dd28f6d98e02d70cabb6372e62ddf6d9180a 100644 (file)
@@ -25,11 +25,13 @@ class boolean_colmatrix_base {
         typedef std::vector<index_type> column_type;
         typedef D derived;
 
+    protected:
         /** Create a matrix with 'width' columns, initalized with zero entries. */
         boolean_colmatrix_base(size_t width) :
             cols(width) {
         }
 
+    public:
         /** Get height resp. width of the matrix. */
         size_t width() const {
             return cols.size();
@@ -47,6 +49,12 @@ class boolean_colmatrix_base {
             get_derived()->_set(r, c, value);
         }
 
+        /** For each of the 'count'-many (row-index, column-pair) pair in 'indices', set the specific value. */
+        void set_all(index_type indices[][2], size_t count, bool value) {
+            for (unsigned i=0; i < count; ++i)
+                set(indices[i][0], indices[i][1], value);
+        }
+
         /** Get the c-th column. */
         const column_type& get_column(index_type c) const {
             assert(c < width());
@@ -73,6 +81,24 @@ class boolean_colmatrix_base {
             return !(*this == m);
         }
 
+        /** Print index pairs of the 1s as { {r, c}, {r, c}, {r, c} } */
+        void print_indexpairs(std::ostream &os) const {
+            bool first=true;
+
+            os << "{";
+            for (unsigned c=0; c < width(); ++c) {
+                const column_type &col = get_column(c);
+                for (typename column_type::const_iterator it = col.begin(); it != col.end(); ++it) {
+                    if (first)
+                        first = false;
+                    else
+                        os << ",";
+                    os << " {" << *it << ", " << c << "}";
+                }
+            }
+            os << " }";
+        }
+
     protected:
         /** Set the matrix entry at row 'r' and column 'c'. */
         void _set(index_type r, index_type c, bool value) {
@@ -148,12 +174,14 @@ class boolean_rowmatrix_base {
         typedef std::vector<index_type> row_type;
         typedef D derived;
 
+    protected:
         /** Create a matrix with 'height' rows, initalized with zero entries.
          * */
         boolean_rowmatrix_base(size_t height) :
             rows(height) {
         }
 
+    public:
         /** Get height resp. width of the matrix. */
         size_t height() const {
             return rows.size();
@@ -171,6 +199,12 @@ class boolean_rowmatrix_base {
             get_derived()->_set(r, c, value);
         }
 
+        /** For each of the 'count'-many (row-index, column-pair) pair in 'indices', set the specific value. */
+        void set_all(index_type indices[][2], size_t count, bool value) {
+            for (unsigned i=0; i < count; ++i)
+                set(indices[i][0], indices[i][1], value);
+        }
+
         /** Get the r-th row. */
         const row_type& get_row(index_type r) const {
             assert(r < height());
@@ -301,6 +335,11 @@ class boolean_colrowmatrix : public boolean_colmatrix_base<IT, boolean_colrowmat
             colbase::set(r, c, value);
         }
 
+        /** For each of the 'count'-many (row-index, column-pair) pair in 'indices', set the specific value. */
+        void set_all(index_type indices[][2], size_t count, bool value) {
+            colbase::set_all(indices, count, value);
+        }
+
         /** Get the matrix entry at row 'r' and column 'c'. */
         bool get(index_type r, index_type c) const {
             assert(colbase::get(r, c) == rowbase::get(r, c));
@@ -320,7 +359,7 @@ class boolean_colrowmatrix : public boolean_colmatrix_base<IT, boolean_colrowmat
 
         /** Multiply with matrix b from the right */
         template<class D>
-        boolean_colrowmatrix<IT> operator*(const boolean_colmatrix_base<IT, D> &b) {
+        boolean_colrowmatrix<IT> operator*(const boolean_colmatrix_base<IT, D> &b) const {
             boolean_colrowmatrix<IT> c(size());
             multiply_matrix(c, *this, b);
             return c;
@@ -353,14 +392,14 @@ size_t count_set_intersection (InputIterator1 first1, InputIterator1 last1, Inpu
 }
 
 /** Multiply a*b and save the product in 'result'. It is assumed that 'result' is intially empty and has appropriate size. */
-template<class IT, class D, class RT>
-void multiply_matrix(RT &result, const boolean_rowmatrix_base<IT, D> &a, const boolean_colmatrix_base<IT, D> &b) {
+template<class IT, class D1, class D2, class RT>
+void multiply_matrix(RT &result, const boolean_rowmatrix_base<IT, D1> &a, const boolean_colmatrix_base<IT, D2> &b) {
     assert(a.height() == b.width());
 
     for (unsigned r=0; r < a.height(); ++r) {
-        const typename boolean_rowmatrix_base<IT, D>::row_type &row = a.get_row(r);
+        const typename boolean_rowmatrix_base<IT, D1>::row_type &row = a.get_row(r);
         for (unsigned c=0; c < b.width(); ++c) {
-            const typename boolean_colmatrix_base<IT, D>::column_type &col = b.get_column(c);
+            const typename boolean_colmatrix_base<IT, D2>::column_type &col = b.get_column(c);
             if (count_set_intersection(row.begin(), row.end(), col.begin(), col.end()) % 2 == 1)
                 result.set(r, c, true);
         }
@@ -377,7 +416,24 @@ MT create_unit_matrix(size_t size) {
 
 template<class IT>
 std::ostream& operator<<(std::ostream &os, const boolean_colrowmatrix<IT> &mat) {
+
+    os << " ";
+    for (unsigned c=0; c < mat.size(); ++c) {
+        const unsigned d = (c % 10);
+        if (d > 0)
+            os << d;
+        else
+            os << " ";
+    }
+    os << std::endl;
+
     for (unsigned r=0; r < mat.size(); ++r) {
+        const unsigned d = (r % 10);
+        if (d > 0)
+            os << d;
+        else
+            os << " ";
+
         for (unsigned c=0; c < mat.size(); ++c)
             os << (mat.get(r,c) ? "X" : ".");