
Module: ppl/ppl Branch: floating_point Commit: c9ec5bc2cb674fd20a8cdc4c85b93361428ed8e2 URL: http://www.cs.unipr.it/git/gitweb.cgi?p=ppl/ppl.git;a=commit;h=c9ec5bc2cb674...
Author: Roberto Bagnara bagnara@cs.unipr.it Date: Tue Aug 18 09:57:45 2009 +0200
Several corrections and improvements.
---
src/Linear_Form.defs.hh | 7 +--- src/Linear_Form.inlines.hh | 11 +----- src/Linear_Form.templates.hh | 68 ++++++++++++++++++++++++-------------- tests/Polyhedron/linearform1.cc | 24 +++++++++++++- 4 files changed, 70 insertions(+), 40 deletions(-)
diff --git a/src/Linear_Form.defs.hh b/src/Linear_Form.defs.hh index bbd2869..65cd073 100644 --- a/src/Linear_Form.defs.hh +++ b/src/Linear_Form.defs.hh @@ -268,9 +268,9 @@ public: Thrown if the space dimension of \p v exceeds <CODE>Linear_Form::max_space_dimension()</CODE>. */ - explicit Linear_Form(Variable v); + Linear_Form(Variable v);
- //! Builds the linear form corresponding to the linear expression \p e. + //! Builds a linear form approximating the linear expression \p e. Linear_Form(const Linear_Expression& e);
//! Returns the maximum space dimension a Linear_Form can handle. @@ -319,9 +319,6 @@ private: //! The container vector. vec_type vec;
- //! Copy constructor with a specified space dimension. - Linear_Form(const Linear_Form& f, dimension_type sz); - //! Implementation sizing constructor. /*! The bool parameter is just to avoid problems with diff --git a/src/Linear_Form.inlines.hh b/src/Linear_Form.inlines.hh index 82136cf..3280eef 100644 --- a/src/Linear_Form.inlines.hh +++ b/src/Linear_Form.inlines.hh @@ -38,7 +38,7 @@ template <typename C> inline Linear_Form<C>::Linear_Form() : vec(1, zero) { - vec.reserve(compute_capacity(1, vec_type::max_size())); + vec.reserve(compute_capacity(1, vec_type().max_size())); }
template <typename C> @@ -75,16 +75,9 @@ Linear_Form<C>::extend(dimension_type sz) {
template <typename C> inline -Linear_Form<C>::Linear_Form(const Linear_Form& f, dimension_type sz) - : vec(f.vec) { - extend(sz); -} - -template <typename C> -inline Linear_Form<C>::Linear_Form(const C& n) : vec(1, n) { - vec.reserve(compute_capacity(1, vec_type::max_size())); + vec.reserve(compute_capacity(1, vec_type().max_size())); }
template <typename C> diff --git a/src/Linear_Form.templates.hh b/src/Linear_Form.templates.hh index c30fb4e..6ac4b38 100644 --- a/src/Linear_Form.templates.hh +++ b/src/Linear_Form.templates.hh @@ -23,6 +23,7 @@ site: http://www.cs.unipr.it/ppl/ . */ #ifndef PPL_Linear_Form_templates_hh #define PPL_Linear_Form_templates_hh 1
+#include "Linear_Expression.defs.hh" #include <stdexcept> #include <iostream>
@@ -30,16 +31,16 @@ namespace Parma_Polyhedra_Library {
template <typename C> Linear_Form<C>::Linear_Form(const Variable v) - : vec(v.space_dimension() <= max_space_dimension() - ? v.space_dimension()+1 - : (throw std::length_error("Linear_Form<C>::" - "Linear_Form(v):\n" - "v exceeds the maximum allowed " - "space dimension."), - v.space_dimension()+1) - , zero) { - vec.reserve(compute_capacity(v.space_dimension()+1, vec_type().max_size())); - vec[v.space_dimension()] += 1.0; + : vec() { + const dimension_type space_dim = v.space_dimension(); + if (space_dim > max_space_dimension()) + throw std::length_error("Linear_Form<C>::" + "Linear_Form(v):\n" + "v exceeds the maximum allowed " + "space dimension."); + vec.reserve(compute_capacity(space_dim+1, vec_type().max_size())); + vec.resize(space_dim+1, zero); + vec[v.space_dimension()] = 1.0; }
template <typename C> @@ -53,7 +54,7 @@ Linear_Form<C>::Linear_Form(const Variable v, const Variable w) "Linear_Form(v, w):\n" "v or w exceed the maximum allowed " "space dimension."); - vec.reserve(compute_capacity(space_dim+1, vec_type::max_size())); + vec.reserve(compute_capacity(space_dim+1, vec_type().max_size())); vec.resize(space_dim+1, zero); if (v_space_dim != w_space_dim) { vec[v_space_dim] = 1.0; @@ -61,6 +62,22 @@ Linear_Form<C>::Linear_Form(const Variable v, const Variable w) } }
+template <typename C> +Linear_Form<C>::Linear_Form(const Linear_Expression& e) + : vec() { + const dimension_type space_dim = e.space_dimension(); + if (space_dim > max_space_dimension()) + throw std::length_error("Linear_Form<C>::" + "Linear_Form(e):\n" + "e exceeds the maximum allowed " + "space dimension."); + vec.reserve(compute_capacity(space_dim+1, vec_type().max_size())); + vec.resize(space_dim+1); + for (dimension_type i = space_dim; i-- > 0; ) + vec[i+1] = e.coefficient(Variable(i)); + vec[0] = e.inhomogeneous_term(); +} + /*! \relates Parma_Polyhedra_Library::Linear_Form */ template <typename C> Linear_Form<C> @@ -106,8 +123,9 @@ operator+(const Variable v, const Linear_Form<C>& f) { "operator+(v, f):\n" "v exceeds the maximum allowed " "space dimension."); - const dimension_type space_dim = std::max(v_space_dim, f.space_dimension()); - Linear_Form<C> r(f, space_dim+1); + Linear_Form<C> r(f); + if (v_space_dim > f.space_dimension()) + r.extend(v_space_dim+1); r[v_space_dim] += 1.0; return r; } @@ -177,9 +195,9 @@ operator-(const Variable v, const Linear_Form<C>& f) { "operator-(v, e):\n" "v exceeds the maximum allowed " "space dimension."); - const dimension_type f_space_dim = f.space_dimension(); - const dimension_type space_dim = std::max(v_space_dim, f_space_dim); - Linear_Form<C> r(f, space_dim+1); + Linear_Form<C> r(f); + if (v_space_dim > f.space_dimension()) + r.extend(v_space_dim+1); for (dimension_type i = f.size(); i-- > 0; ) r[i].neg_assign(r[i]); r[v_space_dim] += 1.0; @@ -196,8 +214,9 @@ operator-(const Linear_Form<C>& f, const Variable v) { "operator-(e, v):\n" "v exceeds the maximum allowed " "space dimension."); - const dimension_type space_dim = std::max(v_space_dim, f.space_dimension()); - Linear_Form<C> r(f, space_dim+1); + Linear_Form<C> r(f); + if (v_space_dim > f.space_dimension()) + r.extend(v_space_dim+1); r[v_space_dim] -= 1.0; return r; } @@ -246,8 +265,7 @@ operator+=(Linear_Form<C>& f, const Variable v) { throw std::length_error("Linear_Form<C>& " "operator+=(e, v):\n" "v exceeds the maximum allowed space dimension."); - const dimension_type f_size = f.size(); - if (f_size <= v_space_dim) + if (v_space_dim > f.space_dimension()) f.extend(v_space_dim+1); f[v_space_dim] += 1.0; return f; @@ -275,8 +293,7 @@ operator-=(Linear_Form<C>& f, const Variable v) { throw std::length_error("Linear_Form<C>& " "operator-=(e, v):\n" "v exceeds the maximum allowed space dimension."); - const dimension_type f_size = f.size(); - if (f_size <= v_space_dim) + if (v_space_dim > f.space_dimension()) f.extend(v_space_dim+1); f[v_space_dim] -= 1.0; return f; @@ -346,10 +363,11 @@ IO_Operators::operator<<(std::ostream& s, const Linear_Form<C>& f) { else { if (fv == -1.0) s << " - "; - else if (fv != 1.0) - s << fv << "*"; - else + else { s << " + "; + if (fv != 1.0) + s << fv << "*"; + } } s << Variable(v); } diff --git a/tests/Polyhedron/linearform1.cc b/tests/Polyhedron/linearform1.cc index 0eeb6d9..33395d1 100644 --- a/tests/Polyhedron/linearform1.cc +++ b/tests/Polyhedron/linearform1.cc @@ -166,6 +166,28 @@ test05() { return ok; }
+bool +test06() { + Variable A(0); + Variable B(1); + Variable C(16); + Variable D(120); + + Linear_Form<db_r_oc> f = A + 2*B + 16*C + 120*D; + + Linear_Form<db_r_oc> known_result = A; + known_result += db_r_oc(2) * Linear_Form<db_r_oc>(B); + known_result += db_r_oc(16) * Linear_Form<db_r_oc>(C); + known_result += db_r_oc(120) * Linear_Form<db_r_oc>(D); + + bool ok = (f == known_result); + + nout << "*** known_result ***" << endl + << known_result << endl; + + return ok; +} + } // namespace
BEGIN_MAIN @@ -173,5 +195,5 @@ BEGIN_MAIN DO_TEST(test02); DO_TEST(test03); DO_TEST(test04); - DO_TEST(test05); + DO_TEST(test06); END_MAIN