[PPL-devel] [GIT] ppl/ppl(pip): Fully normalize artificial parameters on construction.
Enea Zaffanella
zaffanella at cs.unipr.it
Fri Feb 4 11:26:41 CET 2011
Module: ppl/ppl
Branch: pip
Commit: 35d2df08098d17c0a57b5df0d9f7f27512d0c5f1
URL: http://www.cs.unipr.it/git/gitweb.cgi?p=ppl/ppl.git;a=commit;h=35d2df08098d17c0a57b5df0d9f7f27512d0c5f1
Author: Enea Zaffanella <zaffanella at cs.unipr.it>
Date: Fri Feb 4 09:52:58 2011 +0100
Fully normalize artificial parameters on construction.
When in noisy mode, print normalized parameters.
---
src/PIP_Tree.cc | 71 +++++++++++++++++++++++++++++++++++++++++-----
src/PIP_Tree.inlines.hh | 17 -----------
2 files changed, 63 insertions(+), 25 deletions(-)
diff --git a/src/PIP_Tree.cc b/src/PIP_Tree.cc
index 8c22a25..b9a818d 100644
--- a/src/PIP_Tree.cc
+++ b/src/PIP_Tree.cc
@@ -29,6 +29,9 @@ site: http://www.cs.unipr.it/ppl/ . */
#include <memory>
#include <map>
+// #define NOISY_PIP
+// #define VERY_NOISY_PIP 0
+
namespace Parma_Polyhedra_Library {
namespace {
@@ -802,6 +805,60 @@ PIP_Tree_Node::PIP_Tree_Node(const PIP_Tree_Node& y)
artificial_parameters(y.artificial_parameters) {
}
+PIP_Tree_Node::Artificial_Parameter
+::Artificial_Parameter(const Linear_Expression& expr,
+ Coefficient_traits::const_reference den)
+ : Linear_Expression(expr), denom(den) {
+ if (denom == 0)
+ throw std::invalid_argument("PIP_Tree_Node::Artificial_Parameter(e, d): "
+ "denominator d is zero.");
+
+ // Normalize if needed.
+ // FIXME: Provide a proper normalization helper.
+ Linear_Expression& param_expr = *this;
+ if (denom < 0) {
+ neg_assign(denom);
+ param_expr *= -1;
+ }
+
+ // Compute GCD of parameter expression and denum.
+ PPL_DIRTY_TEMP_COEFFICIENT(gcd);
+ gcd = denom;
+ gcd_assign(gcd, param_expr.inhomogeneous_term(), gcd);
+ if (gcd == 1)
+ return;
+ const dimension_type space_dim = param_expr.space_dimension();
+ for (dimension_type i = space_dim; i-- > 0; ) {
+ Coefficient_traits::const_reference
+ e_i = param_expr.coefficient(Variable(i));
+ if (e_i != 0) {
+ gcd_assign(gcd, e_i, gcd);
+ if (gcd == 1)
+ return;
+ }
+ }
+
+ // Divide coefficients and denominator by their (non-trivial) GCD.
+ PPL_ASSERT(gcd > 1);
+ Linear_Expression normalized(0 * Variable(space_dim-1));
+ PPL_DIRTY_TEMP_COEFFICIENT(coeff);
+ exact_div_assign(coeff, param_expr.inhomogeneous_term(), gcd);
+ normalized += coeff;
+ for (dimension_type i = space_dim; i-- > 0; ) {
+ Coefficient_traits::const_reference
+ e_i = param_expr.coefficient(Variable(i));
+ if (e_i != 0) {
+ exact_div_assign(coeff, e_i, gcd);
+ add_mul_assign(normalized, coeff, Variable(i));
+ }
+ }
+ // Replace the parameter expression with the normalized one.
+ param_expr = normalized;
+ exact_div_assign(denom, denom, gcd);
+
+ PPL_ASSERT(OK());
+}
+
bool
PIP_Tree_Node::Artificial_Parameter
::operator==(const PIP_Tree_Node::Artificial_Parameter& y) const {
@@ -2262,11 +2319,11 @@ PIP_Solution_Node::solve(const PIP_Problem& pip,
const dimension_type num_params = tableau.t.num_columns();
Coefficient_traits::const_reference tableau_den = tableau.denominator();
-#ifdef NOISY_PIP
+#ifdef VERY_NOISY_PIP
tableau.ascii_dump(std::cerr);
std::cerr << "context ";
context.ascii_dump(std::cerr);
-#endif
+#endif // #ifdef VERY_NOISY_PIP
// (Re-) Compute parameter row signs.
// While at it, keep track of the first parameter rows
@@ -2407,7 +2464,7 @@ PIP_Solution_Node::solve(const PIP_Problem& pip,
#ifdef NOISY_PIP
std::cerr << "Pivot (pi, pj) = (" << pi << ", " << pj << ")\n";
-#endif
+#endif // #ifdef NOISY_PIP
// Normalize the tableau before pivoting.
tableau.normalize();
@@ -2617,7 +2674,7 @@ PIP_Solution_Node::solve(const PIP_Problem& pip,
std::cerr << "Found row (" << i_neg << ") with mixed parameter sign "
<< "and negative variable coefficients.\n"
<< "==> adding tautology.\n";
-#endif
+#endif // #ifdef NOISY_PIP
Row copy = tableau.t[i_neg];
copy.normalize();
context.add_row(copy);
@@ -2994,8 +3051,7 @@ PIP_Solution_Node::generate_cut(const dimension_type index,
#ifdef NOISY_PIP
using namespace IO_Operators;
std::cout << "Re-using parameter " << Variable(ap_column)
- << " = (" << expr << ")/" << den
- << std::endl;
+ << " = " << ap << std::endl;
#endif // #ifdef NOISY_PIP
ap_column = ap_column - num_vars + 1;
}
@@ -3010,8 +3066,7 @@ PIP_Solution_Node::generate_cut(const dimension_type index,
using namespace IO_Operators;
std::cout << "Creating new parameter "
<< Variable(space_dimension)
- << " = (" << expr << ")/" << den
- << std::endl;
+ << " = " << ap << std::endl;
#endif // #ifdef NOISY_PIP
++space_dimension;
ap_column = num_params;
diff --git a/src/PIP_Tree.inlines.hh b/src/PIP_Tree.inlines.hh
index ef0e8e0..ddd1bc0 100644
--- a/src/PIP_Tree.inlines.hh
+++ b/src/PIP_Tree.inlines.hh
@@ -111,23 +111,6 @@ PIP_Tree_Node::Artificial_Parameter::Artificial_Parameter()
inline
PIP_Tree_Node::Artificial_Parameter
-::Artificial_Parameter(const Linear_Expression& expr,
- Coefficient_traits::const_reference den)
- : Linear_Expression(expr), denom(den) {
- if (denom == 0)
- throw std::invalid_argument("PIP_Tree_Node::Artificial_Parameter(e, d): "
- "denominator d is zero.");
- // Normalize if needed.
- if (denom < 0) {
- neg_assign(denom);
- Linear_Expression& e = *this;
- e *= -1;
- }
- PPL_ASSERT(OK());
-}
-
-inline
-PIP_Tree_Node::Artificial_Parameter
::Artificial_Parameter(const Artificial_Parameter& y)
: Linear_Expression(y), denom(y.denom) {
PPL_ASSERT(OK());
More information about the PPL-devel
mailing list