282 lines
7.7 KiB
C++
282 lines
7.7 KiB
C++
// Copyright (c) 1997-2007 ETH Zurich (Switzerland).
|
|
// All rights reserved.
|
|
//
|
|
// This file is part of CGAL (www.cgal.org).
|
|
//
|
|
// $URL: https://github.com/CGAL/cgal/blob/v5.1/QP_solver/include/CGAL/QP_solver/functors.h $
|
|
// $Id: functors.h 0779373 2020-03-26T13:31:46+01:00 Sébastien Loriot
|
|
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
|
//
|
|
//
|
|
// Author(s) : Sven Schoenherr
|
|
// Bernd Gaertner <gaertner@inf.ethz.ch>
|
|
// Franz Wessendorp
|
|
// Kaspar Fischer
|
|
|
|
#ifndef CGAL_QP_SOLVER_FUNCTORS_H
|
|
#define CGAL_QP_SOLVER_FUNCTORS_H
|
|
|
|
#include <CGAL/license/QP_solver.h>
|
|
|
|
|
|
#include <CGAL/QP_solver/basic.h>
|
|
#include <CGAL/function_objects.h>
|
|
#include <functional>
|
|
#include <iterator>
|
|
|
|
namespace CGAL {
|
|
|
|
// ==================
|
|
// class declarations
|
|
// ==================
|
|
template < class VectorIt,
|
|
bool check_lower = false, bool check_upper = false >
|
|
class QP_vector_accessor;
|
|
|
|
template < class MatrixIt,
|
|
bool check_1st_lower = false, bool check_1st_upper = false,
|
|
bool check_2nd_lower = false, bool check_2nd_upper = false >
|
|
class QP_matrix_accessor;
|
|
|
|
template < class MatrixIt, typename ET >
|
|
class QP_matrix_pairwise_accessor;
|
|
|
|
|
|
template < class RndAccIt >
|
|
class Value_by_basic_index;
|
|
|
|
template<typename Map>
|
|
class Map_with_default;
|
|
|
|
// =====================
|
|
// class implementations
|
|
// =====================
|
|
|
|
// -------------------
|
|
// QP_vector_accessor
|
|
// -------------------
|
|
template < class VectorIt, bool check_lower, bool check_upper >
|
|
class QP_vector_accessor : public CGAL::cpp98::unary_function<
|
|
int, typename std::iterator_traits<VectorIt>::value_type > {
|
|
|
|
public:
|
|
typedef typename
|
|
CGAL::cpp98::unary_function<
|
|
int,
|
|
typename std::iterator_traits<VectorIt>::value_type >::result_type
|
|
result_type;
|
|
QP_vector_accessor( VectorIt it, int lower = 0, int upper = 0)
|
|
: z( 0), v( it), l(lower), u(upper)
|
|
{}
|
|
|
|
result_type operator ( ) ( int i) const
|
|
{
|
|
if ( check_lower && i < l) return z;
|
|
if ( check_upper && i >= u) return z;
|
|
return v[ i];
|
|
}
|
|
|
|
private:
|
|
const result_type z;
|
|
VectorIt v;
|
|
int l;
|
|
int u;
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// -------------------
|
|
// QP_matrix_accessor
|
|
// -------------------
|
|
template < class MatrixIt, bool check_1st_lower, bool check_1st_upper,
|
|
bool check_2nd_lower, bool check_2nd_upper >
|
|
class QP_matrix_accessor {
|
|
|
|
public:
|
|
typedef int argument1_type;
|
|
typedef int argument2_type;
|
|
typedef typename std::iterator_traits<MatrixIt>::value_type VectorIt;
|
|
typedef typename std::iterator_traits<VectorIt>::value_type result_type;
|
|
|
|
QP_matrix_accessor( MatrixIt it, int lower_1 = 0, int upper_1 = 0,
|
|
int lower_2 = 0, int upper_2 = 0)
|
|
: z( 0), m( it)
|
|
{
|
|
if ( check_1st_lower) l1 = lower_1;
|
|
if ( check_1st_upper) u1 = upper_1;
|
|
if ( check_2nd_lower) l2 = lower_2;
|
|
if ( check_2nd_upper) u2 = upper_2;
|
|
}
|
|
|
|
result_type operator () ( int r, int c) const
|
|
{
|
|
if ( check_1st_lower && ( r < l1)) return z;
|
|
if ( check_1st_upper && ( r >= u1)) return z;
|
|
if ( check_2nd_lower && ( c < l2)) return z;
|
|
if ( check_2nd_upper && ( c >= u2)) return z;
|
|
return VectorIt(m[ r])[ c];
|
|
}
|
|
|
|
private:
|
|
const result_type z;
|
|
MatrixIt m;
|
|
int l1, u1, l2, u2;
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// ----------------------------
|
|
// QP_matrix_pairwise_accessor
|
|
// ----------------------------
|
|
template < class MatrixIt, typename ResultType >
|
|
class QP_matrix_pairwise_accessor {
|
|
typedef typename std::iterator_traits<MatrixIt>::value_type VectorIt;
|
|
|
|
public:
|
|
typedef int argument_type;
|
|
typedef ResultType result_type;
|
|
|
|
// The following default constructor is needed to make it possible
|
|
// to use QP_matrix_pairwise_accessor with CGAL's Join_input_iterator_1
|
|
// (more precisely: once Join_input_iterator_1 should not use an internal
|
|
// mutable variable 'val' anymore, you can remove the following default
|
|
// constructor).
|
|
//QP_matrix_pairwise_accessor() {}
|
|
|
|
QP_matrix_pairwise_accessor( MatrixIt it, int row)
|
|
: m (it), v (*(it + row)), r (row)
|
|
{}
|
|
|
|
ResultType operator () ( int c) const
|
|
{
|
|
// make sure that only entries on or below the diagonal are
|
|
// accessed
|
|
if (c <= r)
|
|
return ResultType(v[ c]);
|
|
else
|
|
return ResultType((*(m + c))[ r]);
|
|
}
|
|
|
|
private:
|
|
MatrixIt m;
|
|
VectorIt v;
|
|
int r;
|
|
};
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// --------------------
|
|
// Value_by_basic_index
|
|
// --------------------
|
|
template < class RndAccIt >
|
|
class Value_by_basic_index : public CGAL::cpp98::unary_function<
|
|
int, typename std::iterator_traits<RndAccIt>::value_type > {
|
|
|
|
public:
|
|
typedef typename
|
|
CGAL::cpp98::unary_function<
|
|
int, typename std::iterator_traits
|
|
<RndAccIt>::value_type >::result_type
|
|
result_type;
|
|
|
|
Value_by_basic_index( RndAccIt x_B_O_it, int n_original)
|
|
: o( x_B_O_it), s( x_B_O_it),
|
|
l( n_original), u( n_original+0),
|
|
z( 0)
|
|
{ }
|
|
|
|
Value_by_basic_index( RndAccIt x_B_O_it, int n_original,
|
|
RndAccIt x_B_S_it, int n_slack = 0)
|
|
: o( x_B_O_it), s( x_B_S_it),
|
|
l( n_original), u( n_original+n_slack),
|
|
z( 0)
|
|
{ }
|
|
|
|
result_type operator () ( int i) const
|
|
{
|
|
if ( i < 0) return z;
|
|
if ( i >= l && i < u) return s[ i];
|
|
return o[ i];
|
|
}
|
|
|
|
private:
|
|
RndAccIt o, s;
|
|
int l, u;
|
|
result_type z;
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// --------------------
|
|
// Access_by_index
|
|
// --------------------
|
|
// A functor whose operator(int i) provides access to the i-th element
|
|
// of a random access iterator.
|
|
template < typename RndAccIt, typename ArgType >
|
|
class QP_access_by_index {
|
|
public:
|
|
typedef typename std::iterator_traits<RndAccIt>::value_type result_type;
|
|
|
|
QP_access_by_index(RndAccIt it = RndAccIt()) : a(it) {}
|
|
|
|
result_type operator () (ArgType i) const { return a[i]; }
|
|
|
|
private:
|
|
RndAccIt a;
|
|
};
|
|
|
|
|
|
// -------------------
|
|
// Map_with_default
|
|
// -------------------
|
|
template<typename Map>
|
|
class Map_with_default {
|
|
// public types
|
|
public:
|
|
typedef typename Map::mapped_type mapped_type;
|
|
//typedef typename Map::difference_type difference_type;
|
|
typedef typename Map::size_type size_type;
|
|
typedef typename Map::key_type key_type;
|
|
typedef mapped_type result_type;
|
|
// data members
|
|
private:
|
|
const Map* map; // pointer to map
|
|
mapped_type d; // default value
|
|
|
|
public:
|
|
// construction
|
|
Map_with_default ()
|
|
: map(0), d()
|
|
{}
|
|
|
|
Map_with_default (const Map* m, const mapped_type& v = mapped_type())
|
|
: map(m), d(v)
|
|
{}
|
|
|
|
// Added as workaround for VC2017 with /arch:AVX to fix
|
|
// https://cgal.geometryfactory.com/CGAL/testsuite/CGAL-4.14-I-95/QP_solver/TestReport_afabri_x64_Cygwin-Windows10_MSVC2017-Release-64bits.gz
|
|
Map_with_default& operator=(const Map_with_default& other)
|
|
{
|
|
map = other.map;
|
|
d = other.d;
|
|
return *this;
|
|
}
|
|
|
|
// operator()
|
|
const mapped_type& operator() (key_type n) const {
|
|
CGAL_qpe_precondition (map != 0);
|
|
typename Map::const_iterator i = map->find (n);
|
|
if (i != map->end())
|
|
return i->second;
|
|
else
|
|
return d;
|
|
}
|
|
};
|
|
|
|
} //namespace CGAL
|
|
|
|
#endif // CGAL_QP_SOLVER_FUNCTORS_H
|
|
|
|
// ===== EOF ==================================================================
|