PPL  1.2
Parma_Polyhedra_Library::Sparse_Row Class Reference

A finite sparse sequence of coefficients. More...

#include <Sparse_Row_defs.hh>

Collaboration diagram for Parma_Polyhedra_Library::Sparse_Row:

Public Types

typedef CO_Tree::iterator iterator
 An iterator on the row elements. More...
 
typedef CO_Tree::const_iterator const_iterator
 A const iterator on the row elements. More...
 

Public Member Functions

 Sparse_Row (dimension_type n=0)
 Constructs a row with the specified size. More...
 
 Sparse_Row (dimension_type n, dimension_type capacity)
 Constructs a row with the specified size. More...
 
 Sparse_Row (const Sparse_Row &y, dimension_type capacity)
 Copy constructor with specified capacity. More...
 
 Sparse_Row (const Sparse_Row &y, dimension_type sz, dimension_type capacity)
 Copy constructor with specified size and capacity. More...
 
 Sparse_Row (const Dense_Row &row)
 Constructor from a Dense_Row. More...
 
 Sparse_Row (const Dense_Row &y, dimension_type sz, dimension_type capacity)
 Copy constructor from a Dense_Row with specified size and capacity. More...
 
Sparse_Rowoperator= (const Dense_Row &row)
 
void m_swap (Sparse_Row &x)
 Swaps *this and x. More...
 
dimension_type size () const
 Returns the size of the row. More...
 
dimension_type num_stored_elements () const
 Returns the number of elements explicitly stored in the row. More...
 
void resize (dimension_type n)
 Resizes the row to the specified size. More...
 
void expand_within_capacity (dimension_type n)
 Resizes the row to size n. More...
 
void shrink (dimension_type n)
 Resizes the row to size n. More...
 
void delete_element_and_shift (dimension_type i)
 Deletes the i-th element from the row, shifting the next elements to the left. More...
 
void add_zeroes_and_shift (dimension_type n, dimension_type i)
 Adds n zeroes before index i. More...
 
iterator begin ()
 Returns an iterator that points at the first stored element. More...
 
const iteratorend ()
 Returns an iterator that points after the last stored element. More...
 
const_iterator begin () const
 Equivalent to cbegin(). More...
 
const const_iteratorend () const
 Equivalent to cend(). More...
 
const_iterator cbegin () const
 Returns an iterator that points at the first element. More...
 
const const_iteratorcend () const
 Returns an iterator that points after the last element. More...
 
void clear ()
 Resets all the elements of this row. More...
 
Coefficientoperator[] (dimension_type i)
 Gets a reference to the i-th element. More...
 
Coefficient_traits::const_reference operator[] (dimension_type i) const
 Equivalent to get(i), provided for convenience. More...
 
Coefficient_traits::const_reference get (dimension_type i) const
 Gets the i-th element in the sequence. More...
 
iterator find (dimension_type i)
 Looks for an element with index i. More...
 
iterator find (iterator itr, dimension_type i)
 Looks for an element with index i. More...
 
const_iterator find (dimension_type i) const
 Looks for an element with index i. More...
 
const_iterator find (const_iterator itr, dimension_type i) const
 Looks for an element with index i. More...
 
iterator lower_bound (dimension_type i)
 Lower bound of index i. More...
 
iterator lower_bound (iterator itr, dimension_type i)
 Lower bound of index i. More...
 
const_iterator lower_bound (dimension_type i) const
 Lower bound of index i. More...
 
const_iterator lower_bound (const_iterator itr, dimension_type i) const
 Lower bound of index i. More...
 
iterator insert (dimension_type i, Coefficient_traits::const_reference x)
 Equivalent to (*this)[i] = x; find(i), but faster. More...
 
iterator insert (iterator itr, dimension_type i, Coefficient_traits::const_reference x)
 Equivalent to (*this)[i] = x; find(i), but faster. More...
 
iterator insert (dimension_type i)
 Equivalent to (*this)[i]; find(i), but faster. More...
 
iterator insert (iterator itr, dimension_type i)
 Equivalent to (*this)[i]; find(i), but faster. More...
 
void swap_coefficients (dimension_type i, dimension_type j)
 Swaps the i-th element with the j-th element. More...
 
void fast_swap (dimension_type i, iterator itr)
 
void swap_coefficients (iterator i, iterator j)
 Swaps the element pointed to by i with the element pointed to by j. More...
 
iterator reset (iterator i)
 Resets to zero the value pointed to by i. More...
 
iterator reset (iterator first, iterator last)
 Resets to zero the values in the range [first,last). More...
 
void reset (dimension_type i)
 Resets to zero the i-th element. More...
 
void reset_after (dimension_type i)
 Resets to zero the elements with index greater than or equal to i. More...
 
void normalize ()
 Normalizes the modulo of coefficients so that they are mutually prime. More...
 
template<typename Func1 , typename Func2 >
void combine_needs_first (const Sparse_Row &y, const Func1 &f, const Func2 &g)
 Calls g(x[i],y[i]), for each i. More...
 
template<typename Func1 , typename Func2 >
void combine_needs_second (const Sparse_Row &y, const Func1 &g, const Func2 &h)
 Calls g(x[i],y[i]), for each i. More...
 
template<typename Func1 , typename Func2 , typename Func3 >
void combine (const Sparse_Row &y, const Func1 &f, const Func2 &g, const Func3 &h)
 Calls g(x[i],y[i]), for each i. More...
 
void linear_combine (const Sparse_Row &y, Coefficient_traits::const_reference coeff1, Coefficient_traits::const_reference coeff2)
 
void linear_combine (const Sparse_Row &y, Coefficient_traits::const_reference c1, Coefficient_traits::const_reference c2, dimension_type start, dimension_type end)
 
void ascii_dump () const
 Writes to std::cerr an ASCII representation of *this. More...
 
void ascii_dump (std::ostream &s) const
 Writes to s an ASCII representation of *this. More...
 
void print () const
 Prints *this to std::cerr using operator<<. More...
 
bool ascii_load (std::istream &s)
 Loads the row from an ASCII representation generated using ascii_dump(). More...
 
memory_size_type external_memory_in_bytes () const
 Returns the size in bytes of the memory managed by *this. More...
 
memory_size_type external_memory_in_bytes (dimension_type capacity) const
 Returns the size in bytes of the memory managed by *this. More...
 
memory_size_type total_memory_in_bytes () const
 Returns the size in bytes of the memory managed by *this. More...
 
memory_size_type total_memory_in_bytes (dimension_type capacity) const
 Returns the size in bytes of the memory managed by *this. More...
 
bool OK () const
 Checks the invariant. More...
 
bool OK (dimension_type capacity) const
 Checks the invariant. More...
 

Static Public Member Functions

static dimension_type max_size ()
 Returns the size() of the largest possible Sparse_Row. More...
 

Private Attributes

CO_Tree tree
 The tree used to store the elements. More...
 
dimension_type size_
 The size of the row. More...
 

Related Functions

(Note that these are not member functions.)

bool operator== (const Sparse_Row &x, const Sparse_Row &y)
 
bool operator!= (const Sparse_Row &x, const Sparse_Row &y)
 
void swap (Parma_Polyhedra_Library::Sparse_Row &x, Parma_Polyhedra_Library::Sparse_Row &y)
 Swaps x with y. More...
 
bool operator== (const Sparse_Row &x, const Sparse_Row &y)
 Returns true if and only if x and y are equal. More...
 
bool operator!= (const Sparse_Row &x, const Sparse_Row &y)
 Returns true if and only if x and y are different. More...
 
void linear_combine (Sparse_Row &x, const Dense_Row &y, Coefficient_traits::const_reference coeff1, Coefficient_traits::const_reference coeff2)
 
void linear_combine (Sparse_Row &x, const Dense_Row &y, Coefficient_traits::const_reference c1, Coefficient_traits::const_reference c2, dimension_type start, dimension_type end)
 
void linear_combine (Dense_Row &x, const Sparse_Row &y, Coefficient_traits::const_reference coeff1, Coefficient_traits::const_reference coeff2)
 
void linear_combine (Dense_Row &x, const Sparse_Row &y, Coefficient_traits::const_reference c1, Coefficient_traits::const_reference c2, dimension_type start, dimension_type end)
 
void linear_combine (Sparse_Row &x, const Sparse_Row &y, Coefficient_traits::const_reference coeff1, Coefficient_traits::const_reference coeff2)
 
void linear_combine (Sparse_Row &x, const Sparse_Row &y, Coefficient_traits::const_reference c1, Coefficient_traits::const_reference c2, dimension_type start, dimension_type end)
 
void swap (Sparse_Row &x, Sparse_Row &y)
 

Detailed Description

A finite sparse sequence of coefficients.

This class is implemented using a CO_Tree. See the documentation of CO_Tree for details on the implementation and the performance.

This class is a drop-in replacement of Dense_Row, meaning that code using Dense_Row can be ported to Sparse_Row changing only the type. The resulting code will work, but probably needs more CPU and memory (it does not exploit the sparse representation yet).

To take advantage of the sparse representation, the client code must then be modified to use methods which can have a faster implementation on sparse data structures.

The main changes are the replacement of calls to operator[] with calls to find(), lower_bound() or insert(), using hint iterators when possible. Sequential scanning of rows should probably be implemented using iterators rather than indexes, to improve performance. reset() should be called to zero elements.

See also
Sparse_Matrix
CO_Tree

Definition at line 58 of file Sparse_Row_defs.hh.

Member Typedef Documentation

A const iterator on the row elements.

This iterator skips non-stored zeroes.

See also
CO_Tree::const_iterator

Definition at line 74 of file Sparse_Row_defs.hh.

An iterator on the row elements.

This iterator skips non-stored zeroes.

See also
CO_Tree::iterator

Definition at line 67 of file Sparse_Row_defs.hh.

Constructor & Destructor Documentation

Parma_Polyhedra_Library::Sparse_Row::Sparse_Row ( dimension_type  n = 0)
inlineexplicit

Constructs a row with the specified size.

Parameters
nThe size for the new row.

The row will contain only non-stored zeroes.

This constructor takes $O(1)$ time.

Definition at line 32 of file Sparse_Row_inlines.hh.

References OK().

33  : size_(n) {
34  PPL_ASSERT(OK());
35 }
dimension_type size_
The size of the row.
bool OK() const
Checks the invariant.
Definition: Sparse_Row.cc:742
Parma_Polyhedra_Library::Sparse_Row::Sparse_Row ( dimension_type  n,
dimension_type  capacity 
)
inline

Constructs a row with the specified size.

Parameters
nThe size for the new row.
capacityIt is ignored. This parameter is needed for compatibility with Dense_Row.

The row will contain only non-stored zeroes.

This constructor takes $O(1)$ time.

Definition at line 38 of file Sparse_Row_inlines.hh.

References OK().

39  : size_(n) {
40  PPL_ASSERT(OK());
41 }
dimension_type size_
The size of the row.
bool OK() const
Checks the invariant.
Definition: Sparse_Row.cc:742
Parma_Polyhedra_Library::Sparse_Row::Sparse_Row ( const Sparse_Row y,
dimension_type  capacity 
)
inline

Copy constructor with specified capacity.

It is assumed that capacity is greater than or equal to the size of y.

Definition at line 44 of file Sparse_Row_inlines.hh.

45  : tree(y.tree), size_(y.size_) {
46 }
CO_Tree tree
The tree used to store the elements.
dimension_type size_
The size of the row.
Parma_Polyhedra_Library::Sparse_Row::Sparse_Row ( const Sparse_Row y,
dimension_type  sz,
dimension_type  capacity 
)
inline

Copy constructor with specified size and capacity.

It is assumed that sz is less than or equal to capacity.

Definition at line 49 of file Sparse_Row_inlines.hh.

References OK().

50  : tree(y.begin(),
51  std::distance(y.begin(), y.lower_bound(std::min(y.size(), sz)))),
52  size_(sz) {
53  PPL_ASSERT(OK());
54 }
CO_Tree tree
The tree used to store the elements.
dimension_type size_
The size of the row.
bool OK() const
Checks the invariant.
Definition: Sparse_Row.cc:742
Parma_Polyhedra_Library::Sparse_Row::Sparse_Row ( const Dense_Row row)
explicit

Constructor from a Dense_Row.

Parameters
rowThe row that will be copied into *this.

This constructor takes $O(n)$ time. Note that constructing of a row of zeroes and then inserting n elements costs $O(n*\log^2 n)$ time.

Definition at line 101 of file Sparse_Row.cc.

References OK().

102  : tree(Sparse_Row_from_Dense_Row_helper_iterator(row, row.size()),
103  Sparse_Row_from_Dense_Row_helper_function(row, row.size())),
104  size_(row.size()) {
105  PPL_ASSERT(OK());
106 }
CO_Tree tree
The tree used to store the elements.
dimension_type size_
The size of the row.
bool OK() const
Checks the invariant.
Definition: Sparse_Row.cc:742
Parma_Polyhedra_Library::Sparse_Row::Sparse_Row ( const Dense_Row y,
dimension_type  sz,
dimension_type  capacity 
)

Copy constructor from a Dense_Row with specified size and capacity.

It is assumed that sz is less than or equal to capacity.

Definition at line 108 of file Sparse_Row.cc.

References OK().

110  : tree(Sparse_Row_from_Dense_Row_helper_iterator(row, row.size()),
111  Sparse_Row_from_Dense_Row_helper_function(row, row.size())),
112  size_(sz) {
113  (void)capacity;
114  PPL_ASSERT(OK());
115 }
CO_Tree tree
The tree used to store the elements.
dimension_type size_
The size of the row.
bool OK() const
Checks the invariant.
Definition: Sparse_Row.cc:742

Member Function Documentation

void Parma_Polyhedra_Library::Sparse_Row::add_zeroes_and_shift ( dimension_type  n,
dimension_type  i 
)
inline

Adds n zeroes before index i.

Parameters
nThe number of non-stored zeroes that will be added to the row.
iThe index of the element before which the zeroes will be added.

Existing elements with index greater than or equal to i are shifted to the right by n positions. The size is increased by n.

Existing iterators are not invalidated, but are shifted to the right by n if they pointed at or after index i (i.e., they point to the same, possibly shifted, values as before).

This method takes $O(k + \log m)$ expected time, where $k$ is the number of elements with index greater than or equal to i and $m$ the number of stored elements.

Definition at line 105 of file Sparse_Row_inlines.hh.

References Parma_Polyhedra_Library::CO_Tree::increase_keys_from(), OK(), size_, and tree.

105  {
106  PPL_ASSERT(i <= size_);
107  tree.increase_keys_from(i, n);
108  size_ += n;
109  PPL_ASSERT(OK());
110 }
void increase_keys_from(dimension_type key, dimension_type n)
Adds n to all keys greater than or equal to key.
Definition: CO_Tree.cc:196
CO_Tree tree
The tree used to store the elements.
dimension_type size_
The size of the row.
bool OK() const
Checks the invariant.
Definition: Sparse_Row.cc:742
void Parma_Polyhedra_Library::Sparse_Row::ascii_dump ( ) const

Writes to std::cerr an ASCII representation of *this.

void Parma_Polyhedra_Library::Sparse_Row::ascii_dump ( std::ostream &  s) const

Writes to s an ASCII representation of *this.

Definition at line 685 of file Sparse_Row.cc.

685  {
686  s << "size " << size_ << ' ';
687  dimension_type n_elements = 0;
688  for (const_iterator i = begin(), i_end = end(); i != i_end; ++i) {
689  ++n_elements;
690  }
691  s << "elements " << n_elements << ' ';
692  for (const_iterator i = begin(), i_end = end(); i != i_end; ++i) {
693  s << "[ " << i.index() << " ]= " << *i << ' ';
694  }
695  s << "\n";
696 }
size_t dimension_type
An unsigned integral type for representing space dimensions.
const iterator & end()
Returns an iterator that points after the last stored element.
dimension_type size_
The size of the row.
iterator begin()
Returns an iterator that points at the first stored element.
CO_Tree::const_iterator const_iterator
A const iterator on the row elements.
bool Parma_Polyhedra_Library::Sparse_Row::ascii_load ( std::istream &  s)

Loads the row from an ASCII representation generated using ascii_dump().

Parameters
sThe stream from which the ASCII representation will be loaded.

Definition at line 701 of file Sparse_Row.cc.

References PPL_DIRTY_TEMP_COEFFICIENT.

701  {
702  std::string str;
703  if (!(s >> str) || str != "size") {
704  return false;
705  }
706  if (!(s >> size_)) {
707  return false;
708  }
709  clear();
710 
711  if (!(s >> str) || str != "elements") {
712  return false;
713  }
714 
715  dimension_type n_elements;
716  if (!(s >> n_elements)) {
717  return false;
718  }
719 
720  PPL_DIRTY_TEMP_COEFFICIENT(current_data);
721  for (dimension_type i = 0; i < n_elements; ++i) {
722  dimension_type current_key;
723  if (!(s >> str) || str != "[") {
724  return false;
725  }
726  if (!(s >> current_key)) {
727  return false;
728  }
729  if (!(s >> str) || str != "]=") {
730  return false;
731  }
732  if (!(s >> current_data)) {
733  return false;
734  }
735  tree.insert(current_key, current_data);
736  }
737  PPL_ASSERT(OK());
738  return true;
739 }
size_t dimension_type
An unsigned integral type for representing space dimensions.
#define PPL_DIRTY_TEMP_COEFFICIENT(id)
Declare a local variable named id, of type Coefficient, and containing an unknown initial value...
iterator insert(dimension_type key)
Inserts an element in the tree.
void clear()
Resets all the elements of this row.
CO_Tree tree
The tree used to store the elements.
dimension_type size_
The size of the row.
bool OK() const
Checks the invariant.
Definition: Sparse_Row.cc:742
Sparse_Row::iterator Parma_Polyhedra_Library::Sparse_Row::begin ( )
inline

Returns an iterator that points at the first stored element.

This method takes $O(1)$ time.

Definition at line 113 of file Sparse_Row_inlines.hh.

References Parma_Polyhedra_Library::CO_Tree::begin(), and tree.

Referenced by Parma_Polyhedra_Library::PIP_Tree_Node::add_constraint(), combine(), combine_needs_first(), combine_needs_second(), Parma_Polyhedra_Library::PIP_Tree_Node::compatibility_check(), Parma_Polyhedra_Library::Dense_Row::Dense_Row(), Parma_Polyhedra_Library::MIP_Problem::erase_artificials(), Parma_Polyhedra_Library::PIP_Solution_Node::generate_cut(), Parma_Polyhedra_Library::Dense_Row::init(), Parma_Polyhedra_Library::PIP_Solution_Node::Tableau::is_better_pivot(), linear_combine(), Parma_Polyhedra_Library::PIP_Solution_Node::Tableau::normalize(), Parma_Polyhedra_Library::MIP_Problem::OK(), Parma_Polyhedra_Library::Dense_Row::operator=(), operator==(), Parma_Polyhedra_Library::MIP_Problem::process_pending_constraints(), Parma_Polyhedra_Library::PIP_Solution_Node::row_sign(), Parma_Polyhedra_Library::PIP_Solution_Node::Tableau::scale(), Parma_Polyhedra_Library::MIP_Problem::second_phase(), Parma_Polyhedra_Library::PIP_Problem::solve(), Parma_Polyhedra_Library::PIP_Solution_Node::solve(), Parma_Polyhedra_Library::MIP_Problem::steepest_edge_exact_entering_index(), Parma_Polyhedra_Library::MIP_Problem::steepest_edge_float_entering_index(), Parma_Polyhedra_Library::swap(), and Parma_Polyhedra_Library::PIP_Solution_Node::update_solution().

113  {
114  return tree.begin();
115 }
iterator begin()
Returns an iterator that points at the first element.
CO_Tree tree
The tree used to store the elements.
Sparse_Row::const_iterator Parma_Polyhedra_Library::Sparse_Row::begin ( ) const
inline

Equivalent to cbegin().

Definition at line 123 of file Sparse_Row_inlines.hh.

References Parma_Polyhedra_Library::CO_Tree::cbegin(), and tree.

123  {
124  return tree.cbegin();
125 }
const_iterator cbegin() const
Returns a const_iterator that points at the first element.
CO_Tree tree
The tree used to store the elements.
Sparse_Row::const_iterator Parma_Polyhedra_Library::Sparse_Row::cbegin ( ) const
inline

Returns an iterator that points at the first element.

This method takes $O(1)$ time.

Definition at line 133 of file Sparse_Row_inlines.hh.

References Parma_Polyhedra_Library::CO_Tree::cbegin(), and tree.

133  {
134  return tree.cbegin();
135 }
const_iterator cbegin() const
Returns a const_iterator that points at the first element.
CO_Tree tree
The tree used to store the elements.
const Sparse_Row::const_iterator & Parma_Polyhedra_Library::Sparse_Row::cend ( ) const
inline

Returns an iterator that points after the last element.

This method always returns a reference to the same internal iterator, that is updated at each operation that modifies the structure. Client code can keep a const reference to that iterator instead of keep updating a local iterator.

This method takes $O(1)$ time.

Definition at line 138 of file Sparse_Row_inlines.hh.

References Parma_Polyhedra_Library::CO_Tree::cend(), and tree.

138  {
139  return tree.cend();
140 }
const const_iterator & cend() const
Returns a const_iterator that points after the last element.
CO_Tree tree
The tree used to store the elements.
void Parma_Polyhedra_Library::Sparse_Row::clear ( )
inline

Resets all the elements of this row.

This method takes $O(n)$ time.

Definition at line 148 of file Sparse_Row_inlines.hh.

References Parma_Polyhedra_Library::CO_Tree::clear(), and tree.

148  {
149  tree.clear();
150 }
CO_Tree tree
The tree used to store the elements.
void clear()
Removes all elements from the tree.
template<typename Func1 , typename Func2 , typename Func3 >
void Parma_Polyhedra_Library::Sparse_Row::combine ( const Sparse_Row y,
const Func1 &  f,
const Func2 &  g,
const Func3 &  h 
)

Calls g(x[i],y[i]), for each i.

Parameters
yThe row that will be combined with *this.
fA functor that should take a Coefficient&. f(c1) must be equivalent to g(c1, 0).
gA functor that should take a Coefficient& and a Coefficient_traits::const_reference. g(c1, c2) must do nothing when both c1 and c2 are zero.
hA functor that should take a Coefficient& and a Coefficient_traits::const_reference. h(c1, c2) must be equivalent to g(c1, c2) when c1 is zero.

This method takes $O(n*\log^2 n)$ time.

Note
The functors will only be called when necessary, assuming the requested properties hold.
See also
combine_needs_first
combine_needs_second

Definition at line 101 of file Sparse_Row_templates.hh.

References begin(), end(), Parma_Polyhedra_Library::CO_Tree::const_iterator::index(), Parma_Polyhedra_Library::CO_Tree::iterator::index(), insert(), and reset().

102  {
103  if (this == &y) {
104  for (iterator i = begin(), i_end = end(); i != i_end; ++i) {
105  g(*i, *i);
106  }
107  }
108  else {
109  iterator i = begin();
110  // This is a const reference to an internal iterator, that is kept valid.
111  // If we just stored a copy, that would be invalidated by the calls to
112  // reset() and insert().
113  const iterator& i_end = end();
114  const_iterator j = y.begin();
115  const_iterator j_end = y.end();
116  while (i != i_end && j != j_end) {
117  if (i.index() == j.index()) {
118  g(*i, *j);
119  if (*i == 0) {
120  i = reset(i);
121  }
122  else {
123  ++i;
124  }
125  ++j;
126  }
127  else
128  if (i.index() < j.index()) {
129  f(*i);
130  if (*i == 0) {
131  i = reset(i);
132  }
133  else {
134  ++i;
135  }
136  }
137  else {
138  PPL_ASSERT(i.index() > j.index());
139  i = insert(i, j.index());
140  h(*i, *j);
141  if (*i == 0) {
142  i = reset(i);
143  }
144  else {
145  ++i;
146  }
147  ++j;
148  }
149  }
150  PPL_ASSERT(i == i_end || j == j_end);
151  while (i != i_end) {
152  f(*i);
153  if (*i == 0) {
154  i = reset(i);
155  }
156  else {
157  ++i;
158  }
159  }
160  while (j != j_end) {
161  i = insert(i, j.index());
162  h(*i, *j);
163  if (*i == 0) {
164  i = reset(i);
165  }
166  ++j;
167  }
168  }
169 }
iterator reset(iterator i)
Resets to zero the value pointed to by i.
CO_Tree::iterator iterator
An iterator on the row elements.
const iterator & end()
Returns an iterator that points after the last stored element.
iterator insert(dimension_type i, Coefficient_traits::const_reference x)
Equivalent to (*this)[i] = x; find(i), but faster.
iterator begin()
Returns an iterator that points at the first stored element.
CO_Tree::const_iterator const_iterator
A const iterator on the row elements.
template<typename Func1 , typename Func2 >
void Parma_Polyhedra_Library::Sparse_Row::combine_needs_first ( const Sparse_Row y,
const Func1 &  f,
const Func2 &  g 
)

Calls g(x[i],y[i]), for each i.

Parameters
yThe row that will be combined with *this.
fA functor that should take a Coefficient&. f(c1) must be equivalent to g(c1, 0).
gA functor that should take a Coefficient& and a Coefficient_traits::const_reference. g(c1, c2) must do nothing when c1 is zero.

This method takes $O(n*\log^2 n)$ time.

Note
The functors will only be called when necessary, assuming the requested properties hold.
See also
combine_needs_second
combine

Definition at line 32 of file Sparse_Row_templates.hh.

References begin(), end(), Parma_Polyhedra_Library::CO_Tree::const_iterator::index(), Parma_Polyhedra_Library::CO_Tree::iterator::index(), lower_bound(), and reset().

33  {
34  if (this == &y) {
35  for (iterator i = begin(), i_end = end(); i != i_end; ++i) {
36  g(*i, *i);
37  }
38  }
39  else {
40  iterator i = begin();
41  // This is a const reference to an internal iterator, that is kept valid.
42  // If we just stored a copy, that would be invalidated by the calls to
43  // reset().
44  const iterator& i_end = end();
45  const_iterator j = y.begin();
46  const_iterator j_end = y.end();
47  while (i != i_end && j != j_end) {
48  if (i.index() == j.index()) {
49  g(*i, *j);
50  if (*i == 0) {
51  i = reset(i);
52  }
53  else {
54  ++i;
55  }
56  ++j;
57  }
58  else
59  if (i.index() < j.index()) {
60  f(*i);
61  if (*i == 0) {
62  i = reset(i);
63  }
64  else {
65  ++i;
66  }
67  }
68  else {
69  j = y.lower_bound(j, i.index());
70  }
71  }
72  while (i != i_end) {
73  f(*i);
74  if (*i == 0) {
75  i = reset(i);
76  }
77  else {
78  ++i;
79  }
80  }
81  }
82 }
iterator reset(iterator i)
Resets to zero the value pointed to by i.
CO_Tree::iterator iterator
An iterator on the row elements.
const iterator & end()
Returns an iterator that points after the last stored element.
iterator begin()
Returns an iterator that points at the first stored element.
CO_Tree::const_iterator const_iterator
A const iterator on the row elements.
template<typename Func1 , typename Func2 >
void Parma_Polyhedra_Library::Sparse_Row::combine_needs_second ( const Sparse_Row y,
const Func1 &  g,
const Func2 &  h 
)

Calls g(x[i],y[i]), for each i.

Parameters
yThe row that will be combined with *this.
gA functor that should take a Coefficient& and a Coefficient_traits::const_reference. g(c1, 0) must do nothing, for every c1.
hA functor that should take a Coefficient& and a Coefficient_traits::const_reference. h(c1, c2) must be equivalent to g(c1, c2) when c1 is zero.

This method takes $O(n*\log^2 n)$ time.

Note
The functors will only be called when necessary, assuming the requested properties hold.
See also
combine_needs_first
combine

Definition at line 86 of file Sparse_Row_templates.hh.

References begin(), end(), Parma_Polyhedra_Library::CO_Tree::iterator::index(), insert(), and reset().

88  {
89  iterator i = begin();
90  for (const_iterator j = y.begin(), j_end = y.end(); j != j_end; ++j) {
91  i = insert(i, j.index());
92  g(*i, *j);
93  if (*i == 0) {
94  i = reset(i);
95  }
96  }
97 }
iterator reset(iterator i)
Resets to zero the value pointed to by i.
CO_Tree::iterator iterator
An iterator on the row elements.
iterator insert(dimension_type i, Coefficient_traits::const_reference x)
Equivalent to (*this)[i] = x; find(i), but faster.
iterator begin()
Returns an iterator that points at the first stored element.
CO_Tree::const_iterator const_iterator
A const iterator on the row elements.
void Parma_Polyhedra_Library::Sparse_Row::delete_element_and_shift ( dimension_type  i)
inline

Deletes the i-th element from the row, shifting the next elements to the left.

Parameters
iThe index of the element that will be deleted.

The size of the row is decreased by 1.

This operation invalidates existing iterators.

This method takes $O(k+\log^2 n)$ amortized time, where k is the number of elements with index greater than i.

Definition at line 97 of file Sparse_Row_inlines.hh.

References Parma_Polyhedra_Library::CO_Tree::erase_element_and_shift_left(), OK(), size_, and tree.

97  {
98  PPL_ASSERT(i < size_);
100  --size_;
101  PPL_ASSERT(OK());
102 }
CO_Tree tree
The tree used to store the elements.
dimension_type size_
The size of the row.
void erase_element_and_shift_left(dimension_type key)
Removes the element with key key (if it exists) and decrements by 1 all elements' keys that were grea...
Definition: CO_Tree.cc:179
bool OK() const
Checks the invariant.
Definition: Sparse_Row.cc:742
const Sparse_Row::iterator & Parma_Polyhedra_Library::Sparse_Row::end ( )
inline

Returns an iterator that points after the last stored element.

This method always returns a reference to the same internal iterator, that is kept valid. Client code can keep a const reference to that iterator instead of keep updating a local iterator.

This method takes $O(1)$ time.

Definition at line 118 of file Sparse_Row_inlines.hh.

References Parma_Polyhedra_Library::CO_Tree::end(), and tree.

Referenced by Parma_Polyhedra_Library::PIP_Tree_Node::add_constraint(), combine(), combine_needs_first(), combine_needs_second(), Parma_Polyhedra_Library::PIP_Tree_Node::compatibility_check(), Parma_Polyhedra_Library::MIP_Problem::erase_artificials(), fast_swap(), find(), Parma_Polyhedra_Library::PIP_Solution_Node::generate_cut(), get(), Parma_Polyhedra_Library::Dense_Row::init(), Parma_Polyhedra_Library::PIP_Solution_Node::Tableau::is_better_pivot(), Parma_Polyhedra_Library::MIP_Problem::linear_combine(), linear_combine(), lower_bound(), Parma_Polyhedra_Library::PIP_Solution_Node::Tableau::normalize(), Parma_Polyhedra_Library::MIP_Problem::OK(), Parma_Polyhedra_Library::Dense_Row::operator=(), operator==(), Parma_Polyhedra_Library::operator==(), Parma_Polyhedra_Library::MIP_Problem::process_pending_constraints(), Parma_Polyhedra_Library::PIP_Solution_Node::row_sign(), Parma_Polyhedra_Library::PIP_Solution_Node::Tableau::scale(), Parma_Polyhedra_Library::MIP_Problem::second_phase(), Parma_Polyhedra_Library::PIP_Problem::solve(), Parma_Polyhedra_Library::PIP_Solution_Node::solve(), Parma_Polyhedra_Library::MIP_Problem::steepest_edge_exact_entering_index(), Parma_Polyhedra_Library::MIP_Problem::steepest_edge_float_entering_index(), Parma_Polyhedra_Library::swap(), swap_coefficients(), and Parma_Polyhedra_Library::PIP_Solution_Node::update_solution().

118  {
119  return tree.end();
120 }
const iterator & end()
Returns an iterator that points after the last element.
CO_Tree tree
The tree used to store the elements.
const Sparse_Row::const_iterator & Parma_Polyhedra_Library::Sparse_Row::end ( ) const
inline

Equivalent to cend().

Definition at line 128 of file Sparse_Row_inlines.hh.

References Parma_Polyhedra_Library::CO_Tree::cend(), and tree.

128  {
129  return tree.cend();
130 }
const const_iterator & cend() const
Returns a const_iterator that points after the last element.
CO_Tree tree
The tree used to store the elements.
void Parma_Polyhedra_Library::Sparse_Row::expand_within_capacity ( dimension_type  n)
inline

Resizes the row to size n.

Parameters
nThe new size for the row.

This method, with this signature, is needed for compatibility with Dense_Row.

This method takes $O(1)$ time.

Definition at line 91 of file Sparse_Row_inlines.hh.

References resize(), and size().

91  {
92  PPL_ASSERT(size() <= n);
93  resize(n);
94 }
dimension_type size() const
Returns the size of the row.
void resize(dimension_type n)
Resizes the row to the specified size.
memory_size_type Parma_Polyhedra_Library::Sparse_Row::external_memory_in_bytes ( ) const
inline

Returns the size in bytes of the memory managed by *this.

This method takes $O(n)$ time.

Definition at line 362 of file Sparse_Row_inlines.hh.

References Parma_Polyhedra_Library::CO_Tree::external_memory_in_bytes(), and tree.

Referenced by Parma_Polyhedra_Library::MIP_Problem::external_memory_in_bytes(), external_memory_in_bytes(), and total_memory_in_bytes().

362  {
364 }
CO_Tree tree
The tree used to store the elements.
dimension_type external_memory_in_bytes() const
Returns the size in bytes of the memory managed by *this.
Definition: CO_Tree.cc:30
memory_size_type Parma_Polyhedra_Library::Sparse_Row::external_memory_in_bytes ( dimension_type  capacity) const
inline

Returns the size in bytes of the memory managed by *this.

This method is provided for compatibility with Dense_Row.

This method takes $O(n)$ time.

Parameters
capacityThis parameter is ignored.

Definition at line 367 of file Sparse_Row_inlines.hh.

References external_memory_in_bytes().

367  {
368  return external_memory_in_bytes();
369 }
memory_size_type external_memory_in_bytes() const
Returns the size in bytes of the memory managed by *this.
void Parma_Polyhedra_Library::Sparse_Row::fast_swap ( dimension_type  i,
iterator  itr 
)
inline

Equivalent to swap(i,itr.index()), but it assumes that lower_bound(i)==itr.

Iterators that pointed to the itr.index()-th element remain valid but now point to the i-th element. Other iterators are unaffected.

This method takes $O(1)$ time.

Definition at line 339 of file Sparse_Row_inlines.hh.

References end(), Parma_Polyhedra_Library::CO_Tree::fast_shift(), lower_bound(), OK(), and tree.

339  {
340  PPL_ASSERT(lower_bound(i) == itr);
341  PPL_ASSERT(itr != end());
342  tree.fast_shift(i, itr);
343  PPL_ASSERT(OK());
344 }
const iterator & end()
Returns an iterator that points after the last stored element.
CO_Tree tree
The tree used to store the elements.
iterator lower_bound(dimension_type i)
Lower bound of index i.
void fast_shift(dimension_type i, iterator itr)
bool OK() const
Checks the invariant.
Definition: Sparse_Row.cc:742
Sparse_Row::iterator Parma_Polyhedra_Library::Sparse_Row::find ( dimension_type  i)
inline

Looks for an element with index i.

Parameters
iThe index of the desired element.

If possible, use the find() method that takes a hint iterator, to improve performance.

This method takes $O(\log n)$ time.

Definition at line 180 of file Sparse_Row_inlines.hh.

References Parma_Polyhedra_Library::CO_Tree::bisect(), end(), Parma_Polyhedra_Library::CO_Tree::iterator::index(), size(), and tree.

Referenced by get(), Parma_Polyhedra_Library::MIP_Problem::linear_combine(), and Parma_Polyhedra_Library::PIP_Solution_Node::solve().

180  {
181  PPL_ASSERT(i < size());
182 
183  iterator itr = tree.bisect(i);
184 
185  if (itr != end() && itr.index() == i) {
186  return itr;
187  }
188  return end();
189 }
dimension_type size() const
Returns the size of the row.
CO_Tree::iterator iterator
An iterator on the row elements.
const iterator & end()
Returns an iterator that points after the last stored element.
iterator bisect(dimension_type key)
Searches an element with key key using bisection.
CO_Tree tree
The tree used to store the elements.
dimension_type index() const
Returns the index of the element pointed to by *this.
Sparse_Row::iterator Parma_Polyhedra_Library::Sparse_Row::find ( iterator  itr,
dimension_type  i 
)
inline

Looks for an element with index i.

Parameters
iThe index of the desired element.
itrIt is used as a hint. This method will be faster if the searched element is near to itr.

The value of itr does not affect the result of this method, as long it is a valid iterator for this row. itr may even be end().

This method takes $O(\log n)$ time. If the distance between itr and the searched position is $O(1)$, this method takes $O(1)$ time.

Definition at line 192 of file Sparse_Row_inlines.hh.

References Parma_Polyhedra_Library::CO_Tree::bisect_near(), end(), Parma_Polyhedra_Library::CO_Tree::iterator::index(), size(), and tree.

192  {
193  PPL_ASSERT(i < size());
194 
195  iterator itr = tree.bisect_near(hint, i);
196 
197  if (itr != end() && itr.index() == i) {
198  return itr;
199  }
200  return end();
201 }
dimension_type size() const
Returns the size of the row.
CO_Tree::iterator iterator
An iterator on the row elements.
const iterator & end()
Returns an iterator that points after the last stored element.
CO_Tree tree
The tree used to store the elements.
iterator bisect_near(iterator hint, dimension_type key)
Searches an element with key key near hint.
dimension_type index() const
Returns the index of the element pointed to by *this.
Sparse_Row::const_iterator Parma_Polyhedra_Library::Sparse_Row::find ( dimension_type  i) const
inline

Looks for an element with index i.

Parameters
iThe index of the desired element.

If possible, use the find() method that takes a hint iterator, to improve performance.

This method takes $O(\log n)$ time.

Definition at line 204 of file Sparse_Row_inlines.hh.

References Parma_Polyhedra_Library::CO_Tree::bisect(), end(), Parma_Polyhedra_Library::CO_Tree::const_iterator::index(), size(), and tree.

204  {
205  PPL_ASSERT(i < size());
206 
207  const_iterator itr = tree.bisect(i);
208 
209  if (itr != end() && itr.index() == i) {
210  return itr;
211  }
212 
213  return end();
214 }
dimension_type size() const
Returns the size of the row.
const iterator & end()
Returns an iterator that points after the last stored element.
iterator bisect(dimension_type key)
Searches an element with key key using bisection.
CO_Tree tree
The tree used to store the elements.
dimension_type index() const
Returns the index of the element pointed to by *this.
CO_Tree::const_iterator const_iterator
A const iterator on the row elements.
Sparse_Row::const_iterator Parma_Polyhedra_Library::Sparse_Row::find ( const_iterator  itr,
dimension_type  i 
) const
inline

Looks for an element with index i.

Parameters
iThe index of the desired element.
itrIt is used as a hint. This method will be faster if the searched element is near to itr.

The value of itr does not affect the result of this method, as long it is a valid iterator for this row. itr may even be end().

This method takes $O(\log n)$ time. If the distance between itr and the searched position is $O(1)$, this method takes $O(1)$ time.

Definition at line 217 of file Sparse_Row_inlines.hh.

References Parma_Polyhedra_Library::CO_Tree::bisect_near(), end(), Parma_Polyhedra_Library::CO_Tree::const_iterator::index(), size(), and tree.

217  {
218  PPL_ASSERT(i < size());
219 
220  const_iterator itr = tree.bisect_near(hint, i);
221 
222  if (itr != end() && itr.index() == i) {
223  return itr;
224  }
225  return end();
226 }
dimension_type size() const
Returns the size of the row.
const iterator & end()
Returns an iterator that points after the last stored element.
CO_Tree tree
The tree used to store the elements.
iterator bisect_near(iterator hint, dimension_type key)
Searches an element with key key near hint.
dimension_type index() const
Returns the index of the element pointed to by *this.
CO_Tree::const_iterator const_iterator
A const iterator on the row elements.
Coefficient_traits::const_reference Parma_Polyhedra_Library::Sparse_Row::get ( dimension_type  i) const
inline

Gets the i-th element in the sequence.

Parameters
iThe index of the desired element.

If possible, use the insert(), find() or lower_bound() methods with a hint instead of this, to improve performance.

This method takes $O(\log n)$ time.

Definition at line 165 of file Sparse_Row_inlines.hh.

References Parma_Polyhedra_Library::Coefficient_zero(), Parma_Polyhedra_Library::CO_Tree::empty(), end(), find(), size_, and tree.

Referenced by Parma_Polyhedra_Library::PIP_Tree_Node::add_constraint(), Parma_Polyhedra_Library::PIP_Tree_Node::compatibility_check(), Parma_Polyhedra_Library::MIP_Problem::compute_generator(), Parma_Polyhedra_Library::PIP_Solution_Node::generate_cut(), Parma_Polyhedra_Library::MIP_Problem::get_exiting_base_index(), Parma_Polyhedra_Library::PIP_Solution_Node::Tableau::is_better_pivot(), Parma_Polyhedra_Library::MIP_Problem::linear_combine(), Parma_Polyhedra_Library::MIP_Problem::pivot(), Parma_Polyhedra_Library::MIP_Problem::process_pending_constraints(), Parma_Polyhedra_Library::PIP_Solution_Node::row_sign(), Parma_Polyhedra_Library::PIP_Solution_Node::solve(), Parma_Polyhedra_Library::MIP_Problem::steepest_edge_float_entering_index(), and Parma_Polyhedra_Library::PIP_Solution_Node::update_solution().

165  {
166  PPL_ASSERT(i < size_);
167  if (tree.empty()) {
168  return Coefficient_zero();
169  }
170  const_iterator itr = find(i);
171  if (itr != end()) {
172  return *itr;
173  }
174  else {
175  return Coefficient_zero();
176  }
177 }
iterator find(dimension_type i)
Looks for an element with index i.
const iterator & end()
Returns an iterator that points after the last stored element.
bool empty() const
Returns true if the tree has no elements.
CO_Tree tree
The tree used to store the elements.
Coefficient_traits::const_reference Coefficient_zero()
Returns a const reference to a Coefficient with value 0.
dimension_type size_
The size of the row.
CO_Tree::const_iterator const_iterator
A const iterator on the row elements.
Sparse_Row::iterator Parma_Polyhedra_Library::Sparse_Row::insert ( dimension_type  i,
Coefficient_traits::const_reference  x 
)
inline

Equivalent to (*this)[i] = x; find(i), but faster.

Parameters
iThe index of the desired element.
xThe value that will be associated to the element.

If possible, use versions of this method that take a hint, to improve performance.

This operation invalidates existing iterators.

This method takes $O(\log^2 n)$ amortized time.

Definition at line 305 of file Sparse_Row_inlines.hh.

References Parma_Polyhedra_Library::CO_Tree::insert(), size_, and tree.

Referenced by combine(), combine_needs_second(), Parma_Polyhedra_Library::PIP_Solution_Node::generate_cut(), operator[](), Parma_Polyhedra_Library::MIP_Problem::process_pending_constraints(), Parma_Polyhedra_Library::PIP_Problem::solve(), Parma_Polyhedra_Library::PIP_Solution_Node::solve(), and Parma_Polyhedra_Library::PIP_Solution_Node::update_tableau().

305  {
306  PPL_ASSERT(i < size_);
307  return tree.insert(i, x);
308 }
iterator insert(dimension_type key)
Inserts an element in the tree.
CO_Tree tree
The tree used to store the elements.
dimension_type size_
The size of the row.
Sparse_Row::iterator Parma_Polyhedra_Library::Sparse_Row::insert ( iterator  itr,
dimension_type  i,
Coefficient_traits::const_reference  x 
)
inline

Equivalent to (*this)[i] = x; find(i), but faster.

Parameters
iThe index of the desired element.
xThe value that will be associated to the element.
itrIt is used as a hint. This method will be faster if the searched element is near to itr, even faster than (*this)[i] = x.

The value of itr does not affect the result of this method, as long it is a valid iterator for this row. itr may even be end().

This operation invalidates existing iterators.

This method takes $O(\log^2 n)$ amortized time. If the distance between itr and the searched position is $O(1)$ and the row already contains an element with this index, this method takes $O(1)$ time.

Definition at line 311 of file Sparse_Row_inlines.hh.

References Parma_Polyhedra_Library::CO_Tree::insert(), size_, and tree.

312  {
313  PPL_ASSERT(i < size_);
314  return tree.insert(itr, i, x);
315 }
iterator insert(dimension_type key)
Inserts an element in the tree.
CO_Tree tree
The tree used to store the elements.
dimension_type size_
The size of the row.
Sparse_Row::iterator Parma_Polyhedra_Library::Sparse_Row::insert ( dimension_type  i)
inline

Equivalent to (*this)[i]; find(i), but faster.

Parameters
iThe index of the desired element.

If possible, use versions of this method that take a hint, to improve performance.

This operation invalidates existing iterators.

This method takes $O(\log^2 n)$ amortized time.

Definition at line 318 of file Sparse_Row_inlines.hh.

References Parma_Polyhedra_Library::CO_Tree::insert(), size_, and tree.

318  {
319  PPL_ASSERT(i < size_);
320  return tree.insert(i);
321 }
iterator insert(dimension_type key)
Inserts an element in the tree.
CO_Tree tree
The tree used to store the elements.
dimension_type size_
The size of the row.
Sparse_Row::iterator Parma_Polyhedra_Library::Sparse_Row::insert ( iterator  itr,
dimension_type  i 
)
inline

Equivalent to (*this)[i]; find(i), but faster.

Parameters
iThe index of the desired element.
itrIt is used as a hint. This method will be faster if the searched element is near to itr, even faster than (*this)[i].

The value of itr does not affect the result of this method, as long it is a valid iterator for this row. itr may even be end().

This operation invalidates existing iterators.

This method takes $O(\log^2 n)$ amortized time. If the distance between itr and the searched position is $O(1)$ and the row already contains an element with this index, this method takes $O(1)$ time.

Definition at line 324 of file Sparse_Row_inlines.hh.

References Parma_Polyhedra_Library::CO_Tree::insert(), size_, and tree.

324  {
325  PPL_ASSERT(i < size_);
326  return tree.insert(itr, i);
327 }
iterator insert(dimension_type key)
Inserts an element in the tree.
CO_Tree tree
The tree used to store the elements.
dimension_type size_
The size of the row.
void Parma_Polyhedra_Library::Sparse_Row::linear_combine ( const Sparse_Row y,
Coefficient_traits::const_reference  coeff1,
Coefficient_traits::const_reference  coeff2 
)

Executes (*this)[i] = (*this)[i]*coeff1 + y[i]*coeff2, for each i.

Parameters
yThe row that will be combined with *this.
coeff1The coefficient used for elements of *this. This must not be 0.
coeff2The coefficient used for elements of y. This must not be 0.

This method takes $O(n*\log^2 n)$ time.

Note
The functors will only be called when necessary. This method can be implemented in user code, too. It is provided for convenience only.
See also
combine_needs_first
combine_needs_second
combine

Definition at line 370 of file Sparse_Row.cc.

References Parma_Polyhedra_Library::add_mul_assign(), begin(), end(), Parma_Polyhedra_Library::CO_Tree::const_iterator::index(), Parma_Polyhedra_Library::CO_Tree::iterator::index(), and Parma_Polyhedra_Library::CO_Tree::m_swap().

Referenced by Parma_Polyhedra_Library::MIP_Problem::linear_combine().

372  {
373  PPL_ASSERT(coeff1 != 0);
374  PPL_ASSERT(coeff2 != 0);
375  PPL_ASSERT(this != &y);
376 
377  if (coeff1 == 1) {
378  // Optimize for this special case.
379  iterator i = end();
380  for (const_iterator j = y.begin(), j_end = y.end(); j != j_end; ++j) {
381  i = insert(i, j.index());
382  add_mul_assign(*i, *j, coeff2);
383  if (*i == 0) {
384  i = reset(i);
385  }
386  }
387  return;
388  }
389 
390  dimension_type counter = 0;
391  // Count the number of elements that are stored in y but not in *this.
392  {
393  iterator i = begin();
394  iterator i_end = end();
395  const_iterator j = y.begin();
396  const_iterator j_end = y.end();
397  if (i != i_end) {
398  while (j != j_end) {
399  PPL_ASSERT(i != i_end);
400  if (i.index() == j.index()) {
401  ++i;
402  ++j;
403  if (i == i_end) {
404  break;
405  }
406  }
407  else {
408  if (i.index() < j.index()) {
409  i = lower_bound(i, j.index());
410  if (i == i_end) {
411  break;
412  }
413  }
414  else {
415  PPL_ASSERT(i.index() > j.index());
416  ++counter;
417  ++j;
418  }
419  }
420  }
421  }
422  PPL_ASSERT(i == i_end || j == j_end);
423  for ( ; j != j_end; ++j) {
424  ++counter;
425  }
426  }
427  // This condition is arbitrary. Changing it affects performance but not
428  // correctness. The values have been tuned using some ppl_lpsol benchmarks
429  // on 2 October 2010.
430  if (counter == 0 || counter < (7 * size()) / 64) {
431  // Few insertions needed, do them directly.
432  iterator i = begin();
433  // This is a const reference to an internal iterator, that is kept valid.
434  // If we just stored a copy, that would be invalidated by the calls to
435  // reset() and insert().
436  const iterator& i_end = end();
437  const_iterator j = y.begin();
438  const_iterator j_end = y.end();
439  while (i != i_end && j != j_end) {
440  if (i.index() == j.index()) {
441  (*i) *= coeff1;
442  add_mul_assign(*i, *j, coeff2);
443  if (*i == 0) {
444  i = reset(i);
445  }
446  else {
447  ++i;
448  }
449  ++j;
450  }
451  else {
452  if (i.index() < j.index()) {
453  (*i) *= coeff1;
454  ++i;
455  }
456  else {
457  PPL_ASSERT(i.index() > j.index());
458  i = insert(i, j.index(), *j);
459  (*i) *= coeff2;
460  ++i;
461  ++j;
462  }
463  }
464  }
465  PPL_ASSERT(i == i_end || j == j_end);
466  for ( ; i != i_end; ++i) {
467  (*i) *= coeff1;
468  }
469  for ( ; j != j_end; ++j) {
470  i = insert(i, j.index(), *j);
471  (*i) *= coeff2;
472  }
473  }
474  else {
475  // Too many insertions needed, a full copy is probably faster than
476  // inserting all those new elements into *this.
477  CO_Tree new_tree(sparse_row_linear_combine_helper_iterator(*this, y,
478  coeff1,
479  coeff2),
480  counter + tree.size());
481  tree.m_swap(new_tree);
482 
483  // Now remove stored zeroes.
484  iterator i = begin();
485  // Note that end() can not be called only once, because reset()
486  // invalidates all iterators.
487  while (i != end()) {
488  if (*i == 0) {
489 #ifndef NDEBUG
490  const dimension_type old_index = i.index();
491 #endif
492  i = reset(i);
493  PPL_ASSERT(find(old_index) == end());
494  }
495  else {
496  ++i;
497  }
498  }
499  }
500 }
iterator find(dimension_type i)
Looks for an element with index i.
size_t dimension_type
An unsigned integral type for representing space dimensions.
dimension_type size() const
Returns the size of the row.
iterator reset(iterator i)
Resets to zero the value pointed to by i.
CO_Tree::iterator iterator
An iterator on the row elements.
void add_mul_assign(GMP_Integer &x, const GMP_Integer &y, const GMP_Integer &z)
const iterator & end()
Returns an iterator that points after the last stored element.
dimension_type size() const
Returns the number of elements stored in the tree.
void m_swap(CO_Tree &x)
Swaps x with *this.
CO_Tree tree
The tree used to store the elements.
iterator insert(dimension_type i, Coefficient_traits::const_reference x)
Equivalent to (*this)[i] = x; find(i), but faster.
iterator lower_bound(dimension_type i)
Lower bound of index i.
iterator begin()
Returns an iterator that points at the first stored element.
CO_Tree::const_iterator const_iterator
A const iterator on the row elements.
void Parma_Polyhedra_Library::Sparse_Row::linear_combine ( const Sparse_Row y,
Coefficient_traits::const_reference  c1,
Coefficient_traits::const_reference  c2,
dimension_type  start,
dimension_type  end 
)

Equivalent to (*this)[i] = (*this)[i] * c1 + y[i] * c2, for each i in [start, end).

This method, unlike the other linear_combine() method, detects when coeff1==1 and/or coeff2==1 or coeff2==-1 in order to save some work.

Definition at line 503 of file Sparse_Row.cc.

References Parma_Polyhedra_Library::add_mul_assign(), Parma_Polyhedra_Library::CO_Tree::const_iterator::index(), Parma_Polyhedra_Library::CO_Tree::iterator::index(), lower_bound(), and Parma_Polyhedra_Library::neg_assign().

506  {
507  PPL_ASSERT(coeff1 != 0);
508  PPL_ASSERT(coeff2 != 0);
509  PPL_ASSERT(this != &y);
510 
511  if (coeff1 == 1) {
512  if (coeff2 == 1) {
513  // Optimized implementation for coeff1==1, coeff2==1.
514  iterator i = this->end();
515  for (const_iterator j = y.lower_bound(start),
516  j_end = y.lower_bound(end); j != j_end; ++j) {
517  i = insert(i, j.index());
518  *i += *j;
519  if (*i == 0) {
520  i = reset(i);
521  }
522  }
523  return;
524  }
525  if (coeff2 == -1) {
526  // Optimized implementation for coeff1==1, coeff2==-1.
527  iterator i = this->end();
528  for (const_iterator j = y.lower_bound(start),
529  j_end = y.lower_bound(end); j != j_end; ++j) {
530  i = insert(i, j.index());
531  *i -= *j;
532  if (*i == 0) {
533  i = reset(i);
534  }
535  }
536  return;
537  }
538  // Optimized implementation for coeff1==1.
539  iterator i = this->end();
540  for (const_iterator j = y.lower_bound(start),
541  j_end = y.lower_bound(end); j != j_end; ++j) {
542  i = insert(i, j.index());
543  add_mul_assign(*i, *j, coeff2);
544  if (*i == 0) {
545  i = reset(i);
546  }
547  }
548  return;
549  }
550 
551  if (coeff2 == 1) {
552  // Optimized implementation for coeff2==1.
553  iterator i = lower_bound(start);
554  // This is a const reference to an internal iterator, that is kept valid.
555  // If we just stored a copy, that would be invalidated by the calls to
556  // reset() and insert().
557  const iterator& i_end = this->end();
558  const_iterator j = y.lower_bound(start);
559  const_iterator j_end = y.lower_bound(end);
560  while (i != i_end && i.index() < end && j != j_end) {
561  if (i.index() == j.index()) {
562  (*i) *= coeff1;
563  *i += *j;
564  if (*i == 0) {
565  i = reset(i);
566  }
567  else {
568  ++i;
569  }
570  ++j;
571  }
572  else {
573  if (i.index() < j.index()) {
574  (*i) *= coeff1;
575  ++i;
576  }
577  else {
578  PPL_ASSERT(i.index() > j.index());
579  i = insert(i, j.index(), *j);
580  ++i;
581  ++j;
582  }
583  }
584  }
585  PPL_ASSERT(i == i_end || j == j_end);
586  for ( ; i != i_end && i.index() < end; ++i) {
587  (*i) *= coeff1;
588  }
589  for ( ; j != j_end; ++j) {
590  i = insert(i, j.index(), *j);
591  }
592  return;
593  }
594 
595  if (coeff2 == -1) {
596  // Optimized implementation for coeff2==-1.
597  iterator i = lower_bound(start);
598  // This is a const reference to an internal iterator, that is kept valid.
599  // If we just stored a copy, that would be invalidated by the calls to
600  // reset() and insert().
601  const iterator& i_end = this->end();
602  const_iterator j = y.lower_bound(start);
603  const_iterator j_end = y.lower_bound(end);
604  while (i != i_end && i.index() < end && j != j_end) {
605  if (i.index() == j.index()) {
606  (*i) *= coeff1;
607  *i -= *j;
608  if (*i == 0) {
609  i = reset(i);
610  }
611  else {
612  ++i;
613  }
614  ++j;
615  }
616  else {
617  if (i.index() < j.index()) {
618  (*i) *= coeff1;
619  ++i;
620  }
621  else {
622  PPL_ASSERT(i.index() > j.index());
623  i = insert(i, j.index(), *j);
624  neg_assign(*i);
625  ++i;
626  ++j;
627  }
628  }
629  }
630  PPL_ASSERT(i == i_end || j == j_end);
631  for ( ; i != i_end && i.index() < end; ++i) {
632  (*i) *= coeff1;
633  }
634  for ( ; j != j_end; ++j) {
635  i = insert(i, j.index(), *j);
636  neg_assign(*i);
637  }
638  return;
639  }
640 
641  iterator i = lower_bound(start);
642  // This is a const reference to an internal iterator, that is kept valid.
643  // If we just stored a copy, that would be invalidated by the calls to
644  // reset() and insert().
645  const iterator& i_end = this->end();
646  const_iterator j = y.lower_bound(start);
647  const_iterator j_end = y.lower_bound(end);
648  while (i != i_end && i.index() < end && j != j_end) {
649  if (i.index() == j.index()) {
650  (*i) *= coeff1;
651  add_mul_assign(*i, *j, coeff2);
652  if (*i == 0) {
653  i = reset(i);
654  }
655  else {
656  ++i;
657  }
658  ++j;
659  }
660  else {
661  if (i.index() < j.index()) {
662  (*i) *= coeff1;
663  ++i;
664  }
665  else {
666  PPL_ASSERT(i.index() > j.index());
667  i = insert(i, j.index(), *j);
668  (*i) *= coeff2;
669  ++i;
670  ++j;
671  }
672  }
673  }
674  PPL_ASSERT(i == i_end || j == j_end);
675  for ( ; i != i_end && i.index() < end; ++i) {
676  (*i) *= coeff1;
677  }
678  for ( ; j != j_end; ++j) {
679  i = insert(i, j.index(), *j);
680  (*i) *= coeff2;
681  }
682 }
iterator reset(iterator i)
Resets to zero the value pointed to by i.
CO_Tree::iterator iterator
An iterator on the row elements.
void add_mul_assign(GMP_Integer &x, const GMP_Integer &y, const GMP_Integer &z)
const iterator & end()
Returns an iterator that points after the last stored element.
iterator insert(dimension_type i, Coefficient_traits::const_reference x)
Equivalent to (*this)[i] = x; find(i), but faster.
void neg_assign(GMP_Integer &x)
iterator lower_bound(dimension_type i)
Lower bound of index i.
CO_Tree::const_iterator const_iterator
A const iterator on the row elements.
Sparse_Row::iterator Parma_Polyhedra_Library::Sparse_Row::lower_bound ( dimension_type  i)
inline

Lower bound of index i.

Parameters
iThe index of the desired element.
Returns
an iterator to the first element with index greater than or equal to i. If there are no such elements, returns end().

If possible, use the find() method that takes a hint iterator, to improve performance.

This method takes $O(\log n)$ time.

Definition at line 229 of file Sparse_Row_inlines.hh.

References Parma_Polyhedra_Library::CO_Tree::bisect(), end(), Parma_Polyhedra_Library::CO_Tree::iterator::index(), size(), and tree.

Referenced by combine_needs_first(), Parma_Polyhedra_Library::Dense_Row::Dense_Row(), fast_swap(), Parma_Polyhedra_Library::Linear_Expression_Impl< Row >::have_a_common_variable(), linear_combine(), Parma_Polyhedra_Library::MIP_Problem::OK(), Parma_Polyhedra_Library::operator==(), Parma_Polyhedra_Library::MIP_Problem::second_phase(), Parma_Polyhedra_Library::MIP_Problem::steepest_edge_exact_entering_index(), and Parma_Polyhedra_Library::MIP_Problem::steepest_edge_float_entering_index().

229  {
230  PPL_ASSERT(i <= size());
231 
232  iterator itr = tree.bisect(i);
233 
234  if (itr == end()) {
235  return end();
236  }
237 
238  if (itr.index() < i) {
239  ++itr;
240  }
241 
242  PPL_ASSERT(itr == end() || itr.index() >= i);
243 
244  return itr;
245 }
dimension_type size() const
Returns the size of the row.
CO_Tree::iterator iterator
An iterator on the row elements.
const iterator & end()
Returns an iterator that points after the last stored element.
iterator bisect(dimension_type key)
Searches an element with key key using bisection.
CO_Tree tree
The tree used to store the elements.
dimension_type index() const
Returns the index of the element pointed to by *this.
Sparse_Row::iterator Parma_Polyhedra_Library::Sparse_Row::lower_bound ( iterator  itr,
dimension_type  i 
)
inline

Lower bound of index i.

Parameters
iThe index of the desired element.
itrIt is used as a hint. This method will be faster if the searched element is near to itr.
Returns
an iterator to the first element with index greater than or equal to i. If there are no such elements, returns end().

The value of itr does not affect the result of this method, as long it is a valid iterator for this row. itr may even be end().

This method takes $O(\log n)$ time. If the distance between itr and the searched position is $O(1)$, this method takes $O(1)$ time.

Definition at line 248 of file Sparse_Row_inlines.hh.

References Parma_Polyhedra_Library::CO_Tree::bisect_near(), end(), Parma_Polyhedra_Library::CO_Tree::iterator::index(), size(), and tree.

248  {
249  PPL_ASSERT(i <= size());
250 
251  iterator itr = tree.bisect_near(hint, i);
252 
253  if (itr == end()) {
254  return end();
255  }
256 
257  if (itr.index() < i) {
258  ++itr;
259  }
260 
261  PPL_ASSERT(itr == end() || itr.index() >= i);
262 
263  return itr;
264 }
dimension_type size() const
Returns the size of the row.
CO_Tree::iterator iterator
An iterator on the row elements.
const iterator & end()
Returns an iterator that points after the last stored element.
CO_Tree tree
The tree used to store the elements.
iterator bisect_near(iterator hint, dimension_type key)
Searches an element with key key near hint.
dimension_type index() const
Returns the index of the element pointed to by *this.
Sparse_Row::const_iterator Parma_Polyhedra_Library::Sparse_Row::lower_bound ( dimension_type  i) const
inline

Lower bound of index i.

Parameters
iThe index of the desired element.
Returns
an iterator to the first element with index greater than or equal to i. If there are no such elements, returns end().

If possible, use the find() method that takes a hint iterator, to improve performance.

This method takes $O(\log n)$ time.

Definition at line 267 of file Sparse_Row_inlines.hh.

References Parma_Polyhedra_Library::CO_Tree::bisect(), end(), Parma_Polyhedra_Library::CO_Tree::const_iterator::index(), size(), and tree.

267  {
268  PPL_ASSERT(i <= size());
269 
270  const_iterator itr = tree.bisect(i);
271 
272  if (itr == end()) {
273  return end();
274  }
275 
276  if (itr.index() < i) {
277  ++itr;
278  }
279 
280  PPL_ASSERT(itr == end() || itr.index() >= i);
281 
282  return itr;
283 }
dimension_type size() const
Returns the size of the row.
const iterator & end()
Returns an iterator that points after the last stored element.
iterator bisect(dimension_type key)
Searches an element with key key using bisection.
CO_Tree tree
The tree used to store the elements.
dimension_type index() const
Returns the index of the element pointed to by *this.
CO_Tree::const_iterator const_iterator
A const iterator on the row elements.
Sparse_Row::const_iterator Parma_Polyhedra_Library::Sparse_Row::lower_bound ( const_iterator  itr,
dimension_type  i 
) const
inline

Lower bound of index i.

Parameters
iThe index of the desired element.
itrIt is used as a hint. This method will be faster if the searched element is near to itr.
Returns
an iterator to the first element with index greater than or equal to i. If there are no such elements, returns end().

The value of itr does not affect the result of this method, as long it is a valid iterator for this row. itr may even be end().

This method takes $O(\log n)$ time. If the distance between itr and the searched position is $O(1)$, this method takes $O(1)$ time.

Definition at line 286 of file Sparse_Row_inlines.hh.

References Parma_Polyhedra_Library::CO_Tree::bisect_near(), end(), Parma_Polyhedra_Library::CO_Tree::const_iterator::index(), size(), and tree.

286  {
287  PPL_ASSERT(i <= size());
288 
289  const_iterator itr = tree.bisect_near(hint, i);
290 
291  if (itr == end()) {
292  return end();
293  }
294 
295  if (itr.index() < i) {
296  ++itr;
297  }
298 
299  PPL_ASSERT(itr == end() || itr.index() >= i);
300 
301  return itr;
302 }
dimension_type size() const
Returns the size of the row.
const iterator & end()
Returns an iterator that points after the last stored element.
CO_Tree tree
The tree used to store the elements.
iterator bisect_near(iterator hint, dimension_type key)
Searches an element with key key near hint.
dimension_type index() const
Returns the index of the element pointed to by *this.
CO_Tree::const_iterator const_iterator
A const iterator on the row elements.
void Parma_Polyhedra_Library::Sparse_Row::m_swap ( Sparse_Row x)
inline

Swaps *this and x.

Parameters
xThe row that will be swapped with *this.

This method takes $O(1)$ time.

Definition at line 57 of file Sparse_Row_inlines.hh.

References OK(), size_, swap(), Parma_Polyhedra_Library::swap(), and tree.

Referenced by Parma_Polyhedra_Library::MIP_Problem::erase_artificials(), Parma_Polyhedra_Library::PIP_Solution_Node::solve(), and swap().

57  {
58  using std::swap;
59  swap(tree, x.tree);
60  swap(size_, x.size_);
61  PPL_ASSERT(OK());
62  PPL_ASSERT(x.OK());
63 }
void swap(CO_Tree &x, CO_Tree &y)
CO_Tree tree
The tree used to store the elements.
dimension_type size_
The size of the row.
void swap(Parma_Polyhedra_Library::Sparse_Row &x, Parma_Polyhedra_Library::Sparse_Row &y)
Swaps x with y.
bool OK() const
Checks the invariant.
Definition: Sparse_Row.cc:742
dimension_type Parma_Polyhedra_Library::Sparse_Row::max_size ( )
inlinestatic

Returns the size() of the largest possible Sparse_Row.

Definition at line 143 of file Sparse_Row_inlines.hh.

References Parma_Polyhedra_Library::CO_Tree::max_size().

143  {
144  return CO_Tree::max_size();
145 }
static dimension_type max_size()
Returns the size() of the largest possible CO_Tree.
void Parma_Polyhedra_Library::Sparse_Row::normalize ( )

Normalizes the modulo of coefficients so that they are mutually prime.

Computes the Greatest Common Divisor (GCD) among the elements of the row and normalizes them by the GCD itself.

This method takes $O(n)$ time.

Definition at line 210 of file Sparse_Row.cc.

References Parma_Polyhedra_Library::exact_div_assign(), Parma_Polyhedra_Library::gcd_assign(), Parma_Polyhedra_Library::neg_assign(), PPL_DIRTY_TEMP_COEFFICIENT, and Parma_Polyhedra_Library::Boundary_NS::sgn().

Referenced by Parma_Polyhedra_Library::MIP_Problem::linear_combine().

210  {
211  // Compute the GCD of all the coefficients.
213  const_iterator i = begin();
214  const_iterator i_end = end();
215  for ( ; i != i_end; ++i) {
216  Coefficient_traits::const_reference x_i = *i;
217  if (const int x_i_sign = sgn(x_i)) {
218  gcd = x_i;
219  if (x_i_sign < 0) {
220  neg_assign(gcd);
221  }
222  goto compute_gcd;
223  }
224  }
225  // We reach this point only if all the coefficients were zero.
226  return;
227 
228  compute_gcd:
229  if (gcd == 1) {
230  return;
231  }
232  for (++i; i != i_end; ++i) {
233  Coefficient_traits::const_reference x_i = *i;
234  if (x_i != 0) {
235  // Note: we use the ternary version instead of a more concise
236  // gcd_assign(gcd, x_i) to take advantage of the fact that
237  // `gcd' will decrease very rapidly (see D. Knuth, The Art of
238  // Computer Programming, second edition, Section 4.5.2,
239  // Algorithm C, and the discussion following it). Our
240  // implementation of gcd_assign(x, y, z) for checked numbers is
241  // optimized for the case where `z' is smaller than `y', so that
242  // on checked numbers we gain. On the other hand, for the
243  // implementation of gcd_assign(x, y, z) on GMP's unbounded
244  // integers we cannot make any assumption, so here we draw.
245  // Overall, we win.
246  gcd_assign(gcd, x_i, gcd);
247  if (gcd == 1) {
248  return;
249  }
250  }
251  }
252  // Divide the coefficients by the GCD.
253  for (iterator j = begin(), j_end = end(); j != j_end; ++j) {
254  Coefficient& x_j = *j;
255  exact_div_assign(x_j, x_j, gcd);
256  }
257 
258  PPL_ASSERT(OK());
259 }
#define PPL_DIRTY_TEMP_COEFFICIENT(id)
Declare a local variable named id, of type Coefficient, and containing an unknown initial value...
CO_Tree::iterator iterator
An iterator on the row elements.
const iterator & end()
Returns an iterator that points after the last stored element.
void exact_div_assign(Checked_Number< T, Policy > &x, const Checked_Number< T, Policy > &y, const Checked_Number< T, Policy > &z)
PPL_COEFFICIENT_TYPE Coefficient
An alias for easily naming the type of PPL coefficients.
void neg_assign(GMP_Integer &x)
iterator begin()
Returns an iterator that points at the first stored element.
void gcd_assign(GMP_Integer &x, const GMP_Integer &y, const GMP_Integer &z)
int sgn(Boundary_Type type, const T &x, const Info &info)
CO_Tree::const_iterator const_iterator
A const iterator on the row elements.
bool OK() const
Checks the invariant.
Definition: Sparse_Row.cc:742
dimension_type Parma_Polyhedra_Library::Sparse_Row::num_stored_elements ( ) const
inline

Returns the number of elements explicitly stored in the row.

This is equivalent to std::distance(begin(), end()), but it's much faster.

This method takes $O(1)$ time.

Definition at line 71 of file Sparse_Row_inlines.hh.

References Parma_Polyhedra_Library::CO_Tree::size(), and tree.

71  {
72  return tree.size();
73 }
dimension_type size() const
Returns the number of elements stored in the tree.
CO_Tree tree
The tree used to store the elements.
bool Parma_Polyhedra_Library::Sparse_Row::OK ( ) const

Checks the invariant.

Definition at line 742 of file Sparse_Row.cc.

References Parma_Polyhedra_Library::CO_Tree::const_iterator::index().

Referenced by add_zeroes_and_shift(), delete_element_and_shift(), fast_swap(), m_swap(), reset(), resize(), Sparse_Row(), and swap_coefficients().

742  {
743  if (begin() == end()) {
744  return true;
745  }
746  const_iterator last = end();
747  --last;
748  return (last.index() < size_);
749 }
const iterator & end()
Returns an iterator that points after the last stored element.
dimension_type size_
The size of the row.
iterator begin()
Returns an iterator that points at the first stored element.
CO_Tree::const_iterator const_iterator
A const iterator on the row elements.
bool Parma_Polyhedra_Library::Sparse_Row::OK ( dimension_type  capacity) const

Checks the invariant.

This method is provided for compatibility with Dense_Row.

Parameters
capacityThis parameter is ignored.

Definition at line 752 of file Sparse_Row.cc.

752  {
753  return OK();
754 }
bool OK() const
Checks the invariant.
Definition: Sparse_Row.cc:742
PPL::Sparse_Row & Parma_Polyhedra_Library::Sparse_Row::operator= ( const Dense_Row row)

Definition at line 118 of file Sparse_Row.cc.

References Parma_Polyhedra_Library::swap().

118  {
119  Sparse_Row tmp(row);
120  swap(*this, tmp);
121  PPL_ASSERT(OK());
122 
123  return *this;
124 }
Sparse_Row(dimension_type n=0)
Constructs a row with the specified size.
void swap(Parma_Polyhedra_Library::Sparse_Row &x, Parma_Polyhedra_Library::Sparse_Row &y)
Swaps x with y.
bool OK() const
Checks the invariant.
Definition: Sparse_Row.cc:742
Coefficient & Parma_Polyhedra_Library::Sparse_Row::operator[] ( dimension_type  i)
inline

Gets a reference to the i-th element.

Parameters
iThe index of the desired element.

For read-only access it's better to use get(), that avoids allocating space for zeroes.

If possible, use the insert(), find() or lower_bound() methods with a hint instead of this, to improve performance.

This operation invalidates existing iterators.

This method takes $O(\log n)$ amortized time when there is already an element with index i, and $O(\log^2 n)$ otherwise.

Definition at line 153 of file Sparse_Row_inlines.hh.

References insert(), and size_.

153  {
154  PPL_ASSERT(i < size_);
155  iterator itr = insert(i);
156  return *itr;
157 }
CO_Tree::iterator iterator
An iterator on the row elements.
iterator insert(dimension_type i, Coefficient_traits::const_reference x)
Equivalent to (*this)[i] = x; find(i), but faster.
dimension_type size_
The size of the row.
Coefficient_traits::const_reference Parma_Polyhedra_Library::Sparse_Row::operator[] ( dimension_type  i) const
inline

Equivalent to get(i), provided for convenience.

This method takes $O(\log n)$ time.

Definition at line 160 of file Sparse_Row_inlines.hh.

160  {
161  return get(i);
162 }
void Parma_Polyhedra_Library::Sparse_Row::print ( ) const

Prints *this to std::cerr using operator<<.

Sparse_Row::iterator Parma_Polyhedra_Library::Sparse_Row::reset ( iterator  i)
inline

Resets to zero the value pointed to by i.

Parameters
iAn iterator pointing to the element that will be reset (not stored anymore).

By calling this method instead of getting a reference to the value and setting it to zero, the element will no longer be stored.

This operation invalidates existing iterators.

This method takes $O(\log^2 n)$ amortized time.

Definition at line 347 of file Sparse_Row_inlines.hh.

References Parma_Polyhedra_Library::CO_Tree::erase(), OK(), and tree.

Referenced by combine(), combine_needs_first(), combine_needs_second(), and Parma_Polyhedra_Library::Expression_Hide_Inhomo< T >::get_row().

347  {
348  iterator res = tree.erase(i);
349  PPL_ASSERT(OK());
350  return res;
351 }
CO_Tree::iterator iterator
An iterator on the row elements.
CO_Tree tree
The tree used to store the elements.
iterator erase(dimension_type key)
Erases the element with key key from the tree.
bool OK() const
Checks the invariant.
Definition: Sparse_Row.cc:742
PPL::Sparse_Row::iterator Parma_Polyhedra_Library::Sparse_Row::reset ( iterator  first,
iterator  last 
)

Resets to zero the values in the range [first,last).

Parameters
firstAn iterator pointing to the first element to reset.
lastAn iterator pointing after the last element to reset.

By calling this method instead of getting a reference to the values and setting them to zero, the elements will no longer be stored.

This operation invalidates existing iterators.

This method takes $O(k*\log^2 n)$ amortized time, where k is the number of elements in [first,last).

Definition at line 171 of file Sparse_Row.cc.

References Parma_Polyhedra_Library::CO_Tree::iterator::index().

171  {
172  if (first == last) {
173  return first;
174  }
175 
176  PPL_ASSERT(last != end());
177  --last;
178  const dimension_type j = last.index();
179  PPL_ASSERT(first.index() <= j);
180  // We can't just compare first and last at each iteration, because last will
181  // be invalidated by the first erase.
182  while (first.index() < j) {
183  first = reset(first);
184  }
185 
186  first = reset(first);
187 
188  PPL_ASSERT(OK());
189  return first;
190 }
size_t dimension_type
An unsigned integral type for representing space dimensions.
iterator reset(iterator i)
Resets to zero the value pointed to by i.
const iterator & end()
Returns an iterator that points after the last stored element.
bool OK() const
Checks the invariant.
Definition: Sparse_Row.cc:742
void Parma_Polyhedra_Library::Sparse_Row::reset ( dimension_type  i)
inline

Resets to zero the i-th element.

Parameters
iThe index of the element to reset.

By calling this method instead of getting a reference to the value and setting it to zero, the element will no longer be stored.

This operation invalidates existing iterators.

This method takes $O(\log^2 n)$ amortized time.

Definition at line 354 of file Sparse_Row_inlines.hh.

References Parma_Polyhedra_Library::CO_Tree::erase(), OK(), size(), and tree.

354  {
355  PPL_ASSERT(i < size());
356 
357  tree.erase(i);
358  PPL_ASSERT(OK());
359 }
dimension_type size() const
Returns the size of the row.
CO_Tree tree
The tree used to store the elements.
iterator erase(dimension_type key)
Erases the element with key key from the tree.
bool OK() const
Checks the invariant.
Definition: Sparse_Row.cc:742
void Parma_Polyhedra_Library::Sparse_Row::reset_after ( dimension_type  i)

Resets to zero the elements with index greater than or equal to i.

Parameters
iThe index of the first element to reset.

By calling this method instead of getting a reference to the values and setting them to zero, the elements will no longer be stored.

This operation invalidates existing iterators.

This method takes $O(k*\log^2 n)$ amortized time, where k is the number of elements with index greater than or equal to i.

Definition at line 193 of file Sparse_Row.cc.

Referenced by resize().

193  {
194  PPL_ASSERT(i < size_);
195 
196  iterator itr = lower_bound(i);
197  // This is a const reference to an internal iterator, that is kept valid.
198  // If we just stored a copy, that would be invalidated by the calls to
199  // reset().
200  const iterator& itr_end = end();
201 
202  while (itr != itr_end) {
203  itr = reset(itr);
204  }
205 
206  PPL_ASSERT(OK());
207 }
iterator reset(iterator i)
Resets to zero the value pointed to by i.
CO_Tree::iterator iterator
An iterator on the row elements.
const iterator & end()
Returns an iterator that points after the last stored element.
iterator lower_bound(dimension_type i)
Lower bound of index i.
dimension_type size_
The size of the row.
bool OK() const
Checks the invariant.
Definition: Sparse_Row.cc:742
void Parma_Polyhedra_Library::Sparse_Row::resize ( dimension_type  n)
inline

Resizes the row to the specified size.

Parameters
nThe new size for the row.

This method takes $O(k*\log^2 n)$ amortized time when shrinking the row and removing the trailing k elements. It takes $O(1)$ time when enlarging the row.

Definition at line 76 of file Sparse_Row_inlines.hh.

References OK(), reset_after(), and size_.

Referenced by expand_within_capacity(), Parma_Polyhedra_Library::Expression_Hide_Last< T >::get_row(), and shrink().

76  {
77  if (n < size_) {
78  reset_after(n);
79  }
80  size_ = n;
81  PPL_ASSERT(OK());
82 }
void reset_after(dimension_type i)
Resets to zero the elements with index greater than or equal to i.
Definition: Sparse_Row.cc:193
dimension_type size_
The size of the row.
bool OK() const
Checks the invariant.
Definition: Sparse_Row.cc:742
void Parma_Polyhedra_Library::Sparse_Row::shrink ( dimension_type  n)
inline

Resizes the row to size n.

Parameters
nThe new size for the row.

This method, with this signature, is needed for compatibility with Dense_Row.

This method takes $O(k*\log^2 n)$ amortized time where k is the number of removed elements.

Definition at line 85 of file Sparse_Row_inlines.hh.

References resize(), and size().

85  {
86  PPL_ASSERT(size() >= n);
87  resize(n);
88 }
dimension_type size() const
Returns the size of the row.
void resize(dimension_type n)
Resizes the row to the specified size.
void Parma_Polyhedra_Library::Sparse_Row::swap_coefficients ( dimension_type  i,
dimension_type  j 
)

Swaps the i-th element with the j-th element.

Parameters
iThe index of an element.
jThe index of another element.

This operation invalidates existing iterators.

This method takes $O(\log^2 n)$ amortized time.

Definition at line 127 of file Sparse_Row.cc.

References Parma_Polyhedra_Library::CO_Tree::iterator::index(), PPL_DIRTY_TEMP_COEFFICIENT, and Parma_Polyhedra_Library::swap().

127  {
128  PPL_ASSERT(i < size_);
129  PPL_ASSERT(j < size_);
130 
131  if (tree.empty()) {
132  return;
133  }
134 
135  using std::swap;
136 
137  iterator itr_i = tree.bisect(i);
138  iterator itr_j = tree.bisect(j);
139  if (itr_i.index() == i) {
140  if (itr_j.index() == j) {
141  // Both elements are in the tree.
142  swap(*itr_i, *itr_j);
143  }
144  else {
145  // i is in the tree, j is not.
147  swap(*itr_i, tmp);
148  tree.erase(itr_i);
149  // Now both iterators have been invalidated.
150  itr_j = tree.insert(j);
151  swap(*itr_j, tmp);
152  }
153  }
154  else {
155  if (itr_j.index() == j) {
156  // j is in the tree, i is not.
158  swap(*itr_j, tmp);
159  // Now both iterators have been invalidated.
160  tree.erase(itr_j);
161  itr_i = tree.insert(i);
162  swap(*itr_i, tmp);
163  }
164  else {
165  // Do nothing, elements are both non-stored zeroes.
166  }
167  }
168 }
void swap(CO_Tree &x, CO_Tree &y)
#define PPL_DIRTY_TEMP_COEFFICIENT(id)
Declare a local variable named id, of type Coefficient, and containing an unknown initial value...
CO_Tree::iterator iterator
An iterator on the row elements.
bool empty() const
Returns true if the tree has no elements.
iterator insert(dimension_type key)
Inserts an element in the tree.
iterator bisect(dimension_type key)
Searches an element with key key using bisection.
CO_Tree tree
The tree used to store the elements.
dimension_type size_
The size of the row.
iterator erase(dimension_type key)
Erases the element with key key from the tree.
void swap(Parma_Polyhedra_Library::Sparse_Row &x, Parma_Polyhedra_Library::Sparse_Row &y)
Swaps x with y.
void Parma_Polyhedra_Library::Sparse_Row::swap_coefficients ( iterator  i,
iterator  j 
)
inline

Swaps the element pointed to by i with the element pointed to by j.

Parameters
iAn iterator pointing to an element.
jAn iterator pointing to another element.

This method takes $O(1)$ time.

Definition at line 330 of file Sparse_Row_inlines.hh.

References end(), OK(), swap(), and Parma_Polyhedra_Library::swap().

330  {
331  PPL_ASSERT(i != end());
332  PPL_ASSERT(j != end());
333  using std::swap;
334  swap(*i, *j);
335  PPL_ASSERT(OK());
336 }
void swap(CO_Tree &x, CO_Tree &y)
const iterator & end()
Returns an iterator that points after the last stored element.
void swap(Parma_Polyhedra_Library::Sparse_Row &x, Parma_Polyhedra_Library::Sparse_Row &y)
Swaps x with y.
bool OK() const
Checks the invariant.
Definition: Sparse_Row.cc:742
memory_size_type Parma_Polyhedra_Library::Sparse_Row::total_memory_in_bytes ( ) const
inline

Returns the size in bytes of the memory managed by *this.

This method takes $O(n)$ time.

Definition at line 372 of file Sparse_Row_inlines.hh.

References external_memory_in_bytes().

Referenced by total_memory_in_bytes().

372  {
373  return external_memory_in_bytes() + sizeof(*this);
374 }
memory_size_type external_memory_in_bytes() const
Returns the size in bytes of the memory managed by *this.
memory_size_type Parma_Polyhedra_Library::Sparse_Row::total_memory_in_bytes ( dimension_type  capacity) const
inline

Returns the size in bytes of the memory managed by *this.

This method is provided for compatibility with Dense_Row.

This method takes $O(n)$ time.

Parameters
capacityThis parameter is ignored.

Definition at line 377 of file Sparse_Row_inlines.hh.

References total_memory_in_bytes().

377  {
378  return total_memory_in_bytes();
379 }
memory_size_type total_memory_in_bytes() const
Returns the size in bytes of the memory managed by *this.

Friends And Related Function Documentation

void linear_combine ( Sparse_Row x,
const Dense_Row y,
Coefficient_traits::const_reference  coeff1,
Coefficient_traits::const_reference  coeff2 
)
related

Equivalent to x[i] = x[i] * c1 + y[i] * c2, for each i in [start, end).

void linear_combine ( Sparse_Row x,
const Dense_Row y,
Coefficient_traits::const_reference  c1,
Coefficient_traits::const_reference  c2,
dimension_type  start,
dimension_type  end 
)
related

Equivalent to x[i] = x[i] * c1 + y[i] * c2, for each i in [start, end).

This function detects when coeff1==1 and/or coeff2==1 or coeff2==-1 in order to save some work.

void linear_combine ( Dense_Row x,
const Sparse_Row y,
Coefficient_traits::const_reference  coeff1,
Coefficient_traits::const_reference  coeff2 
)
related

Equivalent to x[i] = x[i] * c1 + y[i] * c2, for each i in [start, end).

void linear_combine ( Dense_Row x,
const Sparse_Row y,
Coefficient_traits::const_reference  c1,
Coefficient_traits::const_reference  c2,
dimension_type  start,
dimension_type  end 
)
related

Equivalent to x[i] = x[i] * c1 + y[i] * c2, for each i in [start, end).

This function detects when coeff1==1 and/or coeff2==1 or coeff2==-1 in order to save some work.

void linear_combine ( Sparse_Row x,
const Sparse_Row y,
Coefficient_traits::const_reference  coeff1,
Coefficient_traits::const_reference  coeff2 
)
related

Equivalent to x[i] = x[i] * c1 + y[i] * c2, for each i in [start, end).

void linear_combine ( Sparse_Row x,
const Sparse_Row y,
Coefficient_traits::const_reference  c1,
Coefficient_traits::const_reference  c2,
dimension_type  start,
dimension_type  end 
)
related

Equivalent to x[i] = x[i] * c1 + y[i] * c2, for each i in [start, end).

This function detects when coeff1==1 and/or coeff2==1 or coeff2==-1 in order to save some work.

bool operator!= ( const Sparse_Row x,
const Sparse_Row y 
)
related

Definition at line 805 of file Sparse_Row.cc.

805  {
806  return !(x == y);
807 }
bool operator!= ( const Sparse_Row x,
const Sparse_Row y 
)
related

Returns true if and only if x and y are different.

bool operator== ( const Sparse_Row x,
const Sparse_Row y 
)
related

Definition at line 758 of file Sparse_Row.cc.

References begin(), end(), Parma_Polyhedra_Library::CO_Tree::const_iterator::index(), and size().

758  {
759  if (x.size() != y.size()) {
760  return false;
761  }
762  Sparse_Row::const_iterator i = x.begin();
763  Sparse_Row::const_iterator i_end = x.end();
764  Sparse_Row::const_iterator j = y.begin();
765  Sparse_Row::const_iterator j_end = y.end();
766  while (i != i_end && j != j_end) {
767  if (i.index() == j.index()) {
768  if (*i != *j) {
769  return false;
770  }
771  ++i;
772  ++j;
773  }
774  else {
775  if (i.index() < j.index()) {
776  if (*i != 0) {
777  return false;
778  }
779  ++i;
780  }
781  else {
782  PPL_ASSERT(i.index() > j.index());
783  if (*j != 0) {
784  return false;
785  }
786  ++j;
787  }
788  }
789  }
790  for ( ; i != i_end; ++i) {
791  if (*i != 0) {
792  return false;
793  }
794  }
795  for ( ; j != j_end; ++j) {
796  if (*j != 0) {
797  return false;
798  }
799  }
800  return true;
801 }
CO_Tree::const_iterator const_iterator
A const iterator on the row elements.
bool operator== ( const Sparse_Row x,
const Sparse_Row y 
)
related

Returns true if and only if x and y are equal.

void swap ( Sparse_Row x,
Sparse_Row y 
)
related

Definition at line 385 of file Sparse_Row_inlines.hh.

References m_swap().

385  {
386  x.m_swap(y);
387 }

Swaps x with y.

Referenced by m_swap(), and swap_coefficients().

Member Data Documentation

dimension_type Parma_Polyhedra_Library::Sparse_Row::size_
private

The size of the row.

The elements contained in this row have indexes that are less than size_.

Definition at line 822 of file Sparse_Row_defs.hh.

Referenced by add_zeroes_and_shift(), delete_element_and_shift(), get(), insert(), m_swap(), operator[](), resize(), and size().

CO_Tree Parma_Polyhedra_Library::Sparse_Row::tree
private

The documentation for this class was generated from the following files: