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>
|
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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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( );
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue