00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef PPL_DB_Matrix_templates_hh
00025 #define PPL_DB_Matrix_templates_hh 1
00026
00027 namespace Parma_Polyhedra_Library {
00028
00029 template <typename T>
00030 DB_Matrix<T>::DB_Matrix(const dimension_type n_rows)
00031 : rows(n_rows),
00032 row_size(n_rows),
00033 row_capacity(compute_capacity(n_rows, max_num_columns())) {
00034
00035 for (dimension_type i = 0; i < n_rows; ++i)
00036 rows[i].construct(n_rows, row_capacity);
00037 PPL_ASSERT(OK());
00038 }
00039
00040 template <typename T>
00041 template <typename U>
00042 DB_Matrix<T>::DB_Matrix(const DB_Matrix<U>& y)
00043 : rows(y.rows.size()),
00044 row_size(y.row_size),
00045 row_capacity(compute_capacity(y.row_size, max_num_columns())) {
00046
00047 for (dimension_type i = 0, n_rows = rows.size(); i < n_rows; ++i)
00048 rows[i].construct_upward_approximation(y[i], row_capacity);
00049 PPL_ASSERT(OK());
00050 }
00051
00052 template <typename T>
00053 void
00054 DB_Matrix<T>::grow(const dimension_type new_n_rows) {
00055 const dimension_type old_n_rows = rows.size();
00056 PPL_ASSERT(new_n_rows >= old_n_rows);
00057
00058 if (new_n_rows > old_n_rows) {
00059 if (new_n_rows <= row_capacity) {
00060
00061 if (rows.capacity() < new_n_rows) {
00062
00063 std::vector<DB_Row<T> > new_rows;
00064 new_rows.reserve(compute_capacity(new_n_rows, max_num_rows()));
00065 new_rows.insert(new_rows.end(), new_n_rows, DB_Row<T>());
00066
00067 dimension_type i = new_n_rows;
00068 while (i-- > old_n_rows)
00069 new_rows[i].construct(new_n_rows, row_capacity);
00070
00071 ++i;
00072 while (i-- > 0)
00073 new_rows[i].swap(rows[i]);
00074
00075 std::swap(rows, new_rows);
00076 }
00077 else {
00078
00079 rows.insert(rows.end(), new_n_rows - old_n_rows, DB_Row<T>());
00080 for (dimension_type i = new_n_rows; i-- > old_n_rows; )
00081 rows[i].construct(new_n_rows, row_capacity);
00082 }
00083 }
00084 else {
00085
00086 DB_Matrix new_matrix;
00087 new_matrix.rows.reserve(compute_capacity(new_n_rows, max_num_rows()));
00088 new_matrix.rows.insert(new_matrix.rows.end(), new_n_rows, DB_Row<T>());
00089
00090 new_matrix.row_size = new_n_rows;
00091 new_matrix.row_capacity = compute_capacity(new_n_rows,
00092 max_num_columns());
00093 dimension_type i = new_n_rows;
00094 while (i-- > old_n_rows)
00095 new_matrix.rows[i].construct(new_matrix.row_size,
00096 new_matrix.row_capacity);
00097
00098 ++i;
00099 while (i-- > 0) {
00100
00101 DB_Row<T> new_row(rows[i],
00102 new_matrix.row_size,
00103 new_matrix.row_capacity);
00104 std::swap(new_matrix.rows[i], new_row);
00105 }
00106
00107 swap(new_matrix);
00108 return;
00109 }
00110 }
00111
00112 if (new_n_rows > row_size) {
00113
00114 if (new_n_rows <= row_capacity)
00115
00116 for (dimension_type i = old_n_rows; i-- > 0; )
00117 rows[i].expand_within_capacity(new_n_rows);
00118 else {
00119
00120
00121 const dimension_type new_row_capacity
00122 = compute_capacity(new_n_rows, max_num_columns());
00123 for (dimension_type i = old_n_rows; i-- > 0; ) {
00124
00125 DB_Row<T> new_row(rows[i], new_n_rows, new_row_capacity);
00126 std::swap(rows[i], new_row);
00127 }
00128 row_capacity = new_row_capacity;
00129 }
00130
00131 row_size = new_n_rows;
00132 }
00133 }
00134
00135 template <typename T>
00136 void
00137 DB_Matrix<T>::resize_no_copy(const dimension_type new_n_rows) {
00138 dimension_type old_n_rows = rows.size();
00139
00140 if (new_n_rows > old_n_rows) {
00141
00142 if (new_n_rows <= row_capacity) {
00143
00144 if (rows.capacity() < new_n_rows) {
00145
00146 std::vector<DB_Row<T> > new_rows;
00147 new_rows.reserve(compute_capacity(new_n_rows, max_num_rows()));
00148 new_rows.insert(new_rows.end(), new_n_rows, DB_Row<T>());
00149
00150
00151 dimension_type i = new_n_rows;
00152 while (i-- > old_n_rows)
00153 new_rows[i].construct(new_n_rows, row_capacity);
00154
00155 ++i;
00156 while (i-- > 0)
00157 new_rows[i].swap(rows[i]);
00158
00159 std::swap(rows, new_rows);
00160 }
00161 else {
00162
00163 rows.insert(rows.end(), new_n_rows - old_n_rows, DB_Row<T>());
00164
00165
00166 for (dimension_type i = new_n_rows; i-- > old_n_rows; )
00167 rows[i].construct(new_n_rows, row_capacity);
00168 }
00169 }
00170 else {
00171
00172 DB_Matrix new_matrix(new_n_rows);
00173 swap(new_matrix);
00174 return;
00175 }
00176 }
00177 else if (new_n_rows < old_n_rows) {
00178
00179 rows.erase(rows.begin() + new_n_rows, rows.end());
00180
00181 for (dimension_type i = new_n_rows; i-- > 0; )
00182 rows[i].shrink(new_n_rows);
00183 old_n_rows = new_n_rows;
00184 }
00185
00186 if (new_n_rows > row_size) {
00187
00188 if (new_n_rows <= row_capacity)
00189
00190 for (dimension_type i = old_n_rows; i-- > 0; )
00191 rows[i].expand_within_capacity(new_n_rows);
00192 else {
00193
00194
00195 const dimension_type new_row_capacity
00196 = compute_capacity(new_n_rows, max_num_columns());
00197 for (dimension_type i = old_n_rows; i-- > 0; ) {
00198 DB_Row<T> new_row(new_n_rows, new_row_capacity);
00199 std::swap(rows[i], new_row);
00200 }
00201 row_capacity = new_row_capacity;
00202 }
00203 }
00204
00205 row_size = new_n_rows;
00206 }
00207
00208 template <typename T>
00209 void
00210 DB_Matrix<T>::ascii_dump(std::ostream& s) const {
00211 const DB_Matrix<T>& x = *this;
00212 const char separator = ' ';
00213 const dimension_type nrows = x.num_rows();
00214 s << nrows << separator << "\n";
00215 for (dimension_type i = 0; i < nrows; ++i) {
00216 for (dimension_type j = 0; j < nrows; ++j) {
00217 using namespace IO_Operators;
00218 s << x[i][j] << separator;
00219 }
00220 s << "\n";
00221 }
00222 }
00223
00224 PPL_OUTPUT_TEMPLATE_DEFINITIONS(T, DB_Matrix<T>)
00225
00226 template <typename T>
00227 bool
00228 DB_Matrix<T>::ascii_load(std::istream& s) {
00229 dimension_type nrows;
00230 if (!(s >> nrows))
00231 return false;
00232 resize_no_copy(nrows);
00233 DB_Matrix& x = *this;
00234 for (dimension_type i = 0; i < nrows; ++i)
00235 for (dimension_type j = 0; j < nrows; ++j) {
00236 Result r = input(x[i][j], s, ROUND_CHECK);
00237 if (result_relation(r) != VR_EQ || is_minus_infinity(x[i][j]))
00238 return false;
00239 }
00240
00241
00242 PPL_ASSERT(OK());
00243 return true;
00244 }
00245
00246 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00247
00248 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00249 template <typename T>
00250 bool
00251 operator==(const DB_Matrix<T>& x, const DB_Matrix<T>& y) {
00252 const dimension_type x_num_rows = x.num_rows();
00253 if (x_num_rows != y.num_rows())
00254 return false;
00255 for (dimension_type i = x_num_rows; i-- > 0; )
00256 if (x[i] != y[i])
00257 return false;
00258 return true;
00259 }
00260
00261 template <typename T>
00262 memory_size_type
00263 DB_Matrix<T>::external_memory_in_bytes() const {
00264 memory_size_type n = rows.capacity() * sizeof(DB_Row<T>);
00265 for (dimension_type i = num_rows(); i-- > 0; )
00266 n += rows[i].external_memory_in_bytes(row_capacity);
00267 return n;
00268 }
00269
00270 template <typename T>
00271 bool
00272 DB_Matrix<T>::OK() const {
00273 #ifndef NDEBUG
00274 using std::endl;
00275 using std::cerr;
00276 #endif
00277
00278
00279 if (num_rows() != row_size) {
00280 #ifndef NDEBUG
00281 cerr << "DB_Matrix has fewer columns than rows:\n"
00282 << "row_size is " << row_size
00283 << ", num_rows() is " << num_rows() << "!"
00284 << endl;
00285 #endif
00286 return false;
00287 }
00288
00289 const DB_Matrix& x = *this;
00290 const dimension_type n_rows = x.num_rows();
00291 for (dimension_type i = 0; i < n_rows; ++i) {
00292 if (!x[i].OK(row_size, row_capacity))
00293 return false;
00294 }
00295
00296
00297 return true;
00298 }
00299
00300 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00301
00302 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00303 template <typename T>
00304 std::ostream&
00305 IO_Operators::operator<<(std::ostream& s, const DB_Matrix<T>& c) {
00306 const dimension_type n = c.num_rows();
00307 for (dimension_type i = 0; i < n; ++i) {
00308 for (dimension_type j = 0; j < n; ++j)
00309 s << c[i][j] << " ";
00310 s << "\n";
00311 }
00312 return s;
00313 }
00314
00315 }
00316
00317 #endif // !defined(PPL_DB_Matrix_templates_hh)