diff --git a/QP_solver/include/CGAL/QP_solution.h b/QP_solver/include/CGAL/QP_solution.h index 0b2e3f6c58c..212526bc707 100644 --- a/QP_solver/include/CGAL/QP_solution.h +++ b/QP_solver/include/CGAL/QP_solution.h @@ -42,6 +42,9 @@ namespace QP_solution_detail { template class Value_by_index; + + template + class Unbounded_direction_by_index; } // global status type @@ -81,13 +84,19 @@ public: typedef typename QP_solution_detail::Value_by_index Value_by_index; - typedef Join_input_iterator_1< Original_index_const_iterator,Value_by_index > + typedef Transform_diff_const_iterator Variable_numerator_iterator; typedef Join_input_iterator_1< Variable_numerator_iterator, Quotient_maker > Variable_value_iterator; + typedef typename QP_solution_detail::Unbounded_direction_by_index + Unbounded_direction_by_index; + + typedef Transform_diff_const_iterator + Unbounded_direction_iterator; + public: // virtual access functions to solution that will @@ -95,6 +104,7 @@ public: virtual Quotient solution() const = 0; virtual QP_status status() const = 0; virtual ET variable_value (int i) const = 0; + virtual ET unbounded_direction_value(int i) const = 0; virtual Variable_value_iterator original_variable_values_begin() const = 0; virtual Variable_value_iterator original_variable_values_end() const = 0; virtual Index_const_iterator @@ -285,6 +295,28 @@ namespace QP_solution_detail { { return s->variable_value(i); } + + const QP* s; + }; + + // Unbounded_direction_by_index + // ---------------------------- + template < typename ET> + class Unbounded_direction_by_index : public std::unary_function< int, ET> + { + public: + typedef QP_solver_base QP; + typedef ET result_type; + + Unbounded_direction_by_index(const QP* solver) + : s (solver) + {} + + result_type operator () ( int i) const + { + return s->unbounded_direction_value(i); + } + const QP* s; }; diff --git a/QP_solver/include/CGAL/QP_solver.h b/QP_solver/include/CGAL/QP_solver.h index 76602722aac..10c8fd13d3f 100644 --- a/QP_solver/include/CGAL/QP_solver.h +++ b/QP_solver/include/CGAL/QP_solver.h @@ -616,14 +616,12 @@ public: Variable_numerator_iterator original_variables_numerator_begin( ) const - { return Variable_numerator_iterator - ( Original_index_const_iterator(0), Value_by_index(this));} + { return Variable_numerator_iterator (0, Value_by_index(this));} Variable_numerator_iterator original_variables_numerator_end ( ) const - { return Variable_numerator_iterator - ( Original_index_const_iterator(0) + qp_n, Value_by_index(this));} + { return Variable_numerator_iterator (0, Value_by_index(this)) + qp_n;} Variable_value_iterator original_variable_values_begin( ) const @@ -818,8 +816,10 @@ public: } public: - friend class QP_solver_impl::Unbounded_direction_iterator; - typedef QP_solver_impl::Unbounded_direction_iterator + + typedef typename Base::Unbounded_direction_by_index + Unbounded_direction_by_index; + typedef typename Base::Unbounded_direction_iterator Unbounded_direction_iterator; // Returns an iterator over an unbounded direction, that is a |n|-vector @@ -829,11 +829,15 @@ public: // // is a feasible point of the problem and the objective function on // this ray is unbounded (i.e., it decreases when t increases). - Unbounded_direction_iterator unbounded_direction_begin() const; + Unbounded_direction_iterator unbounded_direction_begin() const + { return Unbounded_direction_iterator + (0, Unbounded_direction_by_index(this));} // Returns the past-the-end iterator corresponding to // unbounded_direction_begin(). - Unbounded_direction_iterator unbounded_direction_end() const; + Unbounded_direction_iterator unbounded_direction_end() const + { return Unbounded_direction_iterator + (0, Unbounded_direction_by_index(this)) + qp_n;} private: @@ -1227,6 +1231,8 @@ private: public: // for original variables ET variable_value(int i) const; + ET unbounded_direction_value(int i) const; + private: // check basis inverse bool check_basis_inverse( ); diff --git a/QP_solver/include/CGAL/QP_solver/Unbounded_direction.h b/QP_solver/include/CGAL/QP_solver/Unbounded_direction.h index b2f91321568..1738afec352 100644 --- a/QP_solver/include/CGAL/QP_solver/Unbounded_direction.h +++ b/QP_solver/include/CGAL/QP_solver/Unbounded_direction.h @@ -24,101 +24,18 @@ #define CGAL_QP_SOLVER_UNBOUNDED_DIRECTION_H CGAL_BEGIN_NAMESPACE - -namespace QP_solver_impl { - - template - class Unbounded_direction_iterator { - private: - const QP_solver &solver; // reference to solver - int pos; // current position - - public: // public types - typedef Unbounded_direction_iterator Self; - typedef std::random_access_iterator_tag iterator_category; - typedef ET value_type; - typedef int difference_type; - - private: // constructor - friend class QP_solver; - - // Note: The solver's routines unbounded_direction_begin/end() - // construct instances of this class such that the range spanned - // by the constructed iterators has length qp_n. - Unbounded_direction_iterator(const QP_solver& solver, - int pos) : - solver(solver), pos(pos) { - CGAL_qpe_assertion(pos <= solver.qp_n); - } - - public: - bool operator==(const Self& i) const - { return pos == i.pos; } - - bool operator!=(const Self& i) const - { return !(*this == i); } - - bool operator< (const Self& i) const - { return pos < i.pos; } - - value_type operator*() const - { - // Note: the vector we return here is described in documentation/ - // Test_suite.tex. - CGAL_qpe_assertion(pos < solver.qp_n); - CGAL_qpe_assertion(solver.direction == 1 || solver.direction == -1); - - const int i = solver.in_B[pos]; - if (i >= 0) { // basic variable? - return solver.direction == 1 ? solver.q_x_O[i] : -solver.q_x_O[i]; - } else { // non-basic variable? - if (pos == solver.j) // most recent entering variable? - return solver.direction == 1 ? -solver.d : solver.d; - return solver.et0; - } - return solver.et0; - } - - Self& operator++( ) { ++pos; return *this; } - Self operator++(int) { Self tmp = *this; ++(*this); return tmp; } - Self& operator--( ) { --pos; return *this; } - Self operator--(int) { Self tmp = *this; --(*this); return tmp; } - - value_type operator[](difference_type i) const - { - // todo: could be optimized slightly. - return *(*this + i); - } - - Self& operator+=(difference_type n) { pos += n; return *this; } - Self& operator-=(difference_type n) { pos -= n; return *this; } - Self operator+ (difference_type n) const { - Self tmp = *this; - return tmp += n; - } - Self operator- (difference_type n) const { - Self tmp = *this; - return tmp -= n; - } - difference_type operator-(const Self& i) const { return pos - i.pos; } - }; - -} // namespace QP_solver_impl - -template -typename QP_solver::Unbounded_direction_iterator -QP_solver::unbounded_direction_begin() const +template < typename Q, typename ET, typename Tags > +ET QP_solver::unbounded_direction_value(int i) const { - return QP_solver_impl::Unbounded_direction_iterator(*this,0); + if (is_basic(i)) { // basic variable? + return direction == 1 ? q_x_O[in_B[i]] : -q_x_O[in_B[i]]; + } else { // non-basic variable? + if (i == j) // most recent entering variable? + return direction == 1 ? -d : d; + return et0; + } + return et0; } - -template -typename QP_solver::Unbounded_direction_iterator -QP_solver::unbounded_direction_end() const -{ - return QP_solver_impl::Unbounded_direction_iterator(*this,qp_n); -} - CGAL_END_NAMESPACE #endif // CGAL_QP_SOLVER_UNBOUNDED_DIRECTION_H diff --git a/QP_solver/include/CGAL/QP_solver/iterator.h b/QP_solver/include/CGAL/QP_solver/iterator.h index f1a9270075f..2c09c0b3f33 100644 --- a/QP_solver/include/CGAL/QP_solver/iterator.h +++ b/QP_solver/include/CGAL/QP_solver/iterator.h @@ -126,15 +126,14 @@ public: // construction Transform_diff_const_iterator ( ) - : base_diff(), diff(), op() + : base_diff(), diff(), op(), val() {} - Transform_diff_const_iterator (Diff n) - : base_diff(n), diff(n), op() + Transform_diff_const_iterator (Diff n, Op operation = Op()) + : base_diff(n), diff(n), op(operation), val() { } - const Val& operator * ( ) const { return op(diff-base_diff); } - // const Val* operator -> ( ) const { return op(diff-base_diff); } + const Val& operator * ( ) const { val = op(diff-base_diff); return val; } // equality operator bool operator == ( const Self& x) const { return ( diff==x.diff); } @@ -153,7 +152,7 @@ public: // random access operations // ------------------------ // access - const Val& operator [] ( Diff i) const { return op(i-base_diff); } + const Val& operator [] ( Diff i) const { val= op(i-base_diff); return val; } // less operator bool operator < ( const Self& x) const { return ( diff < x.diff);} @@ -171,6 +170,7 @@ private: Diff base_diff; Diff diff; Op op; + mutable Val val; };