Parma_Polyhedra_Library::Linear_System Class Reference
[C++ Language Interface]

The base class for systems of constraints and generators. More...

#include <Linear_System.defs.hh>

Inheritance diagram for Parma_Polyhedra_Library::Linear_System:
Inheritance graph
[legend]
Collaboration diagram for Parma_Polyhedra_Library::Linear_System:
Collaboration graph
[legend]

List of all members.

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_Systemoperator= (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_Rowoperator[] (dimension_type k)
 Returns a reference to the k-th row of the system.
const Linear_Rowoperator[] (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.

Detailed Description

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:

Definition at line 55 of file Linear_System.defs.hh.


Constructor & Destructor Documentation

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 $0$.

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.

Parameters:
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 $\times$ 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 }


Member Function Documentation

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.

Parameters:
n The number of rows and columns to be added: must be strictly positive.

Turns the system $M \in \Rset^r \times \Rset^c$ into the system $N \in \Rset^{r+n} \times \Rset^{c+n}$ such that $N = \bigl(\genfrac{}{}{0pt}{}{0}{M}\genfrac{}{}{0pt}{}{J}{o}\bigr)$, where $J$ is the specular image of the $n \times n$ 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]
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.

Parameters:
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
void Parma_Polyhedra_Library::Linear_System::remove_trailing_columns ( dimension_type  n  )  [inline]
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.

Parameters:
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]
void Parma_Polyhedra_Library::Linear_System::set_necessarily_closed (  )  [inline]
void Parma_Polyhedra_Library::Linear_System::set_not_necessarily_closed (  )  [inline]
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.

Parameters:
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 (  ) 
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 $\epsilon$-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]
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 }


Friends And Related Function Documentation

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!=().

00227                                                            {
00228   return !(x == y);
00229 }

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 }

Specializes std::swap.

Definition at line 243 of file Linear_System.inlines.hh.

References swap().

00244                                               {
00245   x.swap(y);
00246 }


Member Data Documentation

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().

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().


The documentation for this class was generated from the following files:
Generated on Sun Feb 27 16:20:23 2011 for PPL by  doxygen 1.6.3