00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <ppl-config.h>
00025
00026 #include "Bit_Matrix.defs.hh"
00027 #include "globals.defs.hh"
00028 #include <iostream>
00029 #include <string>
00030 #include <climits>
00031
00032 #include "swapping_sort.icc"
00033
00034 namespace PPL = Parma_Polyhedra_Library;
00035
00036 PPL::Bit_Matrix&
00037 PPL::Bit_Matrix::operator=(const Bit_Matrix& y){
00038 rows = y.rows;
00039 row_size = y.row_size;
00040 PPL_ASSERT(OK());
00041 return *this;
00042 }
00043
00044 void
00045 PPL::Bit_Matrix::sort_rows() {
00046 const dimension_type num_elems = rows.size();
00047 if (num_elems < 2)
00048 return;
00049
00050
00051
00052 typedef std::vector<Bit_Row> Cont;
00053 Indirect_Sort_Compare<Cont, Bit_Row_Less_Than> sort_cmp(rows);
00054 Indirect_Unique_Compare<Cont> unique_cmp(rows);
00055 Indirect_Swapper<Cont> swapper(rows);
00056
00057 const dimension_type num_duplicates
00058 = indirect_sort_and_unique(num_elems, sort_cmp, unique_cmp, swapper);
00059
00060 if (num_duplicates > 0)
00061 rows.erase(rows.end() - num_duplicates, rows.end());
00062
00063 PPL_ASSERT(OK());
00064 }
00065
00066 void
00067 PPL::Bit_Matrix::add_recycled_row(Bit_Row& row) {
00068 const dimension_type new_rows_size = rows.size() + 1;
00069 if (rows.capacity() < new_rows_size) {
00070
00071 std::vector<Bit_Row> new_rows;
00072 new_rows.reserve(compute_capacity(new_rows_size, max_num_rows()));
00073 new_rows.insert(new_rows.end(), new_rows_size, Bit_Row());
00074
00075 dimension_type i = new_rows_size-1;
00076 new_rows[i].swap(row);
00077
00078 while (i-- > 0)
00079 new_rows[i].swap(rows[i]);
00080
00081 std::swap(rows, new_rows);
00082 }
00083 else
00084
00085
00086 rows.insert(rows.end(), Bit_Row())->swap(row);
00087 PPL_ASSERT(OK());
00088 }
00089
00090 void
00091 PPL::Bit_Matrix::transpose() {
00092 const Bit_Matrix& x = *this;
00093 const dimension_type nrows = num_rows();
00094 const dimension_type ncols = num_columns();
00095 Bit_Matrix tmp(ncols, nrows);
00096 for (dimension_type i = nrows; i-- > 0; )
00097 for (unsigned long j = x[i].last(); j != ULONG_MAX; j = x[i].prev(j))
00098 tmp[j].set(i);
00099 swap(tmp);
00100 PPL_ASSERT(OK());
00101 }
00102
00103 void
00104 PPL::Bit_Matrix::transpose_assign(const Bit_Matrix& y) {
00105 const dimension_type y_nrows = y.num_rows();
00106 const dimension_type y_ncols = y.num_columns();
00107 Bit_Matrix tmp(y_ncols, y_nrows);
00108 for (dimension_type i = y_nrows; i-- > 0; )
00109 for (unsigned long j = y[i].last(); j != ULONG_MAX; j = y[i].prev(j))
00110 tmp[j].set(i);
00111 swap(tmp);
00112 PPL_ASSERT(OK());
00113 }
00114
00115 void
00116 PPL::Bit_Matrix::resize(dimension_type new_n_rows,
00117 dimension_type new_n_columns) {
00118 PPL_ASSERT(OK());
00119 const dimension_type old_num_rows = num_rows();
00120 if (new_n_columns < row_size) {
00121 const dimension_type num_preserved_rows
00122 = std::min(old_num_rows, new_n_rows);
00123 Bit_Matrix& x = *this;
00124 for (dimension_type i = num_preserved_rows; i-- > 0; )
00125 x[i].clear_from(new_n_columns);
00126 }
00127 row_size = new_n_columns;
00128 if (new_n_rows > old_num_rows) {
00129 if (rows.capacity() < new_n_rows) {
00130
00131 std::vector<Bit_Row> new_rows;
00132 new_rows.reserve(compute_capacity(new_n_rows, max_num_rows()));
00133 new_rows.insert(new_rows.end(), new_n_rows, Bit_Row());
00134
00135 for (dimension_type i = old_num_rows; i-- > 0; )
00136 new_rows[i].swap(rows[i]);
00137
00138 std::swap(rows, new_rows);
00139 }
00140 else
00141
00142 rows.insert(rows.end(), new_n_rows - old_num_rows, Bit_Row());
00143 }
00144 else if (new_n_rows < old_num_rows)
00145
00146 rows.erase(rows.begin() + new_n_rows, rows.end());
00147
00148 PPL_ASSERT(OK());
00149 }
00150
00151 void
00152 PPL::Bit_Matrix::ascii_dump(std::ostream& s) const {
00153 const Bit_Matrix& x = *this;
00154 const char separator = ' ';
00155 s << num_rows() << separator << 'x' << separator
00156 << num_columns() << "\n";
00157 for (dimension_type i = 0; i < num_rows(); ++i) {
00158 for (dimension_type j = 0; j < num_columns(); ++j)
00159 s << x[i][j] << separator;
00160 s << "\n";
00161 }
00162 }
00163
00164 PPL_OUTPUT_DEFINITIONS_ASCII_ONLY(Bit_Matrix)
00165
00166 bool
00167 PPL::Bit_Matrix::ascii_load(std::istream& s) {
00168 Bit_Matrix& x = *this;
00169 dimension_type nrows;
00170 dimension_type ncols;
00171 std::string str;
00172 if (!(s >> nrows))
00173 return false;
00174 if (!(s >> str) || str != "x")
00175 return false;
00176 if (!(s >> ncols))
00177 return false;
00178 resize(nrows, ncols);
00179
00180 for (dimension_type i = 0; i < num_rows(); ++i)
00181 for (dimension_type j = 0; j < num_columns(); ++j) {
00182 int bit;
00183 if (!(s >> bit))
00184 return false;
00185 if (bit)
00186 x[i].set(j);
00187 else
00188 x[i].clear(j);
00189 }
00190
00191
00192 PPL_ASSERT(OK());
00193 return true;
00194 }
00195
00196 PPL::memory_size_type
00197 PPL::Bit_Matrix::external_memory_in_bytes() const {
00198 memory_size_type n = rows.capacity() * sizeof(Row);
00199 for (dimension_type i = num_rows(); i-- > 0; )
00200 n += rows[i].external_memory_in_bytes();
00201 return n;
00202 }
00203
00204 bool
00205 PPL::Bit_Matrix::OK() const {
00206 #ifndef NDEBUG
00207 using std::endl;
00208 using std::cerr;
00209 #endif
00210
00211 const Bit_Matrix& x = *this;
00212 for (dimension_type i = num_rows(); i-- > 1; ) {
00213 const Bit_Row& row = x[i];
00214 if (!row.OK())
00215 return false;
00216 else if (row.last() != ULONG_MAX && row.last() >= row_size) {
00217 #ifndef NDEBUG
00218 cerr << "Bit_Matrix[" << i << "] is a row with too many bits!"
00219 << endl
00220 << "(row_size == " << row_size
00221 << ", row.last() == " << row.last() << ")"
00222 << endl;
00223 #endif
00224 return false;
00225 }
00226 }
00227 return true;
00228 }
00229
00230 #ifndef NDEBUG
00231 bool
00232 PPL::Bit_Matrix::check_sorted() const {
00233 const Bit_Matrix& x = *this;
00234 for (dimension_type i = num_rows(); i-- > 1; )
00235 if (compare(x[i-1], x[i]) > 0)
00236 return false;
00237 return true;
00238 }
00239 #endif
00240
00242 bool
00243 PPL::operator==(const Bit_Matrix& x, const Bit_Matrix& y) {
00244 const dimension_type x_num_rows = x.num_rows();
00245 if (x_num_rows != y.num_rows()
00246 || x.num_columns() != y.num_columns())
00247 return false;
00248 for (dimension_type i = x_num_rows; i-- > 0; )
00249 if (x[i] != y[i])
00250 return false;
00251 return true;
00252 }
00253