|
PPL
0.12.1
|
00001 /* Bit_Matrix class implementation (non-inline functions). 00002 Copyright (C) 2001-2010 Roberto Bagnara <bagnara@cs.unipr.it> 00003 Copyright (C) 2010-2012 BUGSENG srl (http://bugseng.com) 00004 00005 This file is part of the Parma Polyhedra Library (PPL). 00006 00007 The PPL is free software; you can redistribute it and/or modify it 00008 under the terms of the GNU General Public License as published by the 00009 Free Software Foundation; either version 3 of the License, or (at your 00010 option) any later version. 00011 00012 The PPL is distributed in the hope that it will be useful, but WITHOUT 00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00014 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 00015 for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program; if not, write to the Free Software Foundation, 00019 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA. 00020 00021 For the most up-to-date information see the Parma Polyhedra Library 00022 site: http://bugseng.com/products/ppl/ . */ 00023 00024 #include "ppl-config.h" 00025 #include "Bit_Matrix.defs.hh" 00026 #include "globals.defs.hh" 00027 #include "swapping_sort.templates.hh" 00028 #include "C_Integer.hh" 00029 #include <iostream> 00030 #include <string> 00031 00032 namespace PPL = Parma_Polyhedra_Library; 00033 00034 PPL::Bit_Matrix& 00035 PPL::Bit_Matrix::operator=(const Bit_Matrix& y){ 00036 rows = y.rows; 00037 row_size = y.row_size; 00038 PPL_ASSERT(OK()); 00039 return *this; 00040 } 00041 00042 void 00043 PPL::Bit_Matrix::sort_rows() { 00044 typedef std::vector<Bit_Row>::iterator Iter; 00045 // Sorting without removing duplicates. 00046 Iter first = rows.begin(); 00047 Iter last = rows.end(); 00048 Implementation::swapping_sort(first, last, Bit_Row_Less_Than()); 00049 // Moving all the duplicate elements at the end of the vector. 00050 Iter new_last = Implementation::swapping_unique(first, last); 00051 // Removing duplicates. 00052 rows.erase(new_last, last); 00053 PPL_ASSERT(OK()); 00054 } 00055 00056 void 00057 PPL::Bit_Matrix::add_recycled_row(Bit_Row& row) { 00058 const dimension_type new_rows_size = rows.size() + 1; 00059 if (rows.capacity() < new_rows_size) { 00060 // Reallocation will take place. 00061 std::vector<Bit_Row> new_rows; 00062 new_rows.reserve(compute_capacity(new_rows_size, max_num_rows())); 00063 new_rows.insert(new_rows.end(), new_rows_size, Bit_Row()); 00064 // Put the new row in place. 00065 dimension_type i = new_rows_size-1; 00066 new_rows[i].m_swap(row); 00067 // Steal the old rows. 00068 while (i-- > 0) 00069 new_rows[i].m_swap(rows[i]); 00070 // Put the new rows into place. 00071 using std::swap; 00072 swap(rows, new_rows); 00073 } 00074 else 00075 // Reallocation will NOT take place: append an empty row 00076 // and swap it with the new row. 00077 rows.insert(rows.end(), Bit_Row())->m_swap(row); 00078 PPL_ASSERT(OK()); 00079 } 00080 00081 void 00082 PPL::Bit_Matrix::transpose() { 00083 const Bit_Matrix& x = *this; 00084 const dimension_type nrows = num_rows(); 00085 const dimension_type ncols = num_columns(); 00086 Bit_Matrix tmp(ncols, nrows); 00087 for (dimension_type i = nrows; i-- > 0; ) 00088 for (unsigned long j = x[i].last(); 00089 j != C_Integer<unsigned long>::max; j = x[i].prev(j)) 00090 tmp[j].set(i); 00091 m_swap(tmp); 00092 PPL_ASSERT(OK()); 00093 } 00094 00095 void 00096 PPL::Bit_Matrix::transpose_assign(const Bit_Matrix& y) { 00097 const dimension_type y_num_rows = y.num_rows(); 00098 const dimension_type y_num_columns = y.num_columns(); 00099 Bit_Matrix tmp(y_num_columns, y_num_rows); 00100 for (dimension_type i = y_num_rows; i-- > 0; ) 00101 for (unsigned long j = y[i].last(); 00102 j != C_Integer<unsigned long>::max; j = y[i].prev(j)) 00103 tmp[j].set(i); 00104 m_swap(tmp); 00105 PPL_ASSERT(OK()); 00106 } 00107 00108 void 00109 PPL::Bit_Matrix::resize(dimension_type new_n_rows, 00110 dimension_type new_n_columns) { 00111 PPL_ASSERT(OK()); 00112 const dimension_type old_num_rows = num_rows(); 00113 if (new_n_columns < row_size) { 00114 const dimension_type num_preserved_rows 00115 = std::min(old_num_rows, new_n_rows); 00116 Bit_Matrix& x = *this; 00117 for (dimension_type i = num_preserved_rows; i-- > 0; ) 00118 x[i].clear_from(new_n_columns); 00119 } 00120 row_size = new_n_columns; 00121 if (new_n_rows > old_num_rows) { 00122 if (rows.capacity() < new_n_rows) { 00123 // Reallocation will take place. 00124 std::vector<Bit_Row> new_rows; 00125 new_rows.reserve(compute_capacity(new_n_rows, max_num_rows())); 00126 new_rows.insert(new_rows.end(), new_n_rows, Bit_Row()); 00127 // Steal the old rows. 00128 for (dimension_type i = old_num_rows; i-- > 0; ) 00129 new_rows[i].m_swap(rows[i]); 00130 // Put the new vector into place. 00131 using std::swap; 00132 swap(rows, new_rows); 00133 } 00134 else 00135 // Reallocation will NOT take place. 00136 rows.insert(rows.end(), new_n_rows - old_num_rows, Bit_Row()); 00137 } 00138 else if (new_n_rows < old_num_rows) 00139 // Drop some rows. 00140 rows.resize(new_n_rows); 00141 00142 PPL_ASSERT(OK()); 00143 } 00144 00145 void 00146 PPL::Bit_Matrix::ascii_dump(std::ostream& s) const { 00147 const Bit_Matrix& x = *this; 00148 const char separator = ' '; 00149 s << num_rows() << separator << 'x' << separator 00150 << num_columns() << "\n"; 00151 for (dimension_type i = 0; i < num_rows(); ++i) { 00152 for (dimension_type j = 0; j < num_columns(); ++j) 00153 s << x[i][j] << separator; 00154 s << "\n"; 00155 } 00156 } 00157 00158 PPL_OUTPUT_DEFINITIONS_ASCII_ONLY(Bit_Matrix) 00159 00160 bool 00161 PPL::Bit_Matrix::ascii_load(std::istream& s) { 00162 Bit_Matrix& x = *this; 00163 dimension_type nrows; 00164 dimension_type ncols; 00165 std::string str; 00166 if (!(s >> nrows)) 00167 return false; 00168 if (!(s >> str) || str != "x") 00169 return false; 00170 if (!(s >> ncols)) 00171 return false; 00172 resize(nrows, ncols); 00173 00174 for (dimension_type i = 0; i < num_rows(); ++i) 00175 for (dimension_type j = 0; j < num_columns(); ++j) { 00176 int bit; 00177 if (!(s >> bit)) 00178 return false; 00179 if (bit != 0) 00180 x[i].set(j); 00181 else 00182 x[i].clear(j); 00183 } 00184 00185 // Check invariants. 00186 PPL_ASSERT(OK()); 00187 return true; 00188 } 00189 00190 PPL::memory_size_type 00191 PPL::Bit_Matrix::external_memory_in_bytes() const { 00192 memory_size_type n = rows.capacity() * sizeof(Dense_Row); 00193 for (dimension_type i = num_rows(); i-- > 0; ) 00194 n += rows[i].external_memory_in_bytes(); 00195 return n; 00196 } 00197 00198 bool 00199 PPL::Bit_Matrix::OK() const { 00200 #ifndef NDEBUG 00201 using std::endl; 00202 using std::cerr; 00203 #endif 00204 00205 const Bit_Matrix& x = *this; 00206 for (dimension_type i = num_rows(); i-- > 0; ) { 00207 const Bit_Row& row = x[i]; 00208 if (!row.OK()) 00209 return false; 00210 else if (row.last() != C_Integer<unsigned long>::max 00211 && row.last() >= row_size) { 00212 #ifndef NDEBUG 00213 cerr << "Bit_Matrix[" << i << "] is a row with too many bits!" 00214 << endl 00215 << "(row_size == " << row_size 00216 << ", row.last() == " << row.last() << ")" 00217 << endl; 00218 #endif 00219 return false; 00220 } 00221 } 00222 return true; 00223 } 00224 00225 #ifndef NDEBUG 00226 bool 00227 PPL::Bit_Matrix::check_sorted() const { 00228 const Bit_Matrix& x = *this; 00229 for (dimension_type i = num_rows(); i-- > 1; ) 00230 if (compare(x[i-1], x[i]) > 0) 00231 return false; 00232 return true; 00233 } 00234 #endif 00235 00237 bool 00238 PPL::operator==(const Bit_Matrix& x, const Bit_Matrix& y) { 00239 const dimension_type x_num_rows = x.num_rows(); 00240 if (x_num_rows != y.num_rows() 00241 || x.num_columns() != y.num_columns()) 00242 return false; 00243 for (dimension_type i = x_num_rows; i-- > 0; ) 00244 if (x[i] != y[i]) 00245 return false; 00246 return true; 00247 } 00248