namespace libstick {
+template<class T>
+std::ostream& operator<<(std::ostream &, const std::vector<T> &);
+
+
/** The base class of boolean_colmatrix and boolean_colrowmatrix which implements
* the common logic of both. */
template<class IT, class D>
}
public:
- /** Get height resp. width of the matrix. */
+ /** A casting constructor for any colmatrix with same entries type. */
+ template<class D2>
+ boolean_colmatrix_base(const boolean_colmatrix_base<IT, D2> &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());
return cols[c];
}
+ /** Get all columns */
+ const std::vector<column_type>& 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) {
}
/** Two matrices are equal iff they have the same entries */
- bool operator==(const boolean_colmatrix_base<IT, D> &m) const {
- return cols == m.cols;
+ template<class D2>
+ bool operator==(const boolean_colmatrix_base<IT, D2> &m) const {
+ return cols == m.get_columns();
}
/** Two matrices are equal iff they have the same entries */
- bool operator!=(const boolean_colmatrix_base<IT, D> &m) const {
+ template<class D2>
+ bool operator!=(const boolean_colmatrix_base<IT, D2> &m) const {
return !(*this == m);
}
#endif
}
- private:
+ protected:
/** The matrix is the set of columns. */
std::vector<column_type> cols;
public:
typedef IT index_type;
typedef boolean_colmatrix_base<IT, boolean_colmatrix<IT> > base;
+ typedef typename base::column_type column_type;
/** Create a matrix with 'width' columns, initalized with zero entries. */
boolean_colmatrix(size_t columns) :
void _set(index_type r, index_type c, bool value) {
base::_set(r, c, value);
}
+
+ /** A faster implementation of boolean_colmatrix_base::add_column().
+ * Assumes that 'col' is sorted. */
+ void add_column(index_type c, const column_type &col) {
+ assert(c < base::width());
+
+#ifndef NDEBUG
+ for (unsigned i=1; i < col.size(); ++i)
+ assert(col[i-1] < col[i]);
+#endif
+
+ // The original column
+ column_type &orig_col = base::cols[c];
+
+ // Make target column large enough
+ const size_t maxsize = orig_col.size() + col.size();
+ if (tcol.size() < maxsize)
+ tcol.resize(maxsize);
+
+ // Compute symmetric difference
+ typename column_type::iterator it = std::set_symmetric_difference(
+ orig_col.begin(), orig_col.end(), col.begin(), col.end(), tcol.begin());
+
+ // Copy back to the original column
+ orig_col.resize(it - tcol.begin());
+ std::copy(tcol.begin(), it, orig_col.begin());
+ }
+
+ private:
+ /** A temporary container to speed up add_column() */
+ column_type tcol;
};
}
public:
- /** Get height resp. width of the matrix. */
+ /** Get height of the matrix. */
size_t height() const {
return rows.size();
}
#endif
}
- private:
+ protected:
derived* get_derived() {
return static_cast<derived*>(this);
}
rowbase(size) {
}
+ /** Casting a colmatrix into a colrow matrix */
+ template<class D>
+ boolean_colrowmatrix(const boolean_colmatrix_base<IT, D>& 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);
return colbase::operator==(m);
}
+ /** Two matrices are equal iff they have the same entries */
+ template<class D>
+ bool operator==(const boolean_colmatrix_base<IT, D> &m) const {
+ return colbase::operator==(m);
+ }
+
/** Two matrices are equal iff they have the same entries */
bool operator!=(const boolean_colrowmatrix<IT> &m) const {
return !(*this == m);
return os << m;
}
+template<class T>
+std::ostream& operator<<(std::ostream& os, const std::vector<T> &vec) {
+ os << "[";
+
+ typename std::vector<T>::const_iterator it = vec.begin();
+ while ( it != vec.end()) {
+ os << *it;
+ if (++it != vec.end())
+ os << " ";
+ }
+
+ os << "]";
+ return os;
+}
+
}
#endif