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 #include "Grid_Generator_System.defs.hh"
00026 #include "Grid_Generator_System.inlines.hh"
00027 #include "Scalar_Products.defs.hh"
00028 #include "Variables_Set.defs.hh"
00029 #include "assert.hh"
00030 #include <iostream>
00031
00032 namespace PPL = Parma_Polyhedra_Library;
00033
00034 void
00035 PPL::Grid_Generator_System::recycling_insert(Grid_Generator_System& gs) {
00036 const dimension_type old_num_rows = num_rows();
00037 const dimension_type gs_num_rows = gs.num_rows();
00038 const dimension_type old_num_columns = num_columns();
00039 const dimension_type gs_num_columns = gs.num_columns();
00040 if (old_num_columns >= gs_num_columns)
00041 add_zero_rows(gs_num_rows,
00042 Linear_Row::Flags(NECESSARILY_CLOSED,
00043 Linear_Row::RAY_OR_POINT_OR_INEQUALITY));
00044 else {
00045 add_zero_rows_and_columns(gs_num_rows,
00046 gs_num_columns - old_num_columns,
00047 Linear_Row::Flags(NECESSARILY_CLOSED,
00048 Linear_Row::RAY_OR_POINT_OR_INEQUALITY));
00049
00050 swap_columns(old_num_columns - 1, num_columns() - 1);
00051 }
00052 set_index_first_pending_row(old_num_rows + gs_num_rows);
00053
00054
00055
00056 for (dimension_type i = gs_num_rows; i-- > 0; )
00057 operator[](old_num_rows + i).coefficient_swap(gs[i]);
00058 }
00059
00060 void
00061 PPL::Grid_Generator_System::recycling_insert(Grid_Generator& g) {
00062 dimension_type old_num_rows = num_rows();
00063 const dimension_type old_num_columns = num_columns();
00064 const dimension_type g_num_columns = g.size();
00065 if (old_num_columns >= g_num_columns)
00066 add_zero_rows(1,
00067 Linear_Row::Flags(NECESSARILY_CLOSED,
00068 Linear_Row::RAY_OR_POINT_OR_INEQUALITY));
00069 else {
00070 add_zero_rows_and_columns(1,
00071 g_num_columns - old_num_columns,
00072 Linear_Row::Flags(NECESSARILY_CLOSED,
00073 Linear_Row::RAY_OR_POINT_OR_INEQUALITY));
00074
00075 swap_columns(old_num_columns - 1, num_columns() - 1);
00076 }
00077 set_index_first_pending_row(old_num_rows + 1);
00078
00079
00080
00081 operator[](old_num_rows).coefficient_swap(g);
00082 }
00083
00084 void
00085 PPL::Grid_Generator_System::insert(const Grid_Generator& g) {
00086 dimension_type g_space_dim = g.space_dimension();
00087
00088 if (g.is_parameter())
00089 if (g.all_homogeneous_terms_are_zero()) {
00090 dimension_type initial_space_dim = space_dimension();
00091 if (initial_space_dim < g_space_dim) {
00092
00093 add_zero_columns(g_space_dim - initial_space_dim);
00094
00095 swap_columns(g_space_dim + 1, initial_space_dim + 1);
00096 PPL_ASSERT(OK());
00097 }
00098 return;
00099 }
00100
00101 {
00102
00103
00104
00105
00106
00107
00108 PPL_ASSERT(num_pending_rows() == 0);
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 PPL_ASSERT(topology() == g.topology());
00122
00123 PPL_ASSERT(num_pending_rows() == 0);
00124
00125 const dimension_type old_num_rows = num_rows();
00126 const dimension_type old_num_columns = num_columns();
00127 const dimension_type g_size = g.size();
00128
00129
00130 PPL_ASSERT(is_necessarily_closed());
00131 if (g_size > old_num_columns) {
00132 add_zero_columns(g_size - old_num_columns);
00133 if (old_num_rows > 0)
00134
00135
00136 swap_columns(old_num_columns - 1, g_size - 1);
00137 Matrix::add_row(g);
00138 }
00139 else if (g_size < old_num_columns)
00140 if (old_num_rows == 0)
00141 Matrix::add_row(Linear_Row(g, old_num_columns, row_capacity));
00142 else {
00143
00144
00145 Linear_Row tmp_row(g, old_num_columns, row_capacity);
00146 std::swap(tmp_row[g_size - 1], tmp_row[old_num_columns - 1]);
00147 Matrix::add_row(tmp_row);
00148 }
00149 else
00150
00151 Matrix::add_row(g);
00152
00153 }
00154
00155 set_index_first_pending_row(num_rows());
00156 set_sorted(false);
00157
00158 PPL_ASSERT(OK());
00159 }
00160
00161 void
00162 PPL::Grid_Generator_System
00163 ::affine_image(dimension_type v,
00164 const Linear_Expression& expr,
00165 Coefficient_traits::const_reference denominator) {
00166
00167
00168 Grid_Generator_System& x = *this;
00169
00170
00171 PPL_ASSERT(v > 0 && v <= x.space_dimension());
00172 PPL_ASSERT(expr.space_dimension() <= x.space_dimension());
00173 PPL_ASSERT(denominator > 0);
00174
00175 const dimension_type num_columns = x.num_columns();
00176 const dimension_type num_rows = x.num_rows();
00177
00178
00179
00180 PPL_DIRTY_TEMP_COEFFICIENT(numerator);
00181 for (dimension_type i = num_rows; i-- > 0; ) {
00182 Grid_Generator& row = x[i];
00183 Scalar_Products::assign(numerator, expr, row);
00184 std::swap(numerator, row[v]);
00185 }
00186
00187 if (denominator != 1)
00188
00189
00190
00191 for (dimension_type i = num_rows; i-- > 0; ) {
00192 Grid_Generator& row = x[i];
00193 for (dimension_type j = num_columns; j-- > 0; )
00194 if (j != v)
00195 row[j] *= denominator;
00196 }
00197
00198
00199
00200 const bool not_invertible = (v > expr.space_dimension() || expr[v] == 0);
00201 if (not_invertible)
00202 x.remove_invalid_lines_and_rays();
00203 }
00204
00205 PPL_OUTPUT_DEFINITIONS(Grid_Generator_System)
00206
00207 void
00208 PPL::Grid_Generator_System::ascii_dump(std::ostream& s) const {
00209 const dimension_type num_rows = this->num_rows();
00210 s << num_rows << " x " << num_columns() << '\n';
00211 for (dimension_type i = 0; i < num_rows; ++i)
00212 operator[](i).ascii_dump(s);
00213 }
00214
00215 bool
00216 PPL::Grid_Generator_System::ascii_load(std::istream& s) {
00217 dimension_type num_rows;
00218 dimension_type num_columns;
00219 if (!(s >> num_rows))
00220 return false;
00221 std::string str;
00222 if (!(s >> str) || str != "x")
00223 return false;
00224 if (!(s >> num_columns))
00225 return false;
00226 resize_no_copy(num_rows, num_columns);
00227
00228 set_sorted(false);
00229 set_index_first_pending_row(num_rows);
00230
00231 Grid_Generator_System& x = *this;
00232 for (dimension_type i = 0; i < num_rows; ++i)
00233 if (!x[i].ascii_load(s))
00234 return false;
00235
00236
00237 PPL_ASSERT(OK());
00238
00239 return true;
00240 }
00241
00242 const PPL::Grid_Generator_System*
00243 PPL::Grid_Generator_System::zero_dim_univ_p = 0;
00244
00245 void
00246 PPL::Grid_Generator_System::initialize() {
00247 PPL_ASSERT(zero_dim_univ_p == 0);
00248 zero_dim_univ_p
00249 = new Grid_Generator_System(Grid_Generator::zero_dim_point());
00250 }
00251
00252 void
00253 PPL::Grid_Generator_System::finalize() {
00254 PPL_ASSERT(zero_dim_univ_p != 0);
00255 delete zero_dim_univ_p;
00256 zero_dim_univ_p = 0;
00257 }
00258
00259 bool
00260 PPL::Grid_Generator_System::OK() const {
00261 if (topology() == NOT_NECESSARILY_CLOSED) {
00262 #ifndef NDEBUG
00263 std::cerr << "Grid_Generator_System is NOT_NECESSARILY_CLOSED"
00264 << std::endl;
00265 #endif
00266 return false;
00267 }
00268
00269 if (is_sorted()) {
00270 #ifndef NDEBUG
00271 std::cerr << "Grid_Generator_System is marked as sorted."
00272 << std::endl;
00273 #endif
00274 return false;
00275 }
00276
00277
00278
00279
00280 if (!Linear_System::OK(false))
00281 return false;
00282
00283
00284 const Grid_Generator_System& x = *this;
00285 for (dimension_type i = num_rows(); i-- > 0; )
00286 if (!x[i].OK())
00287 return false;
00288
00289
00290 return true;
00291 }
00292
00294 std::ostream&
00295 PPL::IO_Operators::operator<<(std::ostream& s,
00296 const Grid_Generator_System& gs) {
00297 Grid_Generator_System::const_iterator i = gs.begin();
00298 const Grid_Generator_System::const_iterator gs_end = gs.end();
00299 if (i == gs_end)
00300 return s << "false";
00301 while (true) {
00302 s << *i++;
00303 if (i == gs_end)
00304 return s;
00305 s << ", ";
00306 }
00307 }
00308
00309 void
00310 PPL::Grid_Generator_System
00311 ::add_universe_rows_and_columns(dimension_type dims) {
00312 PPL_ASSERT(num_columns() > 0);
00313 dimension_type col = num_columns() - 1;
00314 add_zero_rows_and_columns(dims, dims,
00315 Linear_Row::Flags(NECESSARILY_CLOSED,
00316 Linear_Row::LINE_OR_EQUALITY));
00317 unset_pending_rows();
00318
00319 swap_columns(col, col + dims);
00320
00321 dimension_type num_rows = this->num_rows();
00322 for (dimension_type row = num_rows - dims; row < num_rows; ++row, ++col)
00323 const_cast<Coefficient&>(operator[](row)[col]) = 1;
00324 }
00325
00326 void
00327 PPL::Grid_Generator_System
00328 ::remove_space_dimensions(const Variables_Set& vars) {
00329
00330 PPL_ASSERT(space_dimension() >= vars.space_dimension());
00331
00332
00333
00334
00335 if (vars.empty())
00336 return;
00337
00338
00339
00340 Variables_Set::const_iterator vsi = vars.begin();
00341 Variables_Set::const_iterator vsi_end = vars.end();
00342 dimension_type dst_col = *vsi+1;
00343 dimension_type src_col = dst_col + 1;
00344 for (++vsi; vsi != vsi_end; ++vsi) {
00345 const dimension_type vsi_col = *vsi+1;
00346
00347 while (src_col < vsi_col)
00348 Matrix::swap_columns(dst_col++, src_col++);
00349 ++src_col;
00350 }
00351
00352 const dimension_type num_columns = this->num_columns();
00353 while (src_col < num_columns)
00354 Matrix::swap_columns(dst_col++, src_col++);
00355
00356
00357 Matrix::remove_trailing_columns(num_columns - dst_col);
00358 }
00359
00360 void
00361 PPL::Grid_Generator_System
00362 ::remove_higher_space_dimensions(const dimension_type new_dimension) {
00363 dimension_type space_dim = space_dimension();
00364
00365 PPL_ASSERT(new_dimension <= space_dim);
00366
00367
00368
00369
00370 if (new_dimension == space_dim)
00371 return;
00372
00373
00374
00375 swap_columns(new_dimension + 1, space_dim + 1);
00376 Matrix::remove_trailing_columns(space_dim - new_dimension);
00377 PPL_ASSERT(OK());
00378 }