24 #ifndef PPL_Linear_Expression_Impl_templates_hh
25 #define PPL_Linear_Expression_Impl_templates_hh 1
39 template <
typename Row>
45 template <
typename Row>
46 template <
typename Row2>
52 template <
typename Row>
57 if (
const Dense_Ptr p = dynamic_cast<Dense_Ptr>(&e)) {
60 else if (
const Sparse_Ptr p = dynamic_cast<Sparse_Ptr>(&e)) {
69 template <
typename Row>
75 if (
const Dense_Ptr p = dynamic_cast<Dense_Ptr>(&e)) {
78 else if (
const Sparse_Ptr p = dynamic_cast<Sparse_Ptr>(&e)) {
87 template <
typename Row>
88 template <
typename Row2>
97 template <
typename Row>
98 template <
typename Row2>
105 Coefficient_traits::const_reference x_i = x.
row.get(i);
106 Coefficient_traits::const_reference y_i = y.
row.get(i);
107 PPL_ASSERT(x_i != 0);
108 PPL_ASSERT(y_i != 0);
111 normalize2(x_i, y_i, normalized_x_v, normalized_y_v);
116 assert(x.
row.get(i) == 0);
120 template <
typename Row>
121 template <
typename Row2>
125 Coefficient_traits::const_reference c1,
126 Coefficient_traits::const_reference c2) {
136 template <
typename Row>
137 template <
typename Row2>
141 Coefficient_traits::const_reference c1,
142 Coefficient_traits::const_reference c2) {
150 template <
typename Row>
151 template <
typename Row2>
158 typename Row::const_iterator i = x.
row.lower_bound(1);
159 typename Row::const_iterator i_end = x.
row.end();
160 typename Row2::const_iterator j = y.
row.lower_bound(1);
161 typename Row2::const_iterator j_end = y.
row.end();
162 while (i != i_end && j != j_end) {
163 if (i.index() < j.index()) {
164 const int s =
sgn(*i);
171 if (i.index() > j.index()) {
172 const int s =
sgn(*j);
179 PPL_ASSERT(i.index() == j.index());
180 const int s =
cmp(*i, *j);
191 for ( ; i != i_end; ++i) {
192 const int s =
sgn(*i);
197 for ( ; j != j_end; ++j) {
198 const int s =
sgn(*j);
207 const int comp =
cmp(x.
row.get(0), y.
row.get(0));
214 PPL_ASSERT(comp == 0);
220 template <
typename Row>
223 throw std::length_error(
"Linear_Expression_Impl::"
224 "Linear_Expression_Impl(v):\n"
225 "v exceeds the maximum allowed "
233 template <
typename Row>
234 template <
typename Row2>
241 template <
typename Row>
247 template <
typename Row>
253 template <
typename Row>
263 row.swap_coefficients(cycle[0].space_dimension(),
264 cycle[1].space_dimension());
268 tmp = row.get(cycle.back().space_dimension());
270 row.swap_coefficients(cycle[i + 1].space_dimension(),
271 cycle[i].space_dimension());
274 row.reset(cycle[0].space_dimension());
278 swap(tmp, row[cycle[0].space_dimension()]);
284 template <
typename Row>
285 template <
typename Row2>
293 template <
typename Row>
298 throw std::length_error(
"Linear_Expression_Impl& "
299 "operator+=(e, v):\n"
300 "v exceeds the maximum allowed space dimension.");
302 if (space_dimension() < v_space_dim) {
303 set_space_dimension(v_space_dim);
305 typename Row::iterator itr = row.insert(v_space_dim);
315 template <
typename Row>
316 template <
typename Row2>
324 template <
typename Row>
329 throw std::length_error(
"Linear_Expression_Impl& "
330 "operator-=(e, v):\n"
331 "v exceeds the maximum allowed space dimension.");
333 if (space_dimension() < v_space_dim) {
334 set_space_dimension(v_space_dim);
336 typename Row::iterator itr = row.insert(v_space_dim);
346 template <
typename Row>
354 for (
typename Row::iterator i = row.begin(),
355 i_end = row.end(); i != i_end; ++i) {
363 template <
typename Row>
366 typename Row::iterator i = row.
begin();
367 const typename Row::iterator& i_end = row.end();
382 template <
typename Row>
385 for (
typename Row::iterator i = row.begin(),
386 i_end = row.end(); i != i_end; ++i) {
393 template <
typename Row>
399 throw std::length_error(
"Linear_Expression_Impl& "
400 "add_mul_assign(e, n, v):\n"
401 "v exceeds the maximum allowed space dimension.");
403 if (space_dimension() < v_space_dim) {
404 set_space_dimension(v_space_dim);
409 typename Row::iterator itr = row.insert(v_space_dim);
419 template <
typename Row>
426 throw std::length_error(
"Linear_Expression_Impl& "
427 "sub_mul_assign(e, n, v):\n"
428 "v exceeds the maximum allowed space dimension.");
430 if (space_dimension() < v_space_dim) {
431 set_space_dimension(v_space_dim);
436 typename Row::iterator itr = row.insert(v_space_dim);
445 template <
typename Row>
446 template <
typename Row2>
456 template <
typename Row>
457 template <
typename Row2>
467 template <
typename Row>
472 for (
typename Row::const_iterator i = row.lower_bound(1), i_end = row.end();
523 template <
typename Row>
524 Coefficient_traits::const_reference
529 template <
typename Row>
542 template <
typename Row>
550 for (
typename Row::iterator i = row.lower_bound(start),
551 i_end = row.lower_bound(end); i != i_end; ++i) {
557 template <
typename Row>
563 typename Row::iterator i = row.lower_bound(start);
564 const typename Row::iterator& i_end = row.end();
565 while (i != i_end && i.index() < end) {
570 for (
typename Row::iterator
571 i = row.lower_bound(start), i_end = row.lower_bound(end);
579 template <
typename Row>
580 template <
typename Row2>
584 Coefficient_traits::const_reference c1,
585 Coefficient_traits::const_reference c2,
591 template <
typename Row>
592 template <
typename Row2>
596 Coefficient_traits::const_reference c1,
597 Coefficient_traits::const_reference c2,
599 PPL_ASSERT(start <= end);
600 PPL_ASSERT(end <= row.size());
601 PPL_ASSERT(end <= y.
row.size());
606 typename Row::iterator i = row.lower_bound(start);
607 const typename Row::iterator& i_end = row.end();
608 while (i != i_end && i.index() < end) {
616 typename Row::iterator i = row.lower_bound(start);
617 const typename Row::iterator& i_end = row.end();
618 typename Row2::const_iterator j = y.
row.lower_bound(start);
619 typename Row2::const_iterator j_last = y.
row.lower_bound(end);
621 while (i != i_end && i.index() < end && j != j_last) {
622 if (i.index() < j.index()) {
626 if (i.index() > j.index()) {
627 i = row.insert(i, j.index(), *j);
633 PPL_ASSERT(i.index() == j.index());
639 while (i != i_end && i.index() < end) {
642 while (j != j_last) {
643 i = row.insert(i, j.index(), *j);
654 for (
typename Row::iterator i = row.lower_bound(start),
655 i_end = row.lower_bound(end); i != i_end; ++i) {
668 template <
typename Row>
671 typename Row::iterator i = row.lower_bound(1);
672 typename Row::iterator i_end = row.end();
674 for ( ; i != i_end; ++i) {
680 if (i != i_end && *i < 0) {
681 for ( ; i != i_end; ++i) {
685 typename Row::iterator first = row.begin();
686 if (first != row.end() && first.index() == 0) {
693 template <
typename Row>
696 PPL_ASSERT(first <= last);
697 PPL_ASSERT(last <= row.size());
698 typename Row::iterator i = row.lower_bound(first);
699 typename Row::iterator i_end = row.lower_bound(last);
700 for ( ; i != i_end; ++i) {
706 template <
typename Row>
707 template <
typename Row2>
714 template <
typename Row>
715 template <
typename Row2>
719 Row x(e.
row, space_dim + 1, space_dim + 1);
724 template <
typename Row>
725 template <
typename Row2>
732 PPL_ASSERT(start <= end);
733 PPL_ASSERT(end <= x.
row.size());
734 PPL_ASSERT(end <= y.
row.size());
736 typename Row ::const_iterator x_i = x.
row.lower_bound(start);
737 typename Row ::const_iterator x_end = x.
row.lower_bound(end);
738 typename Row2::const_iterator y_i = y.
row.lower_bound(start);
739 typename Row2::const_iterator y_end = y.
row.lower_bound(end);
740 while (x_i != x_end && y_i != y_end) {
741 if (x_i.index() == y_i.index()) {
747 if (x_i.index() < y_i.index()) {
748 PPL_ASSERT(y.
row.get(x_i.index()) == 0);
753 PPL_ASSERT(x.
row.get(y_i.index()) == 0);
763 template <
typename Row>
764 template <
typename Row2>
770 scalar_product_assign(result, y, start, end);
774 template <
typename Row>
775 template <
typename Row2>
781 PPL_ASSERT(start <= end);
782 PPL_ASSERT(end <= x.
row.size());
783 PPL_ASSERT(end <= y.
row.size());
785 typename Row::const_iterator i = x.
row.lower_bound(start);
786 typename Row::const_iterator i_end = x.
row.lower_bound(end);
787 typename Row2::const_iterator j = y.
row.lower_bound(start);
788 typename Row2::const_iterator j_end = y.
row.lower_bound(end);
789 while (i != i_end && j != j_end) {
790 if (i.index() == j.index()) {
798 if (i.index() < j.index()) {
805 PPL_ASSERT(i.index() > j.index());
813 for ( ; i != i_end; ++i) {
818 for ( ; j != j_end; ++j) {
826 template <
typename Row>
827 template <
typename Row2>
831 Coefficient_traits::const_reference c1,
832 Coefficient_traits::const_reference c2,
835 PPL_ASSERT(start <= end);
836 PPL_ASSERT(end <= x.
row.size());
837 PPL_ASSERT(end <= y.
row.size());
854 typename Row::const_iterator i = x.
row.lower_bound(start);
855 typename Row::const_iterator i_end = x.
row.lower_bound(end);
856 typename Row2::const_iterator j = y.
row.lower_bound(start);
857 typename Row2::const_iterator j_end = y.
row.lower_bound(end);
858 while (i != i_end && j != j_end) {
859 if (i.index() == j.index()) {
860 if ((*i) * c1 != (*j) * c2) {
867 if (i.index() < j.index()) {
874 PPL_ASSERT(i.index() > j.index());
882 for ( ; i != i_end; ++i) {
887 for ( ; j != j_end; ++j) {
895 template <
typename Row>
901 if (
const Dense_Ptr p = dynamic_cast<Dense_Ptr>(&y)) {
904 else if (
const Sparse_Ptr p = dynamic_cast<Sparse_Ptr>(&y)) {
913 template <
typename Row>
917 Coefficient_traits::const_reference c1,
918 Coefficient_traits::const_reference c2) {
921 if (
const Dense_Ptr p = dynamic_cast<Dense_Ptr>(&y)) {
924 else if (
const Sparse_Ptr p = dynamic_cast<Sparse_Ptr>(&y)) {
933 template <
typename Row>
937 Coefficient_traits::const_reference c1,
938 Coefficient_traits::const_reference c2) {
941 if (
const Dense_Ptr p = dynamic_cast<Dense_Ptr>(&y)) {
942 linear_combine_lax(*p, c1, c2);
944 else if (
const Sparse_Ptr p = dynamic_cast<Sparse_Ptr>(&y)) {
945 linear_combine_lax(*p, c1, c2);
953 template <
typename Row>
959 if (
const Dense_Ptr p = dynamic_cast<Dense_Ptr>(&y)) {
960 return is_equal_to(*p);
962 else if (
const Sparse_Ptr p = dynamic_cast<Sparse_Ptr>(&y)) {
963 return is_equal_to(*p);
972 template <
typename Row>
978 if (
const Dense_Ptr p = dynamic_cast<Dense_Ptr>(&y)) {
979 return operator+=(*p);
981 else if (
const Sparse_Ptr p = dynamic_cast<Sparse_Ptr>(&y)) {
982 return operator+=(*p);
991 template <
typename Row>
997 if (
const Dense_Ptr p = dynamic_cast<Dense_Ptr>(&y)) {
998 return operator-=(*p);
1000 else if (
const Sparse_Ptr p = dynamic_cast<Sparse_Ptr>(&y)) {
1001 return operator-=(*p);
1010 template <
typename Row>
1017 if (
const Dense_Ptr p = dynamic_cast<Dense_Ptr>(&y)) {
1020 else if (
const Sparse_Ptr p = dynamic_cast<Sparse_Ptr>(&y)) {
1029 template <
typename Row>
1036 if (
const Dense_Ptr p = dynamic_cast<Dense_Ptr>(&y)) {
1039 else if (
const Sparse_Ptr p = dynamic_cast<Sparse_Ptr>(&y)) {
1048 template <
typename Row>
1054 if (
const Dense_Ptr p = dynamic_cast<Dense_Ptr>(&y)) {
1057 else if (
const Sparse_Ptr p = dynamic_cast<Sparse_Ptr>(&y)) {
1066 template <
typename Row>
1070 Coefficient_traits::const_reference c1,
1071 Coefficient_traits::const_reference c2,
1075 if (
const Dense_Ptr p = dynamic_cast<Dense_Ptr>(&y)) {
1078 else if (
const Sparse_Ptr p = dynamic_cast<Sparse_Ptr>(&y)) {
1087 template <
typename Row>
1091 Coefficient_traits::const_reference c1,
1092 Coefficient_traits::const_reference c2,
1096 if (
const Dense_Ptr p = dynamic_cast<Dense_Ptr>(&y)) {
1097 linear_combine_lax(*p, c1, c2, start, end);
1099 else if (
const Sparse_Ptr p = dynamic_cast<Sparse_Ptr>(&y)) {
1100 linear_combine_lax(*p, c1, c2, start, end);
1108 template <
typename Row>
1114 if (
const Dense_Ptr p = dynamic_cast<Dense_Ptr>(&y)) {
1117 else if (
const Sparse_Ptr p = dynamic_cast<Sparse_Ptr>(&y)) {
1128 template <
typename Row>
1133 if (
const Dense_Ptr p = dynamic_cast<Dense_Ptr>(&y)) {
1136 else if (
const Sparse_Ptr p = dynamic_cast<Sparse_Ptr>(&y)) {
1145 template <
typename Row>
1151 if (
const Dense_Ptr p = dynamic_cast<Dense_Ptr>(&y)) {
1154 else if (
const Sparse_Ptr p = dynamic_cast<Sparse_Ptr>(&y)) {
1163 template <
typename Row>
1171 if (
const Dense_Ptr p = dynamic_cast<Dense_Ptr>(&y)) {
1172 scalar_product_assign(result, *p, start, end);
1174 else if (
const Sparse_Ptr p = dynamic_cast<Sparse_Ptr>(&y)) {
1175 scalar_product_assign(result, *p, start, end);
1183 template <
typename Row>
1190 if (
const Dense_Ptr p = dynamic_cast<Dense_Ptr>(&y)) {
1191 return scalar_product_sign(*p, start, end);
1193 else if (
const Sparse_Ptr p = dynamic_cast<Sparse_Ptr>(&y)) {
1194 return scalar_product_sign(*p, start, end);
1203 template <
typename Row>
1210 if (
const Dense_Ptr p = dynamic_cast<Dense_Ptr>(&y)) {
1211 return is_equal_to(*p, start, end);
1213 else if (
const Sparse_Ptr p = dynamic_cast<Sparse_Ptr>(&y)) {
1214 return is_equal_to(*p, start, end);
1223 template <
typename Row>
1227 Coefficient_traits::const_reference c1,
1228 Coefficient_traits::const_reference c2,
1232 if (
const Dense_Ptr p = dynamic_cast<Dense_Ptr>(&y)) {
1233 return is_equal_to(*p, c1, c2, start, end);
1235 else if (
const Sparse_Ptr p = dynamic_cast<Sparse_Ptr>(&y)) {
1236 return is_equal_to(*p, c1, c2, start, end);
1245 template <
typename Row>
1252 if (
const Dense_Ptr p = dynamic_cast<Dense_Ptr>(&y)) {
1253 return have_a_common_variable(*p, first, last);
1255 else if (
const Sparse_Ptr p = dynamic_cast<Sparse_Ptr>(&y)) {
1256 return have_a_common_variable(*p, first, last);
1265 template <
typename Row>
1271 template <
typename Row>
1277 template <
typename Row>
1283 template <
typename Row>
1286 : row(&r), itr(r.lower_bound(i)) {
1290 template <
typename Row>
1297 template <
typename Row>
1302 skip_zeroes_forward();
1305 template <
typename Row>
1310 skip_zeroes_backward();
1313 template <
typename Row>
1320 template <
typename Row>
1329 template <
typename Row>
1336 PPL_ASSERT(
row == p->
row);
1337 return itr == p->
itr;
1340 template <
typename Row>
1346 if (i !=
row.size() - 1) {
1352 template <
typename Row>
1360 if (str !=
"size") {
1365 if (!(s >> new_size)) {
1370 row.resize(new_size);
1387 template <
typename Row>
1395 #endif // !defined(PPL_Linear_Expression_Impl_templates_hh)
virtual Linear_Expression_Impl & operator+=(Coefficient_traits::const_reference n)
dimension_type max_space_dimension()
Returns the maximum space dimension this library can handle.
void construct(const Linear_Expression_Interface &e)
void swap(CO_Tree &x, CO_Tree &y)
A finite sequence of coefficients.
virtual void print(std::ostream &s) const
virtual void linear_combine(const Linear_Expression_Interface &y, Variable v)
size_t dimension_type
An unsigned integral type for representing space dimensions.
void linear_combine(Dense_Row &x, const Dense_Row &y, Coefficient_traits::const_reference coeff1, Coefficient_traits::const_reference coeff2)
#define PPL_DIRTY_TEMP_COEFFICIENT(id)
Declare a local variable named id, of type Coefficient, and containing an unknown initial value...
virtual bool have_a_common_variable(const Linear_Expression_Interface &x, Variable first, Variable last) const
void add_mul_assign(GMP_Integer &x, const GMP_Integer &y, const GMP_Integer &z)
virtual bool OK() const
Checks if all the invariants are satisfied.
std::ostream & operator<<(std::ostream &s, const Ask_Tell< D > &x)
A finite sparse sequence of coefficients.
virtual void sign_normalize()
void exact_div_assign(Checked_Number< T, Policy > &x, const Checked_Number< T, Policy > &y, const Checked_Number< T, Policy > &z)
virtual Linear_Expression_Impl & operator-=(Coefficient_traits::const_reference n)
virtual Variable variable() const
Returns the variable of the coefficient pointed to by *this.
virtual void exact_div_assign(Coefficient_traits::const_reference c, dimension_type start, dimension_type end)
A dimension of the vector space.
virtual void operator++()
virtual int compare(const Linear_Expression_Interface &y) const
The basic comparison function.
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
virtual Linear_Expression_Impl & operator*=(Coefficient_traits::const_reference n)
virtual void get_row(Dense_Row &r) const
Sets r to a copy of the row that implements *this.
virtual Linear_Expression_Impl & add_mul_assign(Coefficient_traits::const_reference n, const Variable v)
virtual bool ascii_load(std::istream &s)
Loads from s an ASCII representation (as produced by ascii_dump(std::ostream&) const) and sets *this ...
virtual const_iterator_interface * begin() const
virtual int scalar_product_sign(const Linear_Expression_Interface &y, dimension_type start, dimension_type end) const
Computes the sign of the sum of (*this)[i]*y[i], for each i in [start,end).
void skip_zeroes_forward()
virtual const_iterator_interface * end() const
virtual bool is_equal_to(const Linear_Expression_Interface &x) const
PPL_COEFFICIENT_TYPE Coefficient
An alias for easily naming the type of PPL coefficients.
virtual void operator--()
int compare(const Linear_Expression &x, const Linear_Expression &y)
virtual void set(dimension_type i, Coefficient_traits::const_reference n)
Sets the i-th coefficient to n.
Linear_Expression_Impl()
Default constructor: returns a copy of Linear_Expression_Impl::zero().
virtual void ascii_dump(std::ostream &s) const
Writes to s an ASCII representation of *this.
void neg_assign(GMP_Integer &x)
Coefficient_traits::const_reference Coefficient_zero()
Returns a const reference to a Coefficient with value 0.
The entire library is confined to this namespace.
virtual Linear_Expression_Impl & operator/=(Coefficient_traits::const_reference n)
virtual dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
virtual void mul_assign(Coefficient_traits::const_reference n, dimension_type start, dimension_type end)
Equivalent to (*this)[i] *= n, for each i in [start, end).
virtual Coefficient_traits::const_reference get(dimension_type i) const
Returns the i-th coefficient.
virtual bool operator==(const const_iterator_interface &x) const
Compares *this with x .
int cmp(const GMP_Integer &x, const GMP_Integer &y)
const_iterator(const Row &row, dimension_type i)
int sgn(Boundary_Type type, const T &x, const Info &info)
void sub_mul_assign(GMP_Integer &x, const GMP_Integer &y, const GMP_Integer &z)
void normalize2(Coefficient_traits::const_reference x, Coefficient_traits::const_reference y, Coefficient &n_x, Coefficient &n_y)
If is the GCD of x and y, the values of x and y divided by are assigned to n_x and n_y...
virtual const_iterator_interface * clone() const
virtual Linear_Expression_Impl & sub_mul_assign(Coefficient_traits::const_reference n, const Variable v)
virtual void linear_combine_lax(const Linear_Expression_Interface &y, Coefficient_traits::const_reference c1, Coefficient_traits::const_reference c2)
virtual void scalar_product_assign(Coefficient &result, const Linear_Expression_Interface &y, dimension_type start, dimension_type end) const
Sets results to the sum of (*this)[i]*y[i], for each i in [start,end).
virtual bool all_zeroes(const Variables_Set &vars) const
Returns true if the coefficient of each variable in vars[i] is .
Enable_If< Is_Native_Or_Checked< To >::value &&Is_Special< From >::value, Result >::type construct(To &to, const From &, Rounding_Dir dir)
Coefficient_traits::const_reference Coefficient_one()
Returns a const reference to a Coefficient with value 1.
virtual const_iterator_interface * lower_bound(Variable v) const
virtual void permute_space_dimensions(const std::vector< Variable > &cycle)
Permutes the space dimensions of the expression.
virtual reference operator*() const
Returns the current element.