- Unbounded_direction_iterator refactored; it now uses the

Transform_diff_const_iterator
This commit is contained in:
Bernd Gärtner 2006-09-28 16:04:06 +00:00
parent 2b8cc00755
commit 6a05b09d69
4 changed files with 63 additions and 108 deletions

View File

@ -42,6 +42,9 @@ namespace QP_solution_detail {
template <typename ET> template <typename ET>
class Value_by_index; class Value_by_index;
template <typename ET>
class Unbounded_direction_by_index;
} }
// global status type // global status type
@ -81,13 +84,19 @@ public:
typedef typename QP_solution_detail::Value_by_index<ET> Value_by_index; typedef typename QP_solution_detail::Value_by_index<ET> Value_by_index;
typedef Join_input_iterator_1< Original_index_const_iterator,Value_by_index > typedef Transform_diff_const_iterator<int, Value_by_index>
Variable_numerator_iterator; Variable_numerator_iterator;
typedef Join_input_iterator_1< Variable_numerator_iterator, typedef Join_input_iterator_1< Variable_numerator_iterator,
Quotient_maker > Quotient_maker >
Variable_value_iterator; Variable_value_iterator;
typedef typename QP_solution_detail::Unbounded_direction_by_index<ET>
Unbounded_direction_by_index;
typedef Transform_diff_const_iterator<int, Unbounded_direction_by_index>
Unbounded_direction_iterator;
public: public:
// virtual access functions to solution that will // virtual access functions to solution that will
@ -95,6 +104,7 @@ public:
virtual Quotient<ET> solution() const = 0; virtual Quotient<ET> solution() const = 0;
virtual QP_status status() const = 0; virtual QP_status status() const = 0;
virtual ET variable_value (int i) 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_begin() const = 0;
virtual Variable_value_iterator original_variable_values_end() const = 0; virtual Variable_value_iterator original_variable_values_end() const = 0;
virtual Index_const_iterator virtual Index_const_iterator
@ -285,6 +295,28 @@ namespace QP_solution_detail {
{ {
return s->variable_value(i); 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<ET> 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; const QP* s;
}; };

View File

@ -616,14 +616,12 @@ public:
Variable_numerator_iterator Variable_numerator_iterator
original_variables_numerator_begin( ) const original_variables_numerator_begin( ) const
{ return Variable_numerator_iterator { return Variable_numerator_iterator (0, Value_by_index(this));}
( Original_index_const_iterator(0), Value_by_index(this));}
Variable_numerator_iterator Variable_numerator_iterator
original_variables_numerator_end ( ) const original_variables_numerator_end ( ) const
{ return Variable_numerator_iterator { return Variable_numerator_iterator (0, Value_by_index(this)) + qp_n;}
( Original_index_const_iterator(0) + qp_n, Value_by_index(this));}
Variable_value_iterator Variable_value_iterator
original_variable_values_begin( ) const original_variable_values_begin( ) const
@ -818,8 +816,10 @@ public:
} }
public: public:
friend class QP_solver_impl::Unbounded_direction_iterator<Q, ET, Tags>;
typedef QP_solver_impl::Unbounded_direction_iterator<Q, ET, Tags> typedef typename Base::Unbounded_direction_by_index
Unbounded_direction_by_index;
typedef typename Base::Unbounded_direction_iterator
Unbounded_direction_iterator; Unbounded_direction_iterator;
// Returns an iterator over an unbounded direction, that is a |n|-vector // 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 // is a feasible point of the problem and the objective function on
// this ray is unbounded (i.e., it decreases when t increases). // 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 // Returns the past-the-end iterator corresponding to
// unbounded_direction_begin(). // 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: private:
@ -1227,6 +1231,8 @@ private:
public: public:
// for original variables // for original variables
ET variable_value(int i) const; ET variable_value(int i) const;
ET unbounded_direction_value(int i) const;
private: private:
// check basis inverse // check basis inverse
bool check_basis_inverse( ); bool check_basis_inverse( );

View File

@ -24,101 +24,18 @@
#define CGAL_QP_SOLVER_UNBOUNDED_DIRECTION_H #define CGAL_QP_SOLVER_UNBOUNDED_DIRECTION_H
CGAL_BEGIN_NAMESPACE CGAL_BEGIN_NAMESPACE
template < typename Q, typename ET, typename Tags >
namespace QP_solver_impl { ET QP_solver<Q, ET, Tags>::unbounded_direction_value(int i) const
template<typename Q, typename ET, typename Tags>
class Unbounded_direction_iterator {
private:
const QP_solver<Q, ET, Tags> &solver; // reference to solver
int pos; // current position
public: // public types
typedef Unbounded_direction_iterator<Q, ET, Tags> Self;
typedef std::random_access_iterator_tag iterator_category;
typedef ET value_type;
typedef int difference_type;
private: // constructor
friend class QP_solver<Q, ET, Tags>;
// 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<Q, ET, Tags>& 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 Q, typename ET, typename Tags>
typename QP_solver<Q, ET, Tags>::Unbounded_direction_iterator
QP_solver<Q, ET, Tags>::unbounded_direction_begin() const
{ {
return QP_solver_impl::Unbounded_direction_iterator<Q, ET, Tags>(*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 Q, typename ET, typename Tags>
typename QP_solver<Q, ET, Tags>::Unbounded_direction_iterator
QP_solver<Q, ET, Tags>::unbounded_direction_end() const
{
return QP_solver_impl::Unbounded_direction_iterator<Q, ET, Tags>(*this,qp_n);
}
CGAL_END_NAMESPACE CGAL_END_NAMESPACE
#endif // CGAL_QP_SOLVER_UNBOUNDED_DIRECTION_H #endif // CGAL_QP_SOLVER_UNBOUNDED_DIRECTION_H

View File

@ -126,15 +126,14 @@ public:
// construction // construction
Transform_diff_const_iterator ( ) Transform_diff_const_iterator ( )
: base_diff(), diff(), op() : base_diff(), diff(), op(), val()
{} {}
Transform_diff_const_iterator (Diff n) Transform_diff_const_iterator (Diff n, Op operation = Op())
: base_diff(n), diff(n), op() : base_diff(n), diff(n), op(operation), val()
{ } { }
const Val& operator * ( ) const { return op(diff-base_diff); } const Val& operator * ( ) const { val = op(diff-base_diff); return val; }
// const Val* operator -> ( ) const { return op(diff-base_diff); }
// equality operator // equality operator
bool operator == ( const Self& x) const { return ( diff==x.diff); } bool operator == ( const Self& x) const { return ( diff==x.diff); }
@ -153,7 +152,7 @@ public:
// random access operations // random access operations
// ------------------------ // ------------------------
// access // 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 // less operator
bool operator < ( const Self& x) const { return ( diff < x.diff);} bool operator < ( const Self& x) const { return ( diff < x.diff);}
@ -171,6 +170,7 @@ private:
Diff base_diff; Diff base_diff;
Diff diff; Diff diff;
Op op; Op op;
mutable Val val;
}; };