X-Git-Url: https://git.sthu.org/?p=libstick.git;a=blobdiff_plain;f=include%2Flibstick-0.1%2Fbooleanmatrix.h;h=2b64a4ecb79bcd4200e3e26ab3c16bfa2fd10025;hp=8626f53d58eca6c755737b29f16e37bebd316399;hb=799cd8e53b06b4f9ec7d4dde13ab600717982099;hpb=b3a9951228b854b44c507b32a61e9d36e74709d9 diff --git a/include/libstick-0.1/booleanmatrix.h b/include/libstick-0.1/booleanmatrix.h index 8626f53..2b64a4e 100644 --- a/include/libstick-0.1/booleanmatrix.h +++ b/include/libstick-0.1/booleanmatrix.h @@ -15,6 +15,10 @@ namespace libstick { +template +std::ostream& operator<<(std::ostream &, const std::vector &); + + /** The base class of boolean_colmatrix and boolean_colrowmatrix which implements * the common logic of both. */ template @@ -32,11 +36,26 @@ class boolean_colmatrix_base { } public: - /** Get height resp. width of the matrix. */ + /** A casting constructor for any colmatrix with same entries type. */ + template + boolean_colmatrix_base(const boolean_colmatrix_base &mat) : + cols(mat.get_columns()) { + } + + /** Get width of the matrix. */ size_t width() const { return cols.size(); } + /** Get height of the matrix, i.e. maximum row-index + 1 among all columns. */ + size_t height() const { + IT h = 0; + for (unsigned c=0; c < width(); ++c) + if (cols[c].size() > 0) + h = std::max(h, cols[c].back()); + return h+1; + } + /** Get the matrix entry at row 'r' and column 'c'. */ bool get(index_type r, index_type c) const { assert(c < width()); @@ -61,6 +80,11 @@ class boolean_colmatrix_base { return cols[c]; } + /** Get all columns */ + const std::vector& get_columns() const { + return cols; + } + /** Add the column-vector 'col' to the c-th column. Note that 'col' * actually contains the list of row-indices that are 1. */ void add_column(index_type c, const column_type &col) { @@ -72,12 +96,14 @@ class boolean_colmatrix_base { } /** Two matrices are equal iff they have the same entries */ - bool operator==(const boolean_colmatrix_base &m) const { - return cols == m.cols; + template + bool operator==(const boolean_colmatrix_base &m) const { + return cols == m.get_columns(); } /** Two matrices are equal iff they have the same entries */ - bool operator!=(const boolean_colmatrix_base &m) const { + template + bool operator!=(const boolean_colmatrix_base &m) const { return !(*this == m); } @@ -131,7 +157,7 @@ class boolean_colmatrix_base { #endif } - private: + protected: /** The matrix is the set of columns. */ std::vector cols; @@ -151,6 +177,7 @@ class boolean_colmatrix : public boolean_colmatrix_base > base; + typedef typename base::column_type column_type; /** Create a matrix with 'width' columns, initalized with zero entries. */ boolean_colmatrix(size_t columns) : @@ -161,6 +188,37 @@ class boolean_colmatrix : public boolean_colmatrix_base(this); } @@ -314,6 +372,23 @@ class boolean_colrowmatrix : public boolean_colmatrix_base + boolean_colrowmatrix(const boolean_colmatrix_base& mat) : + colbase(std::max(mat.width(), mat.height())), + rowbase(std::max(mat.width(), mat.height())) { + for (unsigned c=0; c < mat.width(); ++c) { + const typename colbase::column_type &col = mat.get_column(c); + for (unsigned i=0; i < col.size(); ++i) + set(col[i], c, true); + } + for (unsigned r=0; r < size(); ++r) { + const typename rowbase::row_type &row = rowbase::get_row(r); + for (unsigned i=0; i < row.size(); ++i) + assert(get(r, row[i]) == true); + } + } + /** Override implementation. */ void _set(index_type r, index_type c, bool value) { colbase::_set(r, c, value); @@ -352,6 +427,12 @@ class boolean_colrowmatrix : public boolean_colmatrix_base + bool operator==(const boolean_colmatrix_base &m) const { + return colbase::operator==(m); + } + /** Two matrices are equal iff they have the same entries */ bool operator!=(const boolean_colrowmatrix &m) const { return !(*this == m); @@ -524,6 +605,21 @@ std::ostream& operator<<(std::ostream &os, boolean_colmatrix_base &mat) { return os << m; } +template +std::ostream& operator<<(std::ostream& os, const std::vector &vec) { + os << "["; + + typename std::vector::const_iterator it = vec.begin(); + while ( it != vec.end()) { + os << *it; + if (++it != vec.end()) + os << " "; + } + + os << "]"; + return os; +} + } #endif