The base class for systems of constraints and generators. More...
#include <Linear_System.defs.hh>


Classes | |
| struct | Row_Less_Than |
| Ordering predicate (used when implementing the sort algorithm). More... | |
| struct | With_Pending |
| A tag class. More... | |
Public Member Functions | |
| Linear_System (Topology topol) | |
| Builds an empty linear system with specified topology. | |
| Linear_System (Topology topol, dimension_type n_rows, dimension_type n_columns) | |
| Builds a system with specified topology and dimensions. | |
| Linear_System (const Linear_System &y) | |
| Copy constructor: pending rows are transformed into non-pending ones. | |
| Linear_System (const Linear_System &y, With_Pending) | |
| Full copy constructor: pending rows are copied as pending. | |
| Linear_System & | operator= (const Linear_System &y) |
| Assignment operator: pending rows are transformed into non-pending ones. | |
| void | assign_with_pending (const Linear_System &y) |
| Full assignment operator: pending rows are copied as pending. | |
| void | swap (Linear_System &y) |
Swaps *this with y. | |
| dimension_type | space_dimension () const |
| Returns the space dimension of the rows in the system. | |
| void | remove_trailing_columns (dimension_type n) |
Makes the system shrink by removing its n trailing columns. | |
| void | permute_columns (const std::vector< dimension_type > &cycles) |
| Permutes the columns of the system. | |
| void | strong_normalize () |
| Strongly normalizes the system. | |
| void | sign_normalize () |
| Sign-normalizes the system. | |
| bool | check_sorted () const |
Returns true if and only if *this is sorted, without checking for duplicates. | |
| void | set_necessarily_closed () |
Sets the system topology to NECESSARILY_CLOSED. | |
| void | set_not_necessarily_closed () |
Sets the system topology to NOT_NECESSARILY_CLOSED. | |
| void | set_rows_topology () |
| Sets the topology of all rows equal to the system topology. | |
| void | unset_pending_rows () |
| Sets the index to indicate that the system has no pending rows. | |
| void | set_index_first_pending_row (dimension_type i) |
Sets the index of the first pending row to i. | |
| void | set_sorted (bool b) |
Sets the sortedness flag of the system to b. | |
| void | resize_no_copy (dimension_type new_n_rows, dimension_type new_n_columns) |
| Resizes the system without worrying about the old contents. | |
| void | add_rows_and_columns (dimension_type n) |
Adds n rows and columns to the system. | |
| void | insert (const Linear_Row &r) |
Adds a copy of r to the system, automatically resizing the system or the row's copy, if needed. | |
| void | insert_pending (const Linear_Row &r) |
| Adds a copy of the given row to the pending part of the system, automatically resizing the system or the row, if needed. | |
| void | add_row (const Linear_Row &r) |
| Adds a copy of the given row to the system. | |
| void | add_pending_row (Linear_Row::Flags flags) |
| Adds a new empty row to the system, setting only its flags. | |
| void | add_pending_row (const Linear_Row &r) |
| Adds a copy of the given row to the pending part of the system. | |
| void | add_rows (const Linear_System &y) |
Adds to *this a copy of the rows of `y'. | |
| void | add_pending_rows (const Linear_System &y) |
| Adds a copy of the rows of `y' to the pending part of `*this'. | |
| void | sort_rows () |
| Sorts the non-pending rows (in growing order) and eliminates duplicated ones. | |
| void | sort_rows (dimension_type first_row, dimension_type last_row) |
Sorts the rows (in growing order) form first_row to last_row and eliminates duplicated ones. | |
| void | merge_rows_assign (const Linear_System &y) |
Assigns to *this the result of merging its rows with those of y, obtaining a sorted system. | |
| void | sort_pending_and_remove_duplicates () |
| Sorts the pending rows and eliminates those that also occur in the non-pending part of the system. | |
| void | sort_and_remove_with_sat (Bit_Matrix &sat) |
| Sorts the system, removing duplicates, keeping the saturation matrix consistent. | |
| dimension_type | gauss (dimension_type n_lines_or_equalities) |
Minimizes the subsystem of equations contained in *this. | |
| void | back_substitute (dimension_type n_lines_or_equalities) |
| Back-substitutes the coefficients to reduce the complexity of the system. | |
| void | simplify () |
| Applies Gaussian elimination and back-substitution so as to simplify the linear system. | |
| void | normalize () |
| Normalizes the system by dividing each row for the GCD of the row's elements. | |
| void | clear () |
| Clears the system deallocating all its rows. | |
| void | ascii_dump () const |
Writes to std::cerr an ASCII representation of *this. | |
| void | ascii_dump (std::ostream &s) const |
Writes to s an ASCII representation of *this. | |
| void | print () const |
Prints *this to std::cerr using operator<<. | |
| bool | ascii_load (std::istream &s) |
Loads from s an ASCII representation (as produced by ascii_dump(std::ostream&) const) and sets *this accordingly. Returns true if successful, false otherwise. | |
| memory_size_type | total_memory_in_bytes () const |
Returns the total size in bytes of the memory occupied by *this. | |
| memory_size_type | external_memory_in_bytes () const |
Returns the size in bytes of the memory managed by *this. | |
| bool | OK (bool check_strong_normalized=true) const |
| Checks if all the invariants are satisfied. | |
Subscript operators | |
| Linear_Row & | operator[] (dimension_type k) |
Returns a reference to the k-th row of the system. | |
| const Linear_Row & | operator[] (dimension_type k) const |
Returns a constant reference to the k-th row of the system. | |
Accessors | |
| Topology | topology () const |
| Returns the system topology. | |
| bool | is_sorted () const |
| Returns the value of the sortedness flag. | |
| bool | is_necessarily_closed () const |
Returns true if and only if the system topology is NECESSARILY_CLOSED. | |
| dimension_type | num_lines_or_equalities () const |
| Returns the number of rows in the system that represent either lines or equalities. | |
| dimension_type | first_pending_row () const |
| Returns the index of the first pending row. | |
| dimension_type | num_pending_rows () const |
| Returns the number of rows that are in the pending part of the system. | |
Static Public Member Functions | |
| static dimension_type | max_space_dimension () |
| Returns the maximum space dimension a Linear_System can handle. | |
Private Attributes | |
| Topology | row_topology |
| The topological kind of the rows in the system. | |
| dimension_type | index_first_pending |
| The index of the first pending row. | |
| bool | sorted |
true if rows are sorted in the ascending order as defined by bool compare(const Linear_Row&, const Linear_Row&). If false may not be sorted. | |
Related Functions | |
(Note that these are not member functions.) | |
| void | swap (Parma_Polyhedra_Library::Linear_System &x, Parma_Polyhedra_Library::Linear_System &y) |
Specializes std::swap. | |
| bool | operator== (const Linear_System &x, const Linear_System &y) |
Returns true if and only if x and y are identical. | |
| bool | operator!= (const Linear_System &x, const Linear_System &y) |
Returns true if and only if x and y are different. | |
The base class for systems of constraints and generators.
An object of this class represents either a constraint system or a generator system. Each Linear_System object can be viewed as a finite sequence of strong-normalized Linear_Row objects, where each Linear_Row implements a constraint or a generator. Linear systems are characterized by the matrix of coefficients, also encoding the number, size and capacity of Linear_row objects, as well as a few additional information, including:
true, ensures that the non-pending prefix of the sequence of rows is sorted. Definition at line 55 of file Linear_System.defs.hh.
| Parma_Polyhedra_Library::Linear_System::Linear_System | ( | Topology | topol | ) | [inline] |
Builds an empty linear system with specified topology.
Rows size and capacity are initialized to
.
Definition at line 57 of file Linear_System.inlines.hh.
00058 : Matrix(), 00059 row_topology(topol), 00060 index_first_pending(0), 00061 sorted(true) { 00062 }
| Parma_Polyhedra_Library::Linear_System::Linear_System | ( | Topology | topol, | |
| dimension_type | n_rows, | |||
| dimension_type | n_columns | |||
| ) | [inline] |
Builds a system with specified topology and dimensions.
| topol | The topology of the system that will be created; | |
| n_rows | The number of rows of the system that will be created; | |
| n_columns | The number of columns of the system that will be created. |
Creates a n_rows
n_columns system whose coefficients are all zero and whose rows are all initialized to be of the given topology.
Definition at line 65 of file Linear_System.inlines.hh.
00067 : Matrix(n_rows, n_columns, Linear_Row::Flags(topol)), 00068 row_topology(topol), 00069 index_first_pending(n_rows), 00070 sorted(true) { 00071 }
| Parma_Polyhedra_Library::Linear_System::Linear_System | ( | const Linear_System & | y | ) | [inline] |
Copy constructor: pending rows are transformed into non-pending ones.
Definition at line 95 of file Linear_System.inlines.hh.
References num_pending_rows(), sorted, and unset_pending_rows().
00096 : Matrix(y), 00097 row_topology(y.row_topology) { 00098 unset_pending_rows(); 00099 // Previously pending rows may violate sortedness. 00100 sorted = (y.num_pending_rows() > 0) ? false : y.sorted; 00101 PPL_ASSERT(num_pending_rows() == 0); 00102 }
| Parma_Polyhedra_Library::Linear_System::Linear_System | ( | const Linear_System & | y, | |
| With_Pending | ||||
| ) | [inline] |
Full copy constructor: pending rows are copied as pending.
Definition at line 105 of file Linear_System.inlines.hh.
00106 : Matrix(y), 00107 row_topology(y.row_topology), 00108 index_first_pending(y.index_first_pending), 00109 sorted(y.sorted) { 00110 }
| void Parma_Polyhedra_Library::Linear_System::add_pending_row | ( | const Linear_Row & | r | ) |
Adds a copy of the given row to the pending part of the system.
Definition at line 397 of file Linear_System.cc.
References Parma_Polyhedra_Library::Linear_Row::check_strong_normalized(), Parma_Polyhedra_Library::compute_capacity(), Parma_Polyhedra_Library::Matrix::max_num_rows(), num_pending_rows(), Parma_Polyhedra_Library::Matrix::OK(), Parma_Polyhedra_Library::Matrix::row_capacity, Parma_Polyhedra_Library::Matrix::row_size, Parma_Polyhedra_Library::Matrix::rows, Parma_Polyhedra_Library::Row::size(), and swap().
00397 { 00398 // The added row must be strongly normalized and have the same 00399 // number of elements of the existing rows of the system. 00400 PPL_ASSERT(r.check_strong_normalized()); 00401 PPL_ASSERT(r.size() == row_size); 00402 00403 const dimension_type new_rows_size = rows.size() + 1; 00404 if (rows.capacity() < new_rows_size) { 00405 // Reallocation will take place. 00406 std::vector<Row> new_rows; 00407 new_rows.reserve(compute_capacity(new_rows_size, max_num_rows())); 00408 new_rows.insert(new_rows.end(), new_rows_size, Row()); 00409 // Put the new row in place. 00410 Row new_row(r, row_capacity); 00411 dimension_type i = new_rows_size-1; 00412 std::swap(new_rows[i], new_row); 00413 // Steal the old rows. 00414 while (i-- > 0) 00415 new_rows[i].swap(rows[i]); 00416 // Put the new rows into place. 00417 std::swap(rows, new_rows); 00418 } 00419 else { 00420 // Reallocation will NOT take place. 00421 // Inserts a new empty row at the end, then substitutes it with a 00422 // copy of the given row. 00423 Row tmp(r, row_capacity); 00424 std::swap(*rows.insert(rows.end(), Row()), tmp); 00425 } 00426 00427 // The added row was a pending row. 00428 PPL_ASSERT(num_pending_rows() > 0); 00429 // Do not check for strong normalization, because no modification of 00430 // rows has occurred. 00431 PPL_ASSERT(OK(false)); 00432 }
| void Parma_Polyhedra_Library::Linear_System::add_pending_row | ( | Linear_Row::Flags | flags | ) |
Adds a new empty row to the system, setting only its flags.
Definition at line 435 of file Linear_System.cc.
References Parma_Polyhedra_Library::compute_capacity(), Parma_Polyhedra_Library::construct(), Parma_Polyhedra_Library::Matrix::max_num_rows(), num_pending_rows(), Parma_Polyhedra_Library::Matrix::row_capacity, Parma_Polyhedra_Library::Matrix::row_size, Parma_Polyhedra_Library::Matrix::rows, and swap().
Referenced by Parma_Polyhedra_Library::Polyhedron::add_and_minimize(), Parma_Polyhedra_Library::Generator_System::add_corresponding_closure_points(), Parma_Polyhedra_Library::Generator_System::add_corresponding_points(), Parma_Polyhedra_Library::Polyhedron::conversion(), and insert_pending().
00435 { 00436 const dimension_type new_rows_size = rows.size() + 1; 00437 if (rows.capacity() < new_rows_size) { 00438 // Reallocation will take place. 00439 std::vector<Row> new_rows; 00440 new_rows.reserve(compute_capacity(new_rows_size, max_num_rows())); 00441 new_rows.insert(new_rows.end(), new_rows_size, Row()); 00442 // Put the new row in place. 00443 Linear_Row new_row(row_size, row_capacity, flags); 00444 dimension_type i = new_rows_size-1; 00445 std::swap(new_rows[i], new_row); 00446 // Steal the old rows. 00447 while (i-- > 0) 00448 new_rows[i].swap(rows[i]); 00449 // Put the new vector into place. 00450 std::swap(rows, new_rows); 00451 } 00452 else { 00453 // Reallocation will NOT take place. 00454 // Insert a new empty row at the end, then construct it assigning 00455 // it the given type. 00456 Row& new_row = *rows.insert(rows.end(), Row()); 00457 static_cast<Linear_Row&>(new_row).construct(row_size, row_capacity, flags); 00458 } 00459 00460 // The added row was a pending row. 00461 PPL_ASSERT(num_pending_rows() > 0); 00462 }
| void Parma_Polyhedra_Library::Linear_System::add_pending_rows | ( | const Linear_System & | y | ) |
Adds a copy of the rows of `y' to the pending part of `*this'.
Definition at line 265 of file Linear_System.cc.
References Parma_Polyhedra_Library::Matrix::add_zero_rows(), Parma_Polyhedra_Library::Matrix::num_rows(), Parma_Polyhedra_Library::Matrix::OK(), Parma_Polyhedra_Library::Matrix::row_capacity, Parma_Polyhedra_Library::Matrix::row_size, row_topology, sorted, and swap().
Referenced by add_rows(), Parma_Polyhedra_Library::Polyhedron::intersection_assign(), Parma_Polyhedra_Library::Polyhedron::poly_hull_assign(), and Parma_Polyhedra_Library::Polyhedron::time_elapse_assign().
00265 { 00266 Linear_System& x = *this; 00267 PPL_ASSERT(x.row_size == y.row_size); 00268 00269 const dimension_type x_n_rows = x.num_rows(); 00270 const dimension_type y_n_rows = y.num_rows(); 00271 // Grow to the required size without changing sortedness. 00272 const bool was_sorted = sorted; 00273 add_zero_rows(y_n_rows, Linear_Row::Flags(row_topology)); 00274 sorted = was_sorted; 00275 00276 // Copy the rows of `y', forcing size and capacity. 00277 for (dimension_type i = y_n_rows; i-- > 0; ) { 00278 Row copy(y[i], x.row_size, x.row_capacity); 00279 std::swap(copy, x[x_n_rows+i]); 00280 } 00281 // Do not check for strong normalization, 00282 // because no modification of rows has occurred. 00283 PPL_ASSERT(OK(false)); 00284 }
| void Parma_Polyhedra_Library::Linear_System::add_row | ( | const Linear_Row & | r | ) |
Adds a copy of the given row to the system.
Definition at line 359 of file Linear_System.cc.
References Parma_Polyhedra_Library::Linear_Row::check_strong_normalized(), is_sorted(), num_pending_rows(), Parma_Polyhedra_Library::Matrix::num_rows(), Parma_Polyhedra_Library::Matrix::OK(), Parma_Polyhedra_Library::Matrix::row_size, set_index_first_pending_row(), set_sorted(), and Parma_Polyhedra_Library::Row::size().
Referenced by Parma_Polyhedra_Library::Polyhedron::generalized_affine_image(), insert(), and Parma_Polyhedra_Library::Grid_Generator_System::insert().
00359 { 00360 // The added row must be strongly normalized and have the same 00361 // number of elements as the existing rows of the system. 00362 PPL_ASSERT(r.check_strong_normalized()); 00363 PPL_ASSERT(r.size() == row_size); 00364 // This method is only used when the system has no pending rows. 00365 PPL_ASSERT(num_pending_rows() == 0); 00366 00367 const bool was_sorted = is_sorted(); 00368 00369 Matrix::add_row(r); 00370 00371 // We update `index_first_pending', because it must be equal to 00372 // `num_rows()'. 00373 set_index_first_pending_row(num_rows()); 00374 00375 if (was_sorted) { 00376 const dimension_type nrows = num_rows(); 00377 // The added row may have caused the system to be not sorted anymore. 00378 if (nrows > 1) { 00379 // If the system is not empty and the inserted row is the 00380 // greatest one, the system is set to be sorted. 00381 // If it is not the greatest one then the system is no longer sorted. 00382 Linear_System& x = *this; 00383 set_sorted(compare(x[nrows-2], x[nrows-1]) <= 0); 00384 } 00385 else 00386 // A system having only one row is sorted. 00387 set_sorted(true); 00388 } 00389 // The added row was not a pending row. 00390 PPL_ASSERT(num_pending_rows() == 0); 00391 // Do not check for strong normalization, because no modification of 00392 // rows has occurred. 00393 PPL_ASSERT(OK(false)); 00394 }
| void Parma_Polyhedra_Library::Linear_System::add_rows | ( | const Linear_System & | y | ) |
Adds to *this a copy of the rows of `y'.
It is assumed that *this has no pending rows.
Definition at line 287 of file Linear_System.cc.
References add_pending_rows(), Parma_Polyhedra_Library::Matrix::has_no_rows(), is_sorted(), num_pending_rows(), Parma_Polyhedra_Library::Matrix::num_rows(), Parma_Polyhedra_Library::Matrix::OK(), set_sorted(), and unset_pending_rows().
Referenced by Parma_Polyhedra_Library::Polyhedron::intersection_assign(), and Parma_Polyhedra_Library::Polyhedron::poly_hull_assign().
00287 { 00288 PPL_ASSERT(num_pending_rows() == 0); 00289 00290 // Adding no rows is a no-op. 00291 if (y.has_no_rows()) 00292 return; 00293 00294 // Check if sortedness is preserved. 00295 if (is_sorted()) { 00296 if (!y.is_sorted() || y.num_pending_rows() > 0) 00297 set_sorted(false); 00298 else { 00299 // `y' is sorted and has no pending rows. 00300 const dimension_type n_rows = num_rows(); 00301 if (n_rows > 0) 00302 set_sorted(compare((*this)[n_rows-1], y[0]) <= 0); 00303 } 00304 } 00305 00306 // Add the rows of `y' as if they were pending. 00307 add_pending_rows(y); 00308 // There are no pending_rows. 00309 unset_pending_rows(); 00310 00311 // Do not check for strong normalization, 00312 // because no modification of rows has occurred. 00313 PPL_ASSERT(OK(false)); 00314 }
| void Parma_Polyhedra_Library::Linear_System::add_rows_and_columns | ( | dimension_type | n | ) |
Adds n rows and columns to the system.
| n | The number of rows and columns to be added: must be strictly positive. |
Turns the system
into the system
such that
, where
is the specular image of the
identity matrix.
Definition at line 748 of file Linear_System.cc.
References Parma_Polyhedra_Library::Matrix::add_zero_rows_and_columns(), is_sorted(), Parma_Polyhedra_Library::Matrix::num_columns(), Parma_Polyhedra_Library::Matrix::num_rows(), Parma_Polyhedra_Library::Matrix::OK(), row_topology, Parma_Polyhedra_Library::Linear_Row::set_is_line_or_equality(), set_sorted(), and Parma_Polyhedra_Library::swap().
Referenced by Parma_Polyhedra_Library::Polyhedron::add_space_dimensions(), Parma_Polyhedra_Library::Polyhedron::add_space_dimensions_and_embed(), Parma_Polyhedra_Library::Polyhedron::add_space_dimensions_and_project(), and Parma_Polyhedra_Library::Polyhedron::concatenate_assign().
00748 { 00749 PPL_ASSERT(n > 0); 00750 const bool was_sorted = is_sorted(); 00751 const dimension_type old_n_rows = num_rows(); 00752 const dimension_type old_n_columns = num_columns(); 00753 add_zero_rows_and_columns(n, n, Linear_Row::Flags(row_topology)); 00754 Linear_System& x = *this; 00755 // The old system is moved to the bottom. 00756 for (dimension_type i = old_n_rows; i-- > 0; ) 00757 std::swap(x[i], x[i + n]); 00758 for (dimension_type i = n, c = old_n_columns; i-- > 0; ) { 00759 // The top right-hand sub-system (i.e., the system made of new 00760 // rows and columns) is set to the specular image of the identity 00761 // matrix. 00762 Linear_Row& r = x[i]; 00763 r[c++] = 1; 00764 r.set_is_line_or_equality(); 00765 // Note: `r' is strongly normalized. 00766 } 00767 // If the old system was empty, the last row added is either 00768 // a positivity constraint or a point. 00769 if (old_n_columns == 0) { 00770 x[n-1].set_is_ray_or_point_or_inequality(); 00771 // Since ray, points and inequalities come after lines 00772 // and equalities, this case implies the system is sorted. 00773 set_sorted(true); 00774 } 00775 else if (was_sorted) 00776 set_sorted(compare(x[n-1], x[n]) <= 0); 00777 00778 // A well-formed system has to be returned. 00779 PPL_ASSERT(OK(true)); 00780 }
| void Parma_Polyhedra_Library::Linear_System::ascii_dump | ( | std::ostream & | s | ) | const |
Writes to s an ASCII representation of *this.
Reimplemented from Parma_Polyhedra_Library::Matrix.
Reimplemented in Parma_Polyhedra_Library::Constraint_System, Parma_Polyhedra_Library::Generator_System, and Parma_Polyhedra_Library::Grid_Generator_System.
Definition at line 114 of file Linear_System.cc.
References ascii_dump(), first_pending_row(), is_necessarily_closed(), Parma_Polyhedra_Library::Matrix::num_columns(), Parma_Polyhedra_Library::Matrix::num_rows(), and sorted.
00114 { 00115 // Prints the topology, the number of rows, the number of columns 00116 // and the sorted flag. The specialized methods provided by 00117 // Constraint_System and Generator_System take care of properly 00118 // printing the contents of the system. 00119 const Linear_System& x = *this; 00120 dimension_type x_num_rows = x.num_rows(); 00121 dimension_type x_num_columns = x.num_columns(); 00122 s << "topology " << (is_necessarily_closed() 00123 ? "NECESSARILY_CLOSED" 00124 : "NOT_NECESSARILY_CLOSED") 00125 << "\n" 00126 << x_num_rows << " x " << x_num_columns 00127 << (x.sorted ? "(sorted)" : "(not_sorted)") 00128 << "\n" 00129 << "index_first_pending " << x.first_pending_row() 00130 << "\n"; 00131 for (dimension_type i = 0; i < x_num_rows; ++i) 00132 x[i].ascii_dump(s); 00133 }
| void Parma_Polyhedra_Library::Linear_System::ascii_dump | ( | ) | const |
Writes to std::cerr an ASCII representation of *this.
Reimplemented from Parma_Polyhedra_Library::Matrix.
Reimplemented in Parma_Polyhedra_Library::Constraint_System, Parma_Polyhedra_Library::Generator_System, and Parma_Polyhedra_Library::Grid_Generator_System.
Referenced by ascii_dump().
| bool Parma_Polyhedra_Library::Linear_System::ascii_load | ( | std::istream & | s | ) |
Loads from s an ASCII representation (as produced by ascii_dump(std::ostream&) const) and sets *this accordingly. Returns true if successful, false otherwise.
Reads into a Linear_System object the information produced by the output of ascii_dump(std::ostream&) const. The specialized methods provided by Constraint_System and Generator_System take care of properly reading the contents of the system.
Reimplemented from Parma_Polyhedra_Library::Matrix.
Reimplemented in Parma_Polyhedra_Library::Constraint_System, Parma_Polyhedra_Library::Generator_System, and Parma_Polyhedra_Library::Grid_Generator_System.
Definition at line 138 of file Linear_System.cc.
References Parma_Polyhedra_Library::ascii_load().
00138 { 00139 std::string str; 00140 if (!(s >> str) || str != "topology") 00141 return false; 00142 if (!(s >> str)) 00143 return false; 00144 if (str == "NECESSARILY_CLOSED") 00145 set_necessarily_closed(); 00146 else { 00147 if (str != "NOT_NECESSARILY_CLOSED") 00148 return false; 00149 set_not_necessarily_closed(); 00150 } 00151 00152 dimension_type nrows; 00153 dimension_type ncols; 00154 if (!(s >> nrows)) 00155 return false; 00156 if (!(s >> str) || str != "x") 00157 return false; 00158 if (!(s >> ncols)) 00159 return false; 00160 resize_no_copy(nrows, ncols); 00161 00162 if (!(s >> str) || (str != "(sorted)" && str != "(not_sorted)")) 00163 return false; 00164 set_sorted(str == "(sorted)"); 00165 dimension_type index; 00166 if (!(s >> str) || str != "index_first_pending") 00167 return false; 00168 if (!(s >> index)) 00169 return false; 00170 set_index_first_pending_row(index); 00171 00172 Linear_System& x = *this; 00173 for (dimension_type row = 0; row < nrows; ++row) 00174 if (!x[row].ascii_load(s)) 00175 return false; 00176 00177 // Check invariants. 00178 PPL_ASSERT(OK(true)); 00179 return true; 00180 }
| void Parma_Polyhedra_Library::Linear_System::assign_with_pending | ( | const Linear_System & | y | ) | [inline] |
Full assignment operator: pending rows are copied as pending.
Definition at line 124 of file Linear_System.inlines.hh.
References index_first_pending, operator=(), row_topology, and sorted.
Referenced by Parma_Polyhedra_Library::Polyhedron::operator=(), and Parma_Polyhedra_Library::Polyhedron::Polyhedron().
00124 { 00125 Matrix::operator=(y); 00126 row_topology = y.row_topology; 00127 index_first_pending = y.index_first_pending; 00128 sorted = y.sorted; 00129 }
| void Parma_Polyhedra_Library::Linear_System::back_substitute | ( | dimension_type | n_lines_or_equalities | ) |
Back-substitutes the coefficients to reduce the complexity of the system.
Takes an upper triangular system having n_lines_or_equalities rows. For each row, starting from the one having the minimum number of coefficients different from zero, computes the expression of an element as a function of the remaining ones and then substitutes this expression in all the other rows.
Definition at line 607 of file Linear_System.cc.
References is_sorted(), Parma_Polyhedra_Library::Linear_Row::linear_combine(), Parma_Polyhedra_Library::neg_assign(), Parma_Polyhedra_Library::Matrix::num_columns(), num_lines_or_equalities(), num_pending_rows(), Parma_Polyhedra_Library::Matrix::num_rows(), OK(), and set_sorted().
Referenced by Parma_Polyhedra_Library::Polyhedron::simplify(), and simplify().
00607 { 00608 Linear_System& x = *this; 00609 // This method is only applied to a well-formed system 00610 // having no pending rows and exactly `n_lines_or_equalities' 00611 // lines or equalities, all of which occur before the first ray 00612 // or point or inequality. 00613 PPL_ASSERT(x.OK(true)); 00614 PPL_ASSERT(x.num_columns() >= 1); 00615 PPL_ASSERT(x.num_pending_rows() == 0); 00616 PPL_ASSERT(n_lines_or_equalities <= x.num_lines_or_equalities()); 00617 #ifndef NDEBUG 00618 for (dimension_type i = n_lines_or_equalities; i-- > 0; ) 00619 PPL_ASSERT(x[i].is_line_or_equality()); 00620 #endif 00621 00622 const dimension_type nrows = x.num_rows(); 00623 const dimension_type ncols = x.num_columns(); 00624 // Trying to keep sortedness. 00625 bool still_sorted = x.is_sorted(); 00626 // This deque of Booleans will be used to flag those rows that, 00627 // before exiting, need to be re-checked for sortedness. 00628 std::deque<bool> check_for_sortedness; 00629 if (still_sorted) 00630 check_for_sortedness.insert(check_for_sortedness.end(), nrows, false); 00631 00632 for (dimension_type k = n_lines_or_equalities; k-- > 0; ) { 00633 // For each line or equality, starting from the last one, 00634 // looks for the last non-zero element. 00635 // `j' will be the index of such a element. 00636 Linear_Row& x_k = x[k]; 00637 dimension_type j = ncols - 1; 00638 while (j != 0 && x_k[j] == 0) 00639 --j; 00640 00641 // Go through the equalities above `x_k'. 00642 for (dimension_type i = k; i-- > 0; ) { 00643 Linear_Row& x_i = x[i]; 00644 if (x_i[j] != 0) { 00645 // Combine linearly `x_i' with `x_k' 00646 // so that `x_i[j]' becomes zero. 00647 x_i.linear_combine(x_k, j); 00648 if (still_sorted) { 00649 // Trying to keep sortedness: remember which rows 00650 // have to be re-checked for sortedness at the end. 00651 if (i > 0) 00652 check_for_sortedness[i-1] = true; 00653 check_for_sortedness[i] = true; 00654 } 00655 } 00656 } 00657 00658 // Due to strong normalization during previous iterations, 00659 // the pivot coefficient `x_k[j]' may now be negative. 00660 // Since an inequality (or ray or point) cannot be multiplied 00661 // by a negative factor, the coefficient of the pivot must be 00662 // forced to be positive. 00663 const bool have_to_negate = (x_k[j] < 0); 00664 if (have_to_negate) 00665 for (dimension_type h = ncols; h-- > 0; ) 00666 PPL::neg_assign(x_k[h]); 00667 // Note: we do not mark index `k' in `check_for_sortedness', 00668 // because we will later negate back the row. 00669 00670 // Go through all the other rows of the system. 00671 for (dimension_type i = n_lines_or_equalities; i < nrows; ++i) { 00672 Linear_Row& x_i = x[i]; 00673 if (x_i[j] != 0) { 00674 // Combine linearly the `x_i' with `x_k' 00675 // so that `x_i[j]' becomes zero. 00676 x_i.linear_combine(x_k, j); 00677 if (still_sorted) { 00678 // Trying to keep sortedness: remember which rows 00679 // have to be re-checked for sortedness at the end. 00680 if (i > n_lines_or_equalities) 00681 check_for_sortedness[i-1] = true; 00682 check_for_sortedness[i] = true; 00683 } 00684 } 00685 } 00686 if (have_to_negate) 00687 // Negate `x_k' to restore strong-normalization. 00688 for (dimension_type h = ncols; h-- > 0; ) 00689 PPL::neg_assign(x_k[h]); 00690 } 00691 00692 // Trying to keep sortedness. 00693 for (dimension_type i = 0; still_sorted && i+1 < nrows; ++i) 00694 if (check_for_sortedness[i]) 00695 // Have to check sortedness of `x[i]' with respect to `x[i+1]'. 00696 still_sorted = (compare(x[i], x[i+1]) <= 0); 00697 // Set the sortedness flag. 00698 x.set_sorted(still_sorted); 00699 00700 // A well-formed system is returned. 00701 PPL_ASSERT(x.OK(true)); 00702 }
| bool Parma_Polyhedra_Library::Linear_System::check_sorted | ( | ) | const |
Returns true if and only if *this is sorted, without checking for duplicates.
Definition at line 839 of file Linear_System.cc.
References first_pending_row().
Referenced by is_sorted(), merge_rows_assign(), Parma_Polyhedra_Library::Polyhedron::obtain_sorted_constraints(), Parma_Polyhedra_Library::Polyhedron::obtain_sorted_constraints_with_sat_c(), Parma_Polyhedra_Library::Polyhedron::obtain_sorted_generators(), Parma_Polyhedra_Library::Polyhedron::obtain_sorted_generators_with_sat_g(), OK(), and sort_and_remove_with_sat().
00839 { 00840 const Linear_System& x = *this; 00841 for (dimension_type i = first_pending_row(); i-- > 1; ) 00842 if (compare(x[i], x[i-1]) < 0) 00843 return false; 00844 return true; 00845 }
| void Parma_Polyhedra_Library::Linear_System::clear | ( | ) | [inline] |
Clears the system deallocating all its rows.
Reimplemented from Parma_Polyhedra_Library::Matrix.
Reimplemented in Parma_Polyhedra_Library::Constraint_System, Parma_Polyhedra_Library::Generator_System, and Parma_Polyhedra_Library::Grid_Generator_System.
Definition at line 140 of file Linear_System.inlines.hh.
References index_first_pending, and sorted.
00140 { 00141 // Note: do NOT modify the value of `row_topology'. 00142 Matrix::clear(); 00143 index_first_pending = 0; 00144 sorted = true; 00145 }
| memory_size_type Parma_Polyhedra_Library::Linear_System::external_memory_in_bytes | ( | ) | const [inline] |
Returns the size in bytes of the memory managed by *this.
Reimplemented from Parma_Polyhedra_Library::Matrix.
Reimplemented in Parma_Polyhedra_Library::Constraint_System, Parma_Polyhedra_Library::Generator_System, and Parma_Polyhedra_Library::Grid_Generator_System.
Definition at line 32 of file Linear_System.inlines.hh.
Referenced by total_memory_in_bytes().
00032 { 00033 return Matrix::external_memory_in_bytes(); 00034 }
| dimension_type Parma_Polyhedra_Library::Linear_System::first_pending_row | ( | ) | const [inline] |
Returns the index of the first pending row.
Definition at line 74 of file Linear_System.inlines.hh.
References index_first_pending.
Referenced by Parma_Polyhedra_Library::Polyhedron::add_and_minimize(), Parma_Polyhedra_Library::Polyhedron::add_space_dimensions(), Parma_Polyhedra_Library::Constraint_System::adjust_topology_and_space_dimension(), ascii_dump(), Parma_Polyhedra_Library::Generator_System::ascii_dump(), Parma_Polyhedra_Library::Constraint_System::ascii_dump(), check_sorted(), Parma_Polyhedra_Library::Polyhedron::constrains(), Parma_Polyhedra_Library::Polyhedron::conversion(), Parma_Polyhedra_Library::Polyhedron::is_universe(), num_pending_rows(), Parma_Polyhedra_Library::Polyhedron::OK(), OK(), operator==(), Parma_Polyhedra_Library::Generator_System::remove_invalid_lines_and_rays(), sort_and_remove_with_sat(), sort_pending_and_remove_duplicates(), sort_rows(), Parma_Polyhedra_Library::Polyhedron::update_sat_c(), and Parma_Polyhedra_Library::Polyhedron::update_sat_g().
00074 { 00075 return index_first_pending; 00076 }
| PPL::dimension_type Parma_Polyhedra_Library::Linear_System::gauss | ( | dimension_type | n_lines_or_equalities | ) |
Minimizes the subsystem of equations contained in *this.
This method works only on the equalities of the system: the system is required to be partially sorted, so that all the equalities are grouped at its top; it is assumed that the number of equalities is exactly n_lines_or_equalities. The method finds a minimal system for the equalities and returns its rank, i.e., the number of linearly independent equalities. The result is an upper triangular subsystem of equalities: for each equality, the pivot is chosen starting from the right-most columns.
Definition at line 555 of file Linear_System.cc.
References Parma_Polyhedra_Library::Matrix::num_columns(), num_lines_or_equalities(), num_pending_rows(), OK(), set_sorted(), and swap().
Referenced by Parma_Polyhedra_Library::Polyhedron::simplify(), and simplify().
00555 { 00556 Linear_System& x = *this; 00557 // This method is only applied to a well-formed linear system 00558 // having no pending rows and exactly `n_lines_or_equalities' 00559 // lines or equalities, all of which occur before the rays or points 00560 // or inequalities. 00561 PPL_ASSERT(x.OK(true)); 00562 PPL_ASSERT(x.num_pending_rows() == 0); 00563 PPL_ASSERT(n_lines_or_equalities == x.num_lines_or_equalities()); 00564 #ifndef NDEBUG 00565 for (dimension_type i = n_lines_or_equalities; i-- > 0; ) 00566 PPL_ASSERT(x[i].is_line_or_equality()); 00567 #endif 00568 00569 dimension_type rank = 0; 00570 // Will keep track of the variations on the system of equalities. 00571 bool changed = false; 00572 for (dimension_type j = x.num_columns(); j-- > 0; ) 00573 for (dimension_type i = rank; i < n_lines_or_equalities; ++i) { 00574 // Search for the first row having a non-zero coefficient 00575 // (the pivot) in the j-th column. 00576 if (x[i][j] == 0) 00577 continue; 00578 // Pivot found: if needed, swap rows so that this one becomes 00579 // the rank-th row in the linear system. 00580 if (i > rank) { 00581 std::swap(x[i], x[rank]); 00582 // After swapping the system is no longer sorted. 00583 changed = true; 00584 } 00585 // Combine the row containing the pivot with all the lines or 00586 // equalities following it, so that all the elements on the j-th 00587 // column in these rows become 0. 00588 for (dimension_type k = i + 1; k < n_lines_or_equalities; ++k) 00589 if (x[k][j] != 0) { 00590 x[k].linear_combine(x[rank], j); 00591 changed = true; 00592 } 00593 // Already dealt with the rank-th row. 00594 ++rank; 00595 // Consider another column index `j'. 00596 break; 00597 } 00598 if (changed) 00599 x.set_sorted(false); 00600 // A well-formed system is returned. 00601 PPL_ASSERT(x.OK(true)); 00602 return rank; 00603 }
| void Parma_Polyhedra_Library::Linear_System::insert | ( | const Linear_Row & | r | ) |
Adds a copy of r to the system, automatically resizing the system or the row's copy, if needed.
Definition at line 183 of file Linear_System.cc.
References add_row(), Parma_Polyhedra_Library::Matrix::add_zero_columns(), Parma_Polyhedra_Library::Linear_Row::check_strong_normalized(), is_necessarily_closed(), Parma_Polyhedra_Library::Matrix::num_columns(), num_pending_rows(), Parma_Polyhedra_Library::Matrix::num_rows(), Parma_Polyhedra_Library::Matrix::OK(), Parma_Polyhedra_Library::Matrix::row_capacity, Parma_Polyhedra_Library::Row::size(), swap(), Parma_Polyhedra_Library::Matrix::swap_columns(), Parma_Polyhedra_Library::Linear_Row::topology(), and topology().
Referenced by Parma_Polyhedra_Library::Generator_System::insert(), and Parma_Polyhedra_Library::Constraint_System::insert().
00183 { 00184 // The added row must be strongly normalized and have the same 00185 // topology of the system. 00186 PPL_ASSERT(r.check_strong_normalized()); 00187 PPL_ASSERT(topology() == r.topology()); 00188 // This method is only used when the system has no pending rows. 00189 PPL_ASSERT(num_pending_rows() == 0); 00190 00191 const dimension_type old_num_rows = num_rows(); 00192 const dimension_type old_num_columns = num_columns(); 00193 const dimension_type r_size = r.size(); 00194 00195 // Resize the system, if necessary. 00196 if (r_size > old_num_columns) { 00197 add_zero_columns(r_size - old_num_columns); 00198 if (!is_necessarily_closed() && old_num_rows != 0) 00199 // Move the epsilon coefficients to the last column 00200 // (note: sorting is preserved). 00201 swap_columns(old_num_columns - 1, r_size - 1); 00202 add_row(r); 00203 } 00204 else if (r_size < old_num_columns) { 00205 // Create a resized copy of the row. 00206 Linear_Row tmp_row(r, old_num_columns, row_capacity); 00207 // If needed, move the epsilon coefficient to the last position. 00208 if (!is_necessarily_closed()) 00209 std::swap(tmp_row[r_size - 1], tmp_row[old_num_columns - 1]); 00210 add_row(tmp_row); 00211 } 00212 else 00213 // Here r_size == old_num_columns. 00214 add_row(r); 00215 00216 // The added row was not a pending row. 00217 PPL_ASSERT(num_pending_rows() == 0); 00218 // Do not check for strong normalization, 00219 // because no modification of rows has occurred. 00220 PPL_ASSERT(OK(false)); 00221 }
| void Parma_Polyhedra_Library::Linear_System::insert_pending | ( | const Linear_Row & | r | ) |
Adds a copy of the given row to the pending part of the system, automatically resizing the system or the row, if needed.
Definition at line 224 of file Linear_System.cc.
References add_pending_row(), Parma_Polyhedra_Library::Matrix::add_zero_columns(), Parma_Polyhedra_Library::Linear_Row::check_strong_normalized(), is_necessarily_closed(), Parma_Polyhedra_Library::Matrix::num_columns(), num_pending_rows(), Parma_Polyhedra_Library::Matrix::num_rows(), Parma_Polyhedra_Library::Matrix::OK(), Parma_Polyhedra_Library::Matrix::row_capacity, Parma_Polyhedra_Library::Row::size(), swap(), Parma_Polyhedra_Library::Matrix::swap_columns(), Parma_Polyhedra_Library::Linear_Row::topology(), and topology().
Referenced by Parma_Polyhedra_Library::Generator_System::insert_pending(), and Parma_Polyhedra_Library::Constraint_System::insert_pending().
00224 { 00225 // The added row must be strongly normalized and have the same 00226 // topology of the system. 00227 PPL_ASSERT(r.check_strong_normalized()); 00228 PPL_ASSERT(topology() == r.topology()); 00229 00230 const dimension_type old_num_rows = num_rows(); 00231 const dimension_type old_num_columns = num_columns(); 00232 const dimension_type r_size = r.size(); 00233 00234 // Resize the system, if necessary. 00235 if (r_size > old_num_columns) { 00236 add_zero_columns(r_size - old_num_columns); 00237 if (!is_necessarily_closed() && old_num_rows != 0) 00238 // Move the epsilon coefficients to the last column 00239 // (note: sorting is preserved). 00240 swap_columns(old_num_columns - 1, r_size - 1); 00241 add_pending_row(r); 00242 } 00243 else if (r_size < old_num_columns) 00244 if (is_necessarily_closed() || old_num_rows == 0) 00245 add_pending_row(Linear_Row(r, old_num_columns, row_capacity)); 00246 else { 00247 // Create a resized copy of the row (and move the epsilon 00248 // coefficient to its last position). 00249 Linear_Row tmp_row(r, old_num_columns, row_capacity); 00250 std::swap(tmp_row[r_size - 1], tmp_row[old_num_columns - 1]); 00251 add_pending_row(tmp_row); 00252 } 00253 else 00254 // Here r_size == old_num_columns. 00255 add_pending_row(r); 00256 00257 // The added row was a pending row. 00258 PPL_ASSERT(num_pending_rows() > 0); 00259 // Do not check for strong normalization, 00260 // because no modification of rows has occurred. 00261 PPL_ASSERT(OK(false)); 00262 }
| bool Parma_Polyhedra_Library::Linear_System::is_necessarily_closed | ( | ) | const [inline] |
Returns true if and only if the system topology is NECESSARILY_CLOSED.
Definition at line 174 of file Linear_System.inlines.hh.
References Parma_Polyhedra_Library::NECESSARILY_CLOSED, and row_topology.
Referenced by Parma_Polyhedra_Library::Polyhedron::add_and_minimize(), Parma_Polyhedra_Library::Generator_System::add_corresponding_closure_points(), Parma_Polyhedra_Library::Generator_System::add_corresponding_points(), Parma_Polyhedra_Library::Constraint_System::add_low_level_constraints(), Parma_Polyhedra_Library::Polyhedron::add_space_dimensions(), ascii_dump(), Parma_Polyhedra_Library::Generator_System::ascii_dump(), Parma_Polyhedra_Library::Constraint_System::ascii_dump(), Parma_Polyhedra_Library::Generator_System::begin(), Parma_Polyhedra_Library::Generator_System::has_closure_points(), Parma_Polyhedra_Library::Generator_System::has_points(), Parma_Polyhedra_Library::Constraint_System::has_strict_inequalities(), insert(), Parma_Polyhedra_Library::Grid_Generator_System::insert(), Parma_Polyhedra_Library::Generator_System::insert(), Parma_Polyhedra_Library::Constraint_System::insert(), insert_pending(), Parma_Polyhedra_Library::Generator_System::insert_pending(), Parma_Polyhedra_Library::Constraint_System::insert_pending(), Parma_Polyhedra_Library::Polyhedron::is_necessarily_closed(), Parma_Polyhedra_Library::Polyhedron::minimize(), OK(), Parma_Polyhedra_Library::Generator_System::const_iterator::operator++(), Parma_Polyhedra_Library::Constraint_System::satisfies_all_constraints(), set_rows_topology(), and space_dimension().
00174 { 00175 return row_topology == NECESSARILY_CLOSED; 00176 }
| bool Parma_Polyhedra_Library::Linear_System::is_sorted | ( | ) | const [inline] |
Returns the value of the sortedness flag.
Definition at line 42 of file Linear_System.inlines.hh.
References check_sorted(), and sorted.
Referenced by Parma_Polyhedra_Library::Polyhedron::add_and_minimize(), add_row(), add_rows(), add_rows_and_columns(), Parma_Polyhedra_Library::Polyhedron::add_space_dimensions(), Parma_Polyhedra_Library::Polyhedron::add_space_dimensions_and_embed(), Parma_Polyhedra_Library::Polyhedron::add_space_dimensions_and_project(), Parma_Polyhedra_Library::Constraint_System::adjust_topology_and_space_dimension(), Parma_Polyhedra_Library::Generator_System::ascii_dump(), Parma_Polyhedra_Library::Constraint_System::ascii_dump(), back_substitute(), Parma_Polyhedra_Library::Polyhedron::conversion(), Parma_Polyhedra_Library::Polyhedron::intersection_assign(), Parma_Polyhedra_Library::Polyhedron::minimize(), Parma_Polyhedra_Library::Constraint_System::num_inequalities(), Parma_Polyhedra_Library::Generator_System::num_lines(), Parma_Polyhedra_Library::Generator_System::num_rays(), Parma_Polyhedra_Library::Polyhedron::obtain_sorted_constraints(), Parma_Polyhedra_Library::Polyhedron::obtain_sorted_constraints_with_sat_c(), Parma_Polyhedra_Library::Polyhedron::obtain_sorted_generators(), Parma_Polyhedra_Library::Polyhedron::obtain_sorted_generators_with_sat_g(), Parma_Polyhedra_Library::Grid_Generator_System::OK(), Parma_Polyhedra_Library::Polyhedron::poly_hull_assign(), Parma_Polyhedra_Library::Polyhedron::process_pending_constraints(), Parma_Polyhedra_Library::Polyhedron::process_pending_generators(), sort_pending_and_remove_duplicates(), and Parma_Polyhedra_Library::Polyhedron::time_elapse_assign().
00042 { 00043 // The flag `sorted' does not really reflect the sortedness status 00044 // of a system (if `sorted' evaluates to `false' nothing is known). 00045 // This assertion is used to ensure that the system 00046 // is actually sorted when `sorted' value is 'true'. 00047 PPL_ASSERT(!sorted || check_sorted()); 00048 return sorted; 00049 }
| dimension_type Parma_Polyhedra_Library::Linear_System::max_space_dimension | ( | ) | [inline, static] |
Returns the maximum space dimension a Linear_System can handle.
Reimplemented in Parma_Polyhedra_Library::Constraint_System, Parma_Polyhedra_Library::Generator_System, and Parma_Polyhedra_Library::Grid_Generator_System.
Definition at line 194 of file Linear_System.inlines.hh.
References Parma_Polyhedra_Library::Matrix::max_num_columns().
00194 { 00195 // Column zero holds the inhomogeneous term or the divisor. 00196 // In NNC linear systems, the last column holds the coefficient 00197 // of the epsilon dimension. 00198 return max_num_columns() - 2; 00199 }
| void Parma_Polyhedra_Library::Linear_System::merge_rows_assign | ( | const Linear_System & | y | ) |
Assigns to *this the result of merging its rows with those of y, obtaining a sorted system.
Duplicated rows will occur only once in the result. On entry, both systems are assumed to be sorted and have no pending rows.
Definition at line 52 of file Linear_System.cc.
References check_sorted(), Parma_Polyhedra_Library::compute_capacity(), Parma_Polyhedra_Library::Matrix::max_num_rows(), num_pending_rows(), Parma_Polyhedra_Library::Matrix::num_rows(), Parma_Polyhedra_Library::Matrix::row_capacity, Parma_Polyhedra_Library::Matrix::row_size, Parma_Polyhedra_Library::Matrix::rows, swap(), and unset_pending_rows().
Referenced by Parma_Polyhedra_Library::Polyhedron::intersection_assign(), Parma_Polyhedra_Library::Polyhedron::poly_hull_assign(), and Parma_Polyhedra_Library::Polyhedron::time_elapse_assign().
00052 { 00053 PPL_ASSERT(row_size >= y.row_size); 00054 // Both systems have to be sorted and have no pending rows. 00055 PPL_ASSERT(check_sorted() && y.check_sorted()); 00056 PPL_ASSERT(num_pending_rows() == 0 && y.num_pending_rows() == 0); 00057 00058 Linear_System& x = *this; 00059 00060 // A temporary vector of rows... 00061 std::vector<Row> tmp; 00062 // ... with enough capacity not to require any reallocations. 00063 tmp.reserve(compute_capacity(x.num_rows() + y.num_rows(), max_num_rows())); 00064 00065 dimension_type xi = 0; 00066 dimension_type x_num_rows = x.num_rows(); 00067 dimension_type yi = 0; 00068 dimension_type y_num_rows = y.num_rows(); 00069 00070 while (xi < x_num_rows && yi < y_num_rows) { 00071 const int comp = compare(x[xi], y[yi]); 00072 if (comp <= 0) { 00073 // Elements that can be taken from `x' are actually _stolen_ from `x' 00074 std::swap(x[xi++], *tmp.insert(tmp.end(), Linear_Row())); 00075 if (comp == 0) 00076 // A duplicate element. 00077 ++yi; 00078 } 00079 else { 00080 // (comp > 0) 00081 Linear_Row copy(y[yi++], row_size, row_capacity); 00082 std::swap(copy, *tmp.insert(tmp.end(), Linear_Row())); 00083 } 00084 } 00085 // Insert what is left. 00086 if (xi < x_num_rows) 00087 while (xi < x_num_rows) 00088 std::swap(x[xi++], *tmp.insert(tmp.end(), Linear_Row())); 00089 else 00090 while (yi < y_num_rows) { 00091 Linear_Row copy(y[yi++], row_size, row_capacity); 00092 std::swap(copy, *tmp.insert(tmp.end(), Linear_Row())); 00093 } 00094 00095 // We get the result vector and let the old one be destroyed. 00096 std::swap(tmp, rows); 00097 // There are no pending rows. 00098 unset_pending_rows(); 00099 PPL_ASSERT(check_sorted()); 00100 }
| void Parma_Polyhedra_Library::Linear_System::normalize | ( | ) |
Normalizes the system by dividing each row for the GCD of the row's elements.
Definition at line 465 of file Linear_System.cc.
References Parma_Polyhedra_Library::Matrix::num_rows(), and set_sorted().
Referenced by Parma_Polyhedra_Library::Generator_System::adjust_topology_and_space_dimension().
00465 { 00466 Linear_System& x = *this; 00467 const dimension_type nrows = x.num_rows(); 00468 // We normalize also the pending rows. 00469 for (dimension_type i = nrows; i-- > 0; ) 00470 x[i].normalize(); 00471 set_sorted(nrows <= 1); 00472 }
| PPL::dimension_type Parma_Polyhedra_Library::Linear_System::num_lines_or_equalities | ( | ) | const |
Returns the number of rows in the system that represent either lines or equalities.
Definition at line 41 of file Linear_System.cc.
References num_pending_rows(), and Parma_Polyhedra_Library::Matrix::num_rows().
Referenced by Parma_Polyhedra_Library::Polyhedron::add_and_minimize(), back_substitute(), and gauss().
00041 { 00042 PPL_ASSERT(num_pending_rows() == 0); 00043 const Linear_System& x = *this; 00044 dimension_type n = 0; 00045 for (dimension_type i = num_rows(); i-- > 0; ) 00046 if (x[i].is_line_or_equality()) 00047 ++n; 00048 return n; 00049 }
| dimension_type Parma_Polyhedra_Library::Linear_System::num_pending_rows | ( | ) | const [inline] |
Returns the number of rows that are in the pending part of the system.
Definition at line 79 of file Linear_System.inlines.hh.
References first_pending_row(), and Parma_Polyhedra_Library::Matrix::num_rows().
Referenced by Parma_Polyhedra_Library::Polyhedron::add_and_minimize(), add_pending_row(), Parma_Polyhedra_Library::Polyhedron::add_recycled_generators(), add_row(), add_rows(), Parma_Polyhedra_Library::Constraint_System::adjust_topology_and_space_dimension(), back_substitute(), gauss(), insert(), Parma_Polyhedra_Library::Grid_Generator_System::insert(), Parma_Polyhedra_Library::Generator_System::insert(), Parma_Polyhedra_Library::Constraint_System::insert(), insert_pending(), Linear_System(), merge_rows_assign(), Parma_Polyhedra_Library::Constraint_System::num_equalities(), Parma_Polyhedra_Library::Constraint_System::num_inequalities(), Parma_Polyhedra_Library::Generator_System::num_lines(), num_lines_or_equalities(), Parma_Polyhedra_Library::Generator_System::num_rays(), Parma_Polyhedra_Library::Polyhedron::OK(), operator=(), Parma_Polyhedra_Library::Polyhedron::Polyhedron(), Parma_Polyhedra_Library::Polyhedron::process_pending_constraints(), Parma_Polyhedra_Library::Polyhedron::process_pending_generators(), Parma_Polyhedra_Library::Generator_System::remove_invalid_lines_and_rays(), Parma_Polyhedra_Library::Polyhedron::simplified_constraints(), simplify(), sort_and_remove_with_sat(), sort_pending_and_remove_duplicates(), and sort_rows().
00079 { 00080 PPL_ASSERT(num_rows() >= first_pending_row()); 00081 return num_rows() - first_pending_row(); 00082 }
| bool Parma_Polyhedra_Library::Linear_System::OK | ( | bool | check_strong_normalized = true |
) | const |
Checks if all the invariants are satisfied.
| check_strong_normalized | true if and only if the strong normalization of all the rows in the system has to be checked. |
By default, the strong normalization check is performed. This check may be turned off to avoid useless repeated checking; e.g., when re-checking a well-formed Linear_System after the permutation or deletion of some of its rows.
Definition at line 848 of file Linear_System.cc.
References check_sorted(), first_pending_row(), Parma_Polyhedra_Library::Matrix::has_no_rows(), is_necessarily_closed(), Parma_Polyhedra_Library::Matrix::num_columns(), Parma_Polyhedra_Library::Matrix::num_rows(), Parma_Polyhedra_Library::Matrix::OK(), Parma_Polyhedra_Library::Matrix::row_capacity, Parma_Polyhedra_Library::Matrix::row_size, sorted, strong_normalize(), and topology().
Referenced by back_substitute(), gauss(), Parma_Polyhedra_Library::Polyhedron::simplify(), and simplify().
00848 { 00849 #ifndef NDEBUG 00850 using std::endl; 00851 using std::cerr; 00852 #endif 00853 00854 // `index_first_pending' must be less than or equal to `num_rows()'. 00855 if (first_pending_row() > num_rows()) { 00856 #ifndef NDEBUG 00857 cerr << "Linear_System has a negative number of pending rows!" 00858 << endl; 00859 #endif 00860 return false; 00861 } 00862 00863 // An empty system is OK, 00864 // unless it is an NNC system with exactly one column. 00865 if (has_no_rows()) { 00866 if (is_necessarily_closed() || num_columns() != 1) 00867 return true; 00868 else { 00869 #ifndef NDEBUG 00870 cerr << "NNC Linear_System has one column" << endl; 00871 #endif 00872 return false; 00873 } 00874 } 00875 00876 // A non-empty system will contain constraints or generators; in 00877 // both cases it must have at least one column for the inhomogeneous 00878 // term and, if it is NNC, another one for the epsilon coefficient. 00879 const dimension_type min_cols = is_necessarily_closed() ? 1 : 2; 00880 if (num_columns() < min_cols) { 00881 #ifndef NDEBUG 00882 cerr << "Linear_System has fewer columns than the minimum " 00883 << "allowed by its topology:" 00884 << endl 00885 << "num_columns is " << num_columns() 00886 << ", minimum is " << min_cols 00887 << endl; 00888 #endif 00889 return false; 00890 } 00891 00892 const Linear_System& x = *this; 00893 const dimension_type n_rows = num_rows(); 00894 for (dimension_type i = 0; i < n_rows; ++i) { 00895 if (!x[i].OK(row_size, row_capacity)) 00896 return false; 00897 // Checking for topology mismatches. 00898 if (x.topology() != x[i].topology()) { 00899 #ifndef NDEBUG 00900 cerr << "Topology mismatch between the system " 00901 << "and one of its rows!" 00902 << endl; 00903 #endif 00904 return false; 00905 } 00906 } 00907 00908 if (check_strong_normalized) { 00909 // Check for strong normalization of rows. 00910 // Note: normalization cannot be checked inside the 00911 // Linear_Row::OK() method, because a Linear_Row object may also 00912 // implement a Linear_Expression object, which in general cannot 00913 // be (strongly) normalized. 00914 Linear_System tmp(x, With_Pending()); 00915 tmp.strong_normalize(); 00916 if (x != tmp) { 00917 #ifndef NDEBUG 00918 cerr << "Linear_System rows are not strongly normalized!" 00919 << endl; 00920 #endif 00921 return false; 00922 } 00923 } 00924 00925 if (sorted && !check_sorted()) { 00926 #ifndef NDEBUG 00927 cerr << "The system declares itself to be sorted but it is not!" 00928 << endl; 00929 #endif 00930 return false; 00931 } 00932 00933 // All checks passed. 00934 return true; 00935 }
| Linear_System & Parma_Polyhedra_Library::Linear_System::operator= | ( | const Linear_System & | y | ) | [inline] |
Assignment operator: pending rows are transformed into non-pending ones.
Definition at line 113 of file Linear_System.inlines.hh.
References num_pending_rows(), row_topology, sorted, and unset_pending_rows().
Referenced by assign_with_pending().
00113 { 00114 Matrix::operator=(y); 00115 row_topology = y.row_topology; 00116 unset_pending_rows(); 00117 // Previously pending rows may violate sortedness. 00118 sorted = (y.num_pending_rows() > 0) ? false : y.sorted; 00119 PPL_ASSERT(num_pending_rows() == 0); 00120 return *this; 00121 }
| const Linear_Row & Parma_Polyhedra_Library::Linear_System::operator[] | ( | dimension_type | k | ) | const [inline] |
Returns a constant reference to the k-th row of the system.
Reimplemented from Parma_Polyhedra_Library::Matrix.
Reimplemented in Parma_Polyhedra_Library::Constraint_System, Parma_Polyhedra_Library::Generator_System, and Parma_Polyhedra_Library::Grid_Generator_System.
Definition at line 184 of file Linear_System.inlines.hh.
References operator[]().
00184 { 00185 return static_cast<const Linear_Row&>(Matrix::operator[](k)); 00186 }
| Linear_Row & Parma_Polyhedra_Library::Linear_System::operator[] | ( | dimension_type | k | ) | [inline] |
Returns a reference to the k-th row of the system.
Reimplemented from Parma_Polyhedra_Library::Matrix.
Reimplemented in Parma_Polyhedra_Library::Constraint_System, Parma_Polyhedra_Library::Generator_System, and Parma_Polyhedra_Library::Grid_Generator_System.
Definition at line 179 of file Linear_System.inlines.hh.
Referenced by operator[]().
00179 { 00180 return static_cast<Linear_Row&>(Matrix::operator[](k)); 00181 }
| void Parma_Polyhedra_Library::Linear_System::permute_columns | ( | const std::vector< dimension_type > & | cycles | ) | [inline] |
Permutes the columns of the system.
Reimplemented from Parma_Polyhedra_Library::Matrix.
Reimplemented in Parma_Polyhedra_Library::Grid_Generator_System.
Definition at line 218 of file Linear_System.inlines.hh.
References sign_normalize().
Referenced by Parma_Polyhedra_Library::Polyhedron::bounded_affine_preimage(), Parma_Polyhedra_Library::Polyhedron::map_space_dimensions(), and Parma_Polyhedra_Library::Grid_Generator_System::permute_columns().
00218 { 00219 Matrix::permute_columns(cycles); 00220 // The rows with permuted columns are still normalized but may 00221 // be not strongly normalized: sign normalization is necessary. 00222 sign_normalize(); 00223 }
| void Parma_Polyhedra_Library::Linear_System::print | ( | ) | const |
Prints *this to std::cerr using operator<<.
Reimplemented from Parma_Polyhedra_Library::Matrix.
Reimplemented in Parma_Polyhedra_Library::Constraint_System, Parma_Polyhedra_Library::Generator_System, and Parma_Polyhedra_Library::Grid_Generator_System.
| void Parma_Polyhedra_Library::Linear_System::remove_trailing_columns | ( | dimension_type | n | ) | [inline] |
Makes the system shrink by removing its n trailing columns.
Reimplemented from Parma_Polyhedra_Library::Matrix.
Definition at line 210 of file Linear_System.inlines.hh.
References strong_normalize().
Referenced by Parma_Polyhedra_Library::Generator_System::adjust_topology_and_space_dimension(), Parma_Polyhedra_Library::Constraint_System::adjust_topology_and_space_dimension(), Parma_Polyhedra_Library::Polyhedron::remove_higher_space_dimensions(), Parma_Polyhedra_Library::Grid_Generator_System::remove_higher_space_dimensions(), Parma_Polyhedra_Library::Polyhedron::remove_space_dimensions(), and Parma_Polyhedra_Library::Grid_Generator_System::remove_space_dimensions().
00210 { 00211 Matrix::remove_trailing_columns(n); 00212 // Have to re-normalize the rows of the system, 00213 // since we removed some coefficients. 00214 strong_normalize(); 00215 }
| void Parma_Polyhedra_Library::Linear_System::resize_no_copy | ( | dimension_type | new_n_rows, | |
| dimension_type | new_n_columns | |||
| ) | [inline] |
Resizes the system without worrying about the old contents.
| new_n_rows | The number of rows of the resized system; | |
| new_n_columns | The number of columns of the resized system. |
The system is expanded to the specified dimensions avoiding reallocation whenever possible. The contents of the original system is lost.
Reimplemented in Parma_Polyhedra_Library::Grid_Generator_System.
Definition at line 148 of file Linear_System.inlines.hh.
References row_topology, and set_sorted().
Referenced by Parma_Polyhedra_Library::Polyhedron::minimize().
00149 { 00150 Matrix::resize_no_copy(new_n_rows, new_n_columns, 00151 Linear_Row::Flags(row_topology)); 00152 // Even though `*this' may happen to keep its sortedness, we believe 00153 // that checking such a property is not worth the effort. In fact, 00154 // it is very likely that the system will be overwritten as soon as 00155 // we return. 00156 set_sorted(false); 00157 }
| void Parma_Polyhedra_Library::Linear_System::set_index_first_pending_row | ( | dimension_type | i | ) | [inline] |
Sets the index of the first pending row to i.
Reimplemented in Parma_Polyhedra_Library::Grid_Generator_System.
Definition at line 90 of file Linear_System.inlines.hh.
References index_first_pending.
Referenced by add_row(), Parma_Polyhedra_Library::Polyhedron::add_space_dimensions(), Parma_Polyhedra_Library::Constraint_System::adjust_topology_and_space_dimension(), Parma_Polyhedra_Library::Polyhedron::minimize(), Parma_Polyhedra_Library::Polyhedron::Polyhedron(), Parma_Polyhedra_Library::Generator_System::remove_invalid_lines_and_rays(), sort_and_remove_with_sat(), and sort_rows().
00090 { 00091 index_first_pending = i; 00092 }
| void Parma_Polyhedra_Library::Linear_System::set_necessarily_closed | ( | ) | [inline] |
Sets the system topology to NECESSARILY_CLOSED.
Definition at line 160 of file Linear_System.inlines.hh.
References Parma_Polyhedra_Library::Matrix::has_no_rows(), Parma_Polyhedra_Library::NECESSARILY_CLOSED, row_topology, and set_rows_topology().
Referenced by Parma_Polyhedra_Library::Generator_System::adjust_topology_and_space_dimension(), Parma_Polyhedra_Library::Constraint_System::adjust_topology_and_space_dimension(), set_rows_topology(), and Parma_Polyhedra_Library::Polyhedron::strongly_minimize_constraints().
00160 { 00161 row_topology = NECESSARILY_CLOSED; 00162 if (!has_no_rows()) 00163 set_rows_topology(); 00164 }
| void Parma_Polyhedra_Library::Linear_System::set_not_necessarily_closed | ( | ) | [inline] |
Sets the system topology to NOT_NECESSARILY_CLOSED.
Definition at line 167 of file Linear_System.inlines.hh.
References Parma_Polyhedra_Library::Matrix::has_no_rows(), Parma_Polyhedra_Library::NOT_NECESSARILY_CLOSED, row_topology, and set_rows_topology().
Referenced by Parma_Polyhedra_Library::Generator_System::adjust_topology_and_space_dimension(), Parma_Polyhedra_Library::Constraint_System::adjust_topology_and_space_dimension(), Parma_Polyhedra_Library::Generator_System::insert(), Parma_Polyhedra_Library::Constraint_System::insert(), Parma_Polyhedra_Library::Generator_System::insert_pending(), Parma_Polyhedra_Library::Constraint_System::insert_pending(), set_rows_topology(), and Parma_Polyhedra_Library::Polyhedron::strongly_minimize_constraints().
00167 { 00168 row_topology = NOT_NECESSARILY_CLOSED; 00169 if (!has_no_rows()) 00170 set_rows_topology(); 00171 }
| void Parma_Polyhedra_Library::Linear_System::set_rows_topology | ( | ) |
Sets the topology of all rows equal to the system topology.
Definition at line 103 of file Linear_System.cc.
References is_necessarily_closed(), Parma_Polyhedra_Library::Matrix::num_rows(), set_necessarily_closed(), and set_not_necessarily_closed().
Referenced by set_necessarily_closed(), and set_not_necessarily_closed().
00103 { 00104 Linear_System& x = *this; 00105 if (is_necessarily_closed()) 00106 for (dimension_type i = num_rows(); i-- > 0; ) 00107 x[i].set_necessarily_closed(); 00108 else 00109 for (dimension_type i = num_rows(); i-- > 0; ) 00110 x[i].set_not_necessarily_closed(); 00111 }
| void Parma_Polyhedra_Library::Linear_System::set_sorted | ( | bool | b | ) | [inline] |
Sets the sortedness flag of the system to b.
Reimplemented in Parma_Polyhedra_Library::Grid_Generator_System.
Definition at line 52 of file Linear_System.inlines.hh.
References sorted.
Referenced by Parma_Polyhedra_Library::Polyhedron::add_recycled_constraints(), Parma_Polyhedra_Library::Polyhedron::add_recycled_generators(), add_row(), add_rows(), add_rows_and_columns(), Parma_Polyhedra_Library::Constraint_System::adjust_topology_and_space_dimension(), back_substitute(), Parma_Polyhedra_Library::Polyhedron::concatenate_assign(), Parma_Polyhedra_Library::Polyhedron::conversion(), Parma_Polyhedra_Library::Polyhedron::drop_some_non_integer_points(), gauss(), Parma_Polyhedra_Library::Polyhedron::generalized_affine_image(), Parma_Polyhedra_Library::Polyhedron::minimize(), normalize(), Parma_Polyhedra_Library::Polyhedron::obtain_sorted_constraints_with_sat_c(), Parma_Polyhedra_Library::Polyhedron::obtain_sorted_generators_with_sat_g(), Parma_Polyhedra_Library::Polyhedron::Polyhedron(), Parma_Polyhedra_Library::Generator_System::remove_invalid_lines_and_rays(), Parma_Polyhedra_Library::Polyhedron::remove_pending_to_obtain_constraints(), Parma_Polyhedra_Library::Polyhedron::remove_pending_to_obtain_generators(), resize_no_copy(), sign_normalize(), Parma_Polyhedra_Library::Polyhedron::simplify(), simplify(), sort_and_remove_with_sat(), strong_normalize(), Parma_Polyhedra_Library::Polyhedron::strongly_minimize_constraints(), Parma_Polyhedra_Library::Polyhedron::strongly_minimize_generators(), and Parma_Polyhedra_Library::Polyhedron::topological_closure_assign().
00052 { 00053 sorted = b; 00054 }
| void Parma_Polyhedra_Library::Linear_System::sign_normalize | ( | ) |
Sign-normalizes the system.
Definition at line 485 of file Linear_System.cc.
References Parma_Polyhedra_Library::Matrix::num_rows(), and set_sorted().
Referenced by permute_columns(), and Parma_Polyhedra_Library::Polyhedron::simplify().
00485 { 00486 Linear_System& x = *this; 00487 const dimension_type nrows = x.num_rows(); 00488 // We sign-normalize also the pending rows. 00489 for (dimension_type i = num_rows(); i-- > 0; ) 00490 x[i].sign_normalize(); 00491 set_sorted(nrows <= 1); 00492 }
| void Parma_Polyhedra_Library::Linear_System::simplify | ( | ) |
Applies Gaussian elimination and back-substitution so as to simplify the linear system.
Reimplemented in Parma_Polyhedra_Library::Constraint_System, and Parma_Polyhedra_Library::Generator_System.
Definition at line 705 of file Linear_System.cc.
References back_substitute(), Parma_Polyhedra_Library::Matrix::erase_to_end(), gauss(), num_pending_rows(), Parma_Polyhedra_Library::Matrix::num_rows(), OK(), set_sorted(), sorted, Parma_Polyhedra_Library::swap(), swap(), and unset_pending_rows().
00705 { 00706 Linear_System& x = *this; 00707 // This method is only applied to a well-formed system 00708 // having no pending rows. 00709 PPL_ASSERT(x.OK(true)); 00710 PPL_ASSERT(x.num_pending_rows() == 0); 00711 00712 // Partially sort the linear system so that all lines/equalities come first. 00713 dimension_type nrows = x.num_rows(); 00714 dimension_type n_lines_or_equalities = 0; 00715 for (dimension_type i = 0; i < nrows; ++i) 00716 if (x[i].is_line_or_equality()) { 00717 if (n_lines_or_equalities < i) { 00718 std::swap(x[i], x[n_lines_or_equalities]); 00719 // The system was not sorted. 00720 PPL_ASSERT(!x.sorted); 00721 } 00722 ++n_lines_or_equalities; 00723 } 00724 // Apply Gaussian elimination to the subsystem of lines/equalities. 00725 const dimension_type rank = x.gauss(n_lines_or_equalities); 00726 // Eliminate any redundant line/equality that has been detected. 00727 if (rank < n_lines_or_equalities) { 00728 const dimension_type 00729 n_rays_or_points_or_inequalities = nrows - n_lines_or_equalities; 00730 const dimension_type 00731 num_swaps = std::min(n_lines_or_equalities - rank, 00732 n_rays_or_points_or_inequalities); 00733 for (dimension_type i = num_swaps; i-- > 0; ) 00734 std::swap(x[--nrows], x[rank + i]); 00735 x.erase_to_end(nrows); 00736 x.unset_pending_rows(); 00737 if (n_rays_or_points_or_inequalities > num_swaps) 00738 x.set_sorted(false); 00739 n_lines_or_equalities = rank; 00740 } 00741 // Apply back-substitution to the system of rays/points/inequalities. 00742 x.back_substitute(n_lines_or_equalities); 00743 // A well-formed system is returned. 00744 PPL_ASSERT(x.OK(true)); 00745 }
| void Parma_Polyhedra_Library::Linear_System::sort_and_remove_with_sat | ( | Bit_Matrix & | sat | ) |
Sorts the system, removing duplicates, keeping the saturation matrix consistent.
| sat | Bit matrix with rows corresponding to the rows of *this. |
Definition at line 515 of file Linear_System.cc.
References check_sorted(), Parma_Polyhedra_Library::Matrix::erase_to_end(), first_pending_row(), num_pending_rows(), Parma_Polyhedra_Library::Matrix::num_rows(), Parma_Polyhedra_Library::Bit_Matrix::num_rows(), Parma_Polyhedra_Library::Matrix::rows, Parma_Polyhedra_Library::Bit_Matrix::rows_erase_to_end(), set_index_first_pending_row(), set_sorted(), and Parma_Polyhedra_Library::swap().
Referenced by Parma_Polyhedra_Library::Polyhedron::obtain_sorted_constraints(), Parma_Polyhedra_Library::Polyhedron::obtain_sorted_constraints_with_sat_c(), Parma_Polyhedra_Library::Polyhedron::obtain_sorted_generators(), and Parma_Polyhedra_Library::Polyhedron::obtain_sorted_generators_with_sat_g().
00515 { 00516 Linear_System& sys = *this; 00517 // We can only sort the non-pending part of the system. 00518 PPL_ASSERT(sys.first_pending_row() == sat.num_rows()); 00519 if (sys.first_pending_row() <= 1) { 00520 sys.set_sorted(true); 00521 return; 00522 } 00523 00524 const dimension_type num_elems = sat.num_rows(); 00525 // Build the function objects implementing indirect sort comparison, 00526 // indirect unique comparison and indirect swap operation. 00527 typedef std::vector<Row> Cont; 00528 Indirect_Sort_Compare<Cont, Row_Less_Than> sort_cmp(rows); 00529 Indirect_Unique_Compare<Cont> unique_cmp(rows); 00530 Indirect_Swapper2<Cont, Bit_Matrix> swapper(rows, sat); 00531 00532 const dimension_type num_duplicates 00533 = indirect_sort_and_unique(num_elems, sort_cmp, unique_cmp, swapper); 00534 00535 const dimension_type new_first_pending_row 00536 = sys.first_pending_row() - num_duplicates; 00537 00538 if (sys.num_pending_rows() > 0) { 00539 // In this case, we must put the duplicates after the pending rows. 00540 const dimension_type n_rows = sys.num_rows() - 1; 00541 for (dimension_type i = 0; i < num_duplicates; ++i) 00542 std::swap(sys[new_first_pending_row + i], sys[n_rows - i]); 00543 } 00544 // Erasing the duplicated rows... 00545 sys.erase_to_end(sys.num_rows() - num_duplicates); 00546 sys.set_index_first_pending_row(new_first_pending_row); 00547 // ... and the corresponding rows of the saturation matrix. 00548 sat.rows_erase_to_end(num_elems - num_duplicates); 00549 PPL_ASSERT(sys.check_sorted()); 00550 // Now the system is sorted. 00551 sys.set_sorted(true); 00552 }
| void Parma_Polyhedra_Library::Linear_System::sort_pending_and_remove_duplicates | ( | ) |
Sorts the pending rows and eliminates those that also occur in the non-pending part of the system.
Definition at line 783 of file Linear_System.cc.
References Parma_Polyhedra_Library::cmp(), Parma_Polyhedra_Library::Matrix::erase_to_end(), first_pending_row(), is_sorted(), num_pending_rows(), Parma_Polyhedra_Library::Matrix::num_rows(), Parma_Polyhedra_Library::Matrix::OK(), sort_rows(), Parma_Polyhedra_Library::swap(), and swap().
Referenced by Parma_Polyhedra_Library::Polyhedron::process_pending_constraints(), and Parma_Polyhedra_Library::Polyhedron::process_pending_generators().
00783 { 00784 PPL_ASSERT(num_pending_rows() > 0); 00785 PPL_ASSERT(is_sorted()); 00786 Linear_System& x = *this; 00787 00788 // The non-pending part of the system is already sorted. 00789 // Now sorting the pending part.. 00790 const dimension_type first_pending = x.first_pending_row(); 00791 x.sort_rows(first_pending, x.num_rows()); 00792 // Recompute the number of rows, because we may have removed 00793 // some rows occurring more than once in the pending part. 00794 dimension_type num_rows = x.num_rows(); 00795 00796 dimension_type k1 = 0; 00797 dimension_type k2 = first_pending; 00798 dimension_type num_duplicates = 0; 00799 // In order to erase them, put at the end of the system 00800 // those pending rows that also occur in the non-pending part. 00801 while (k1 < first_pending && k2 < num_rows) { 00802 const int cmp = compare(x[k1], x[k2]); 00803 if (cmp == 0) { 00804 // We found the same row. 00805 ++num_duplicates; 00806 --num_rows; 00807 // By initial sortedness, we can increment index `k1'. 00808 ++k1; 00809 // Do not increment `k2'; instead, swap there the next pending row. 00810 if (k2 < num_rows) 00811 std::swap(x[k2], x[k2 + num_duplicates]); 00812 } 00813 else if (cmp < 0) 00814 // By initial sortedness, we can increment `k1'. 00815 ++k1; 00816 else { 00817 // Here `cmp > 0'. 00818 // Increment `k2' and, if we already found any duplicate, 00819 // swap the next pending row in position `k2'. 00820 ++k2; 00821 if (num_duplicates > 0 && k2 < num_rows) 00822 std::swap(x[k2], x[k2 + num_duplicates]); 00823 } 00824 } 00825 // If needed, swap any duplicates found past the pending rows 00826 // that has not been considered yet; then erase the duplicates. 00827 if (num_duplicates > 0) { 00828 if (k2 < num_rows) 00829 for (++k2; k2 < num_rows; ++k2) 00830 std::swap(x[k2], x[k2 + num_duplicates]); 00831 x.erase_to_end(num_rows); 00832 } 00833 // Do not check for strong normalization, 00834 // because no modification of rows has occurred. 00835 PPL_ASSERT(OK(false)); 00836 }
| void Parma_Polyhedra_Library::Linear_System::sort_rows | ( | dimension_type | first_row, | |
| dimension_type | last_row | |||
| ) |
Sorts the rows (in growing order) form first_row to last_row and eliminates duplicated ones.
Definition at line 329 of file Linear_System.cc.
References first_pending_row(), Parma_Polyhedra_Library::Matrix::num_rows(), and Parma_Polyhedra_Library::Matrix::rows.
00330 { 00331 PPL_ASSERT(first_row <= last_row && last_row <= num_rows()); 00332 // We cannot mix pending and non-pending rows. 00333 PPL_ASSERT(first_row >= first_pending_row() 00334 || last_row <= first_pending_row()); 00335 00336 const dimension_type num_elems = last_row - first_row; 00337 if (num_elems < 2) 00338 return; 00339 00340 // Build the function objects implementing indirect sort comparison, 00341 // indirect unique comparison and indirect swap operation. 00342 typedef std::vector<Row> Cont; 00343 Indirect_Sort_Compare<Cont, Row_Less_Than> sort_cmp(rows, first_row); 00344 Indirect_Unique_Compare<Cont> unique_cmp(rows, first_row); 00345 Indirect_Swapper<Cont> swapper(rows, first_row); 00346 00347 const dimension_type num_duplicates 00348 = indirect_sort_and_unique(num_elems, sort_cmp, unique_cmp, swapper); 00349 00350 if (num_duplicates > 0) 00351 rows.erase(rows.begin() + (last_row - num_duplicates), 00352 rows.begin() + last_row); 00353 00354 // NOTE: we cannot check all invariants of the system here, 00355 // because the caller still has to update `index_first_pending'. 00356 }
| void Parma_Polyhedra_Library::Linear_System::sort_rows | ( | ) |
Sorts the non-pending rows (in growing order) and eliminates duplicated ones.
Definition at line 317 of file Linear_System.cc.
References first_pending_row(), num_pending_rows(), Parma_Polyhedra_Library::Matrix::num_rows(), Parma_Polyhedra_Library::Matrix::OK(), set_index_first_pending_row(), and sorted.
Referenced by Parma_Polyhedra_Library::Constraint_System::adjust_topology_and_space_dimension(), Parma_Polyhedra_Library::Polyhedron::concatenate_assign(), Parma_Polyhedra_Library::Polyhedron::minimize(), Parma_Polyhedra_Library::Polyhedron::obtain_sorted_constraints(), Parma_Polyhedra_Library::Polyhedron::obtain_sorted_generators(), Parma_Polyhedra_Library::Polyhedron::OK(), sort_pending_and_remove_duplicates(), and Parma_Polyhedra_Library::Polyhedron::time_elapse_assign().
00317 { 00318 const dimension_type num_pending = num_pending_rows(); 00319 // We sort the non-pending rows only. 00320 sort_rows(0, first_pending_row()); 00321 set_index_first_pending_row(num_rows() - num_pending); 00322 sorted = true; 00323 // Do not check for strong normalization, 00324 // because no modification of rows has occurred. 00325 PPL_ASSERT(OK(false)); 00326 }
| dimension_type Parma_Polyhedra_Library::Linear_System::space_dimension | ( | ) | const [inline] |
Returns the space dimension of the rows in the system.
The computation of the space dimension correctly ignores the column encoding the inhomogeneous terms of constraint (resp., the divisors of generators); if the system topology is NOT_NECESSARILY_CLOSED, also the column of the
-dimension coefficients will be ignored.
Reimplemented in Parma_Polyhedra_Library::Constraint_System, Parma_Polyhedra_Library::Generator_System, and Parma_Polyhedra_Library::Grid_Generator_System.
Definition at line 202 of file Linear_System.inlines.hh.
References is_necessarily_closed(), and Parma_Polyhedra_Library::Matrix::num_columns().
00202 { 00203 const dimension_type n_columns = num_columns(); 00204 return (n_columns == 0) 00205 ? 0 00206 : n_columns - (is_necessarily_closed() ? 1 : 2); 00207 }
| void Parma_Polyhedra_Library::Linear_System::strong_normalize | ( | ) |
Strongly normalizes the system.
Definition at line 475 of file Linear_System.cc.
References Parma_Polyhedra_Library::Matrix::num_rows(), and set_sorted().
Referenced by Parma_Polyhedra_Library::Generator_System::affine_image(), Parma_Polyhedra_Library::Constraint_System::affine_preimage(), Parma_Polyhedra_Library::Polyhedron::OK(), OK(), and remove_trailing_columns().
00475 { 00476 Linear_System& x = *this; 00477 const dimension_type nrows = x.num_rows(); 00478 // We strongly normalize also the pending rows. 00479 for (dimension_type i = nrows; i-- > 0; ) 00480 x[i].strong_normalize(); 00481 set_sorted(nrows <= 1); 00482 }
| void Parma_Polyhedra_Library::Linear_System::swap | ( | Linear_System & | y | ) | [inline] |
Swaps *this with y.
Definition at line 132 of file Linear_System.inlines.hh.
References index_first_pending, row_topology, and sorted.
Referenced by add_pending_row(), add_pending_rows(), gauss(), insert(), insert_pending(), merge_rows_assign(), simplify(), sort_pending_and_remove_duplicates(), and swap().
00132 { 00133 Matrix::swap(y); 00134 std::swap(row_topology, y.row_topology); 00135 std::swap(index_first_pending, y.index_first_pending); 00136 std::swap(sorted, y.sorted); 00137 }
| Topology Parma_Polyhedra_Library::Linear_System::topology | ( | ) | const [inline] |
Returns the system topology.
Definition at line 189 of file Linear_System.inlines.hh.
References row_topology.
Referenced by Parma_Polyhedra_Library::Polyhedron::add_space_dimensions(), Parma_Polyhedra_Library::Generator_System::adjust_topology_and_space_dimension(), Parma_Polyhedra_Library::Constraint_System::adjust_topology_and_space_dimension(), Parma_Polyhedra_Library::Polyhedron::BHRZ03_combining_constraints(), Parma_Polyhedra_Library::Polyhedron::conversion(), insert(), Parma_Polyhedra_Library::Grid_Generator_System::insert(), Parma_Polyhedra_Library::Generator_System::insert(), Parma_Polyhedra_Library::Constraint_System::insert(), insert_pending(), Parma_Polyhedra_Library::Generator_System::insert_pending(), Parma_Polyhedra_Library::Constraint_System::insert_pending(), Parma_Polyhedra_Library::Polyhedron::minimize(), Parma_Polyhedra_Library::Polyhedron::OK(), OK(), Parma_Polyhedra_Library::Grid_Generator_System::OK(), Parma_Polyhedra_Library::Polyhedron::select_CH78_constraints(), Parma_Polyhedra_Library::Polyhedron::select_H79_constraints(), and Parma_Polyhedra_Library::Polyhedron::topology().
00189 { 00190 return row_topology; 00191 }
| memory_size_type Parma_Polyhedra_Library::Linear_System::total_memory_in_bytes | ( | ) | const [inline] |
Returns the total size in bytes of the memory occupied by *this.
Reimplemented from Parma_Polyhedra_Library::Matrix.
Reimplemented in Parma_Polyhedra_Library::Constraint_System, Parma_Polyhedra_Library::Generator_System, and Parma_Polyhedra_Library::Grid_Generator_System.
Definition at line 37 of file Linear_System.inlines.hh.
References external_memory_in_bytes().
00037 { 00038 return sizeof(*this) + external_memory_in_bytes(); 00039 }
| void Parma_Polyhedra_Library::Linear_System::unset_pending_rows | ( | ) | [inline] |
Sets the index to indicate that the system has no pending rows.
Reimplemented in Parma_Polyhedra_Library::Grid_Generator_System.
Definition at line 85 of file Linear_System.inlines.hh.
References index_first_pending, and Parma_Polyhedra_Library::Matrix::num_rows().
Referenced by Parma_Polyhedra_Library::Polyhedron::add_recycled_constraints(), Parma_Polyhedra_Library::Polyhedron::add_recycled_generators(), add_rows(), Parma_Polyhedra_Library::Polyhedron::add_space_dimensions_and_embed(), Parma_Polyhedra_Library::Polyhedron::add_space_dimensions_and_project(), Parma_Polyhedra_Library::Constraint_System::adjust_topology_and_space_dimension(), Parma_Polyhedra_Library::Polyhedron::concatenate_assign(), Parma_Polyhedra_Library::Polyhedron::conversion(), Linear_System(), merge_rows_assign(), Parma_Polyhedra_Library::Polyhedron::OK(), operator=(), Parma_Polyhedra_Library::Polyhedron::Polyhedron(), Parma_Polyhedra_Library::Polyhedron::remove_pending_to_obtain_constraints(), Parma_Polyhedra_Library::Polyhedron::remove_pending_to_obtain_generators(), Parma_Polyhedra_Library::Polyhedron::simplified_constraints(), Parma_Polyhedra_Library::Polyhedron::simplify(), simplify(), Parma_Polyhedra_Library::Polyhedron::strongly_minimize_constraints(), Parma_Polyhedra_Library::Polyhedron::strongly_minimize_generators(), Parma_Polyhedra_Library::Polyhedron::time_elapse_assign(), and Parma_Polyhedra_Library::Polyhedron::topological_closure_assign().
00085 { 00086 index_first_pending = num_rows(); 00087 }
| bool operator!= | ( | const Linear_System & | x, | |
| const Linear_System & | y | |||
| ) | [related] |
Returns true if and only if x and y are different.
Definition at line 227 of file Linear_System.inlines.hh.
Referenced by Parma_Polyhedra_Library::Grid_Generator_System::const_iterator::operator!=().
| bool operator== | ( | const Linear_System & | x, | |
| const Linear_System & | y | |||
| ) | [related] |
Returns true if and only if x and y are identical.
Definition at line 496 of file Linear_System.cc.
References first_pending_row(), Parma_Polyhedra_Library::Matrix::num_columns(), and Parma_Polyhedra_Library::Matrix::num_rows().
00496 { 00497 if (x.num_columns() != y.num_columns()) 00498 return false; 00499 const dimension_type x_num_rows = x.num_rows(); 00500 const dimension_type y_num_rows = y.num_rows(); 00501 if (x_num_rows != y_num_rows) 00502 return false; 00503 if (x.first_pending_row() != y.first_pending_row()) 00504 return false; 00505 // Notice that calling operator==(const Matrix&, const Matrix&) 00506 // would be wrong here, as equality of the type fields would 00507 // not be checked. 00508 for (dimension_type i = x_num_rows; i-- > 0; ) 00509 if (x[i] != y[i]) 00510 return false; 00511 return true; 00512 }
| void swap | ( | Parma_Polyhedra_Library::Linear_System & | x, | |
| Parma_Polyhedra_Library::Linear_System & | y | |||
| ) | [related] |
Specializes std::swap.
Definition at line 243 of file Linear_System.inlines.hh.
References swap().
00244 { 00245 x.swap(y); 00246 }
The index of the first pending row.
Definition at line 384 of file Linear_System.defs.hh.
Referenced by assign_with_pending(), clear(), first_pending_row(), set_index_first_pending_row(), swap(), and unset_pending_rows().
The topological kind of the rows in the system.
Definition at line 381 of file Linear_System.defs.hh.
Referenced by add_pending_rows(), add_rows_and_columns(), assign_with_pending(), is_necessarily_closed(), operator=(), resize_no_copy(), set_necessarily_closed(), set_not_necessarily_closed(), swap(), and topology().
bool Parma_Polyhedra_Library::Linear_System::sorted [private] |
true if rows are sorted in the ascending order as defined by bool compare(const Linear_Row&, const Linear_Row&). If false may not be sorted.
Definition at line 391 of file Linear_System.defs.hh.
Referenced by add_pending_rows(), ascii_dump(), assign_with_pending(), clear(), is_sorted(), Linear_System(), OK(), operator=(), set_sorted(), simplify(), sort_rows(), and swap().
1.6.3