PPL  1.2
Bit_Matrix.cc
Go to the documentation of this file.
1 /* Bit_Matrix class implementation (non-inline functions).
2  Copyright (C) 2001-2010 Roberto Bagnara <bagnara@cs.unipr.it>
3  Copyright (C) 2010-2016 BUGSENG srl (http://bugseng.com)
4 
5 This file is part of the Parma Polyhedra Library (PPL).
6 
7 The PPL is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 The PPL is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software Foundation,
19 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA.
20 
21 For the most up-to-date information see the Parma Polyhedra Library
22 site: http://bugseng.com/products/ppl/ . */
23 
24 #include "ppl-config.h"
25 #include "Bit_Matrix_defs.hh"
26 #include "Dense_Row_defs.hh"
27 #include "globals_defs.hh"
29 #include "C_Integer.hh"
30 #include <iostream>
31 #include <string>
32 
33 namespace PPL = Parma_Polyhedra_Library;
34 
37  rows = y.rows;
38  row_size = y.row_size;
39  PPL_ASSERT(OK());
40  return *this;
41 }
42 
43 void
45  const dimension_type num_elems = rows.size();
46  if (num_elems < 2) {
47  return;
48  }
49  // Build the function objects implementing indirect sort comparison,
50  // indirect unique comparison and indirect swap operation.
51  using namespace Implementation;
52  typedef std::vector<Bit_Row> Cont;
53  typedef Indirect_Sort_Compare<Cont, Bit_Row_Less_Than> Sort_Compare;
54  typedef Indirect_Unique_Compare<Cont> Unique_Compare;
55  typedef Indirect_Swapper<Cont> Swapper;
56  const dimension_type num_duplicates
57  = indirect_sort_and_unique(num_elems,
58  Sort_Compare(rows),
59  Unique_Compare(rows),
60  Swapper(rows));
61 
62  if (num_duplicates > 0) {
63  typedef Cont::iterator Iter;
64  typedef std::iterator_traits<Iter>::difference_type diff_t;
65  Iter last = rows.end();
66  Iter first = last - static_cast<diff_t>(num_duplicates);
67  rows.erase(first, last);
68  }
69 
70  PPL_ASSERT(OK());
71 }
72 
73 void
75  const dimension_type new_rows_size = rows.size() + 1;
76  if (rows.capacity() < new_rows_size) {
77  // Reallocation will take place.
78  std::vector<Bit_Row> new_rows;
79  new_rows.reserve(compute_capacity(new_rows_size, max_num_rows()));
80  new_rows.insert(new_rows.end(), new_rows_size, Bit_Row());
81  // Put the new row in place.
82  dimension_type i = new_rows_size-1;
83  new_rows[i].m_swap(row);
84  // Steal the old rows.
85  while (i-- > 0) {
86  new_rows[i].m_swap(rows[i]);
87  }
88  // Put the new rows into place.
89  using std::swap;
90  swap(rows, new_rows);
91  }
92  else {
93  // Reallocation will NOT take place: append an empty row
94  // and swap it with the new row.
95  rows.insert(rows.end(), Bit_Row())->m_swap(row);
96  }
97  PPL_ASSERT(OK());
98 }
99 
100 void
102  const Bit_Matrix& x = *this;
103  const dimension_type nrows = num_rows();
104  const dimension_type ncols = num_columns();
105  Bit_Matrix tmp(ncols, nrows);
106  for (dimension_type i = nrows; i-- > 0; ) {
107  for (unsigned long j = x[i].last();
108  j != C_Integer<unsigned long>::max; j = x[i].prev(j)) {
109  tmp[j].set(i);
110  }
111  }
112  m_swap(tmp);
113  PPL_ASSERT(OK());
114 }
115 
116 void
118  const dimension_type y_num_rows = y.num_rows();
119  const dimension_type y_num_columns = y.num_columns();
120  Bit_Matrix tmp(y_num_columns, y_num_rows);
121  for (dimension_type i = y_num_rows; i-- > 0; ) {
122  for (unsigned long j = y[i].last();
123  j != C_Integer<unsigned long>::max; j = y[i].prev(j)) {
124  tmp[j].set(i);
125  }
126  }
127  m_swap(tmp);
128  PPL_ASSERT(OK());
129 }
130 
131 void
133  dimension_type new_n_columns) {
134  PPL_ASSERT(OK());
135  const dimension_type old_num_rows = num_rows();
136  if (new_n_columns < row_size) {
137  const dimension_type num_preserved_rows
138  = std::min(old_num_rows, new_n_rows);
139  Bit_Matrix& x = *this;
140  for (dimension_type i = num_preserved_rows; i-- > 0; ) {
141  x[i].clear_from(new_n_columns);
142  }
143  }
144  row_size = new_n_columns;
145  if (new_n_rows > old_num_rows) {
146  if (rows.capacity() < new_n_rows) {
147  // Reallocation will take place.
148  std::vector<Bit_Row> new_rows;
149  new_rows.reserve(compute_capacity(new_n_rows, max_num_rows()));
150  new_rows.insert(new_rows.end(), new_n_rows, Bit_Row());
151  // Steal the old rows.
152  for (dimension_type i = old_num_rows; i-- > 0; ) {
153  new_rows[i].m_swap(rows[i]);
154  }
155  // Put the new vector into place.
156  using std::swap;
157  swap(rows, new_rows);
158  }
159  else {
160  // Reallocation will NOT take place.
161  rows.insert(rows.end(), new_n_rows - old_num_rows, Bit_Row());
162  }
163  }
164  else if (new_n_rows < old_num_rows) {
165  // Drop some rows.
166  rows.resize(new_n_rows);
167  }
168 
169  PPL_ASSERT(OK());
170 }
171 
172 void
173 PPL::Bit_Matrix::ascii_dump(std::ostream& s) const {
174  const Bit_Matrix& x = *this;
175  const char separator = ' ';
176  s << num_rows() << separator << 'x' << separator
177  << num_columns() << "\n";
178  for (dimension_type i = 0; i < num_rows(); ++i) {
179  for (dimension_type j = 0; j < num_columns(); ++j) {
180  s << x[i][j] << separator;
181  }
182  s << "\n";
183  }
184 }
185 
187 
188 bool
189 PPL::Bit_Matrix::ascii_load(std::istream& s) {
190  Bit_Matrix& x = *this;
191  dimension_type nrows;
192  dimension_type ncols;
193  std::string str;
194  if (!(s >> nrows)) {
195  return false;
196  }
197  if (!(s >> str) || str != "x") {
198  return false;
199  }
200  if (!(s >> ncols)) {
201  return false;
202  }
203  resize(nrows, ncols);
204 
205  for (dimension_type i = 0; i < num_rows(); ++i) {
206  for (dimension_type j = 0; j < num_columns(); ++j) {
207  int bit;
208  if (!(s >> bit)) {
209  return false;
210  }
211  if (bit != 0) {
212  x[i].set(j);
213  }
214  else {
215  x[i].clear(j);
216  }
217  }
218  }
219  // Check invariants.
220  PPL_ASSERT(OK());
221  return true;
222 }
223 
226  memory_size_type n = rows.capacity() * sizeof(Dense_Row);
227  for (dimension_type i = num_rows(); i-- > 0; ) {
228  n += rows[i].external_memory_in_bytes();
229  }
230  return n;
231 }
232 
233 bool
235 #ifndef NDEBUG
236  using std::endl;
237  using std::cerr;
238 #endif
239 
240  const Bit_Matrix& x = *this;
241  for (dimension_type i = num_rows(); i-- > 0; ) {
242  const Bit_Row& row = x[i];
243  if (!row.OK()) {
244  return false;
245  }
246  else if (row.last() != C_Integer<unsigned long>::max
247  && row.last() >= row_size) {
248 #ifndef NDEBUG
249  cerr << "Bit_Matrix[" << i << "] is a row with too many bits!"
250  << endl
251  << "(row_size == " << row_size
252  << ", row.last() == " << row.last() << ")"
253  << endl;
254 #endif
255  return false;
256  }
257  }
258  return true;
259 }
260 
261 #ifndef NDEBUG
262 bool
264  const Bit_Matrix& x = *this;
265  for (dimension_type i = num_rows(); i-- > 1; ) {
266  if (compare(x[i-1], x[i]) > 0) {
267  return false;
268  }
269  }
270  return true;
271 }
272 #endif
273 
275 bool
276 PPL::operator==(const Bit_Matrix& x, const Bit_Matrix& y) {
277  const dimension_type x_num_rows = x.num_rows();
278  if (x_num_rows != y.num_rows()
279  || x.num_columns() != y.num_columns()) {
280  return false;
281  }
282  for (dimension_type i = x_num_rows; i-- > 0; ) {
283  if (x[i] != y[i]) {
284  return false;
285  }
286  }
287  return true;
288 }
bool OK() const
Checks if all the invariants are satisfied.
Definition: Bit_Row.cc:331
void swap(CO_Tree &x, CO_Tree &y)
A finite sequence of coefficients.
size_t dimension_type
An unsigned integral type for representing space dimensions.
void resize(dimension_type new_n_rows, dimension_type new_n_columns)
Resizes the matrix copying the old contents.
Definition: Bit_Matrix.cc:132
dimension_type num_rows() const
Returns the number of rows of *this.
unsigned long last() const
Returns the index of the last set bit or ULONG_MAX if no bit is set.
Definition: Bit_Row.cc:92
The standard C++ namespace.
void add_recycled_row(Bit_Row &row)
Adds row to *this.
Definition: Bit_Matrix.cc:74
A row in a matrix of bits.
void transpose()
Transposes the matrix.
Definition: Bit_Matrix.cc:101
dimension_type compute_capacity(dimension_type requested_size, dimension_type maximum_size)
Speculative allocation function.
void clear()
Clears the matrix deallocating all its rows.
#define PPL_OUTPUT_DEFINITIONS_ASCII_ONLY(class_name)
Enable_If< Is_Native_Or_Checked< T >::value, bool >::type ascii_load(std::istream &s, T &t)
int compare(const Linear_Expression &x, const Linear_Expression &y)
memory_size_type external_memory_in_bytes() const
Returns the size in bytes of the memory managed by *this.
Definition: Bit_Matrix.cc:225
Bit_Matrix & operator=(const Bit_Matrix &y)
Assignment operator.
Definition: Bit_Matrix.cc:36
void m_swap(Bit_Matrix &y)
Swaps *this with y.
bool check_sorted() const
Checks whether *this is sorted. It does NOT check for duplicates.
Definition: Bit_Matrix.cc:263
bool OK() const
Checks if all the invariants are satisfied.
Definition: Bit_Matrix.cc:234
dimension_type num_columns() const
Returns the number of columns of *this.
The entire library is confined to this namespace.
Definition: version.hh:61
dimension_type row_size
Size of the initialized part of each row.
void sort_rows()
Sorts the rows and removes duplicates.
Definition: Bit_Matrix.cc:44
std::vector< Bit_Row > rows
Contains the rows of the matrix.
bool operator==(const Box< ITV > &x, const Box< ITV > &y)
Sort_Comparer::size_type indirect_sort_and_unique(typename Sort_Comparer::size_type num_elems, Sort_Comparer sort_cmp, Unique_Comparer unique_cmp, Swapper indirect_swap)
size_t memory_size_type
An unsigned integral type for representing memory size in bytes.
void transpose_assign(const Bit_Matrix &y)
Makes *this a transposed copy of y.
Definition: Bit_Matrix.cc:117
void ascii_dump() const
Writes to std::cerr an ASCII representation of *this.