mirror of https://github.com/CGAL/cgal
- Unbounded_direction_iterator refactored; it now uses the
Transform_diff_const_iterator
This commit is contained in:
parent
2b8cc00755
commit
6a05b09d69
|
|
@ -42,6 +42,9 @@ namespace QP_solution_detail {
|
|||
|
||||
template <typename ET>
|
||||
class Value_by_index;
|
||||
|
||||
template <typename ET>
|
||||
class Unbounded_direction_by_index;
|
||||
}
|
||||
|
||||
// global status type
|
||||
|
|
@ -81,13 +84,19 @@ public:
|
|||
|
||||
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;
|
||||
|
||||
typedef Join_input_iterator_1< Variable_numerator_iterator,
|
||||
Quotient_maker >
|
||||
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:
|
||||
|
||||
// virtual access functions to solution that will
|
||||
|
|
@ -95,6 +104,7 @@ public:
|
|||
virtual Quotient<ET> 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<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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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<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;
|
||||
|
||||
// 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( );
|
||||
|
|
|
|||
|
|
@ -24,101 +24,18 @@
|
|||
#define CGAL_QP_SOLVER_UNBOUNDED_DIRECTION_H
|
||||
|
||||
CGAL_BEGIN_NAMESPACE
|
||||
|
||||
namespace QP_solver_impl {
|
||||
|
||||
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
|
||||
template < typename Q, typename ET, typename Tags >
|
||||
ET QP_solver<Q, ET, Tags>::unbounded_direction_value(int i) 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
|
||||
|
||||
#endif // CGAL_QP_SOLVER_UNBOUNDED_DIRECTION_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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue