cgal/Kinetic_data_structures/doc/Kinetic_framework/Concepts/FunctionKernel.h

299 lines
8.0 KiB
C++

namespace KineticConcepts {
/*!
\ingroup PkgKdsFrameworkConcepts
\cgalconcept
The concept `Kinetic::FunctionKernel` encapsulates all the methods for representing
and handing functions. The set is kept deliberately small to easy use
of new `Kinetic::FunctionKernel`s, but together these operations are sufficient to
allow the correct processing of events, handling of degeneracies,
usage of static data structures, run-time error checking as well as
run-time verification of the correctness of kinetic data structures.
The computation of a polynomial with the variable negated is used for
reversing time in kinetic data structures and can be omitted if that
capability is not needed.
\hasModel `POLYNOMIAL::Kernel<RootStack>`
\hasModel `POLYNOMIAL::Filtered_kernel<RootStack>`
\sa `Kinetic::RootEnumerator`
### Example ###
We provide several models of the concept, which are not documented
separately. The models of `Kinetic::SimulationTraits` all choose
appropriate models. However, if
more control is desired, we here provide examples of how to create the
various supported `Kinetic::FunctionKernel`.
A Sturm sequence based kernel which supports exact comparisons of roots of polynomials (certificate failure times):
\code{.cpp}
typedef CGAL::POLYNOMIAL::Polynomial<CGAL::Gmpq> Function;
typedef CGAL::POLYNOMIAL::Sturm_root_stack_traits<Function> Root_stack_traits;
typedef CGAL::POLYNOMIAL::Sturm_root_stack<Root_stack_traits> Root_stack;
typedef CGAL::POLYNOMIAL::Kernel<Function, Root_stack> Function_kernel;
\endcode
A wrapper for `CORE::Expr` which implements the necessary
operations:
\code{.cpp}
typedef CGAL::POLYNOMIAL::CORE_kernel Function_kernel;
\endcode
A function kernel which computes approximations to the roots of the polynomials:
\code{.cpp}
typedef CGAL::POLYNOMIAL::Polynomial<double> Function;
typedef CGAL::POLYNOMIAL::Root_stack_default_traits<Function> Root_stack_traits;
typedef CGAL::POLYNOMIAL::Numeric_root_stack<Root_stack_traits> Root_stack;
typedef CGAL::POLYNOMIAL::Kernel<Function, Root_stack> Function_kernel;
\endcode
When using the function kernel in kinetic data structures, especially
one that is in exact, it is useful to wrap the root stack. The wrapper
checks the sign of the certificate function being solved and uses that
to handle degeneracies. This is done by, for the inexact solvers
\code{.cpp}
typedef Kinetic::Derivitive_filter_function_kernel<Function_kernel> KDS_function_kernel;
\endcode
and for exact solvers
\code{.cpp}
typedef Kinetic::Handle_degeneracy_function_kernel<Function_kernel> KDS_function_kernel;
\endcode
For exact computations, the primary representation for roots is the
now standard choice of a polynomial with an associated isolating
interval (and interval containing exactly one distinct root of a
polynomial) along with whether the root has odd or even multiplicity
and, if needed, the Sturm sequence of the polynomial. Two intervals
can be compared by first seeing if the isolating intervals are
disjoint. If they are, then we know the ordering of the respective
roots. If not we can subdivide each of the intervals (using the
endpoints of the other interval) and repeat. In order to avoid
subdividing endlessly when comparing equal roots, once we subdivide a
constant number of times, we use the Sturm sequence of \f$ p\f$ and \f$ p'q\f$
(where \f$ p\f$ and \f$ q\f$ are the two polynomials and \f$ p'\f$ is the derivative
of \f$ p\f$) to evaluate the sign of the second at the root of the first
one directly (note that this Sturm sequence is applied to a common
isolating interval of the roots of interest of both polynomials).
*/
class FunctionKernel {
public:
/// \name Types
/// @{
/*!
\ingroup PkgKdsFrameworkOtherConcepts
\cgalconcept
The concept `Function` represents a function.
\sa `FunctionKernel
\sa `FunctionKernel::ConstructFunction`
### Example ###
Several ways to create functions:
Using `Kinetic::ConstructFunction`:
\code{.cpp}
Traits::Function_kernel::Construct_function cf= traits.function_kernel_object().construct_function_object();
Traits::Kinetic_kernel::Motion_function x= cf(0.0,1.0,2.0);
Traits::Kinetic_kernel::Motion_function y= cf(0.0,1.0,2.0);
Traits::Kinetic_kernel::Point_2 pt(x,y);
\endcode
Using the constructor:
\code{.cpp}
double coefs[]={1.0, 2.0, 3.0};
Traits::Kinetic_kernel::Motion_function z(coefs, coefs+3);
\endcode
Using ring operations:
\code{.cpp}
Traits::Kinetic_kernel::Motion_function z= x*z+y;
\endcode
*/
class Function {
public:
/// \name Types
/// @{
/*!
The number type used in describing the function.
*/
typedef Hidden_type NT;
/*!
Construct a constant function from a number.
*/
Function(NT);
/// @}
/// \name Operations
/// @{
/*!
Evaluate the function at an `NT`.
*/
NT operator()(NT);
/// @}
}; /* end Function */
/*!
The basic representational number type.
*/
typedef Hidden_type NT;
/*!
A type representing the roots of a `Function`.
*/
typedef Hidden_type Root;
/*!
A model of `RootStack`. These objects can be created by calling the `root_stack_object` method with a `Function` and two (optional) `Root` objects. The enumerator then enumerates all roots of the function in the open inverval defined by the two root arguments. They optional arguments default to positive and negative infinity.
*/
typedef Hidden_type Root_stack;
/*!
The traits for the `Root_enumerator` class.
*/
typedef Hidden_type Root_enumerator_traits;
/// @}
/// \name
/// Each of the following types has a corresponding `type_object`
/// method (not explicitly documented) which takes a `Function` as an
/// argument.
/// @{
/*!
A functor which returns the sign of a
`Function` at a `NT` or `Root`.
*/
typedef Hidden_type Sign_at;
/*!
A functor which returns sign of a function
immediately after a root.
*/
typedef Hidden_type Sign_after;
/// @}
/// \name
/// The following type is used to construct functions from a list of
/// coefficients. To get an instance use the
/// `construct_function_object()` method.
/// @{
/*!
\ingroup PkgKdsFrameworkOtherConcepts
\cgalconcept
The concept `ConstructFunction` is used to construct functions.
\sa `FunctionKernel`
### Example ###
\code{.cpp}
Function_kernel fk;
Function_kernel::Construct_function cf= fk.construct_function_object();
Function_kernel::Function f= cf(0,1,2,3,4,5);
\endcode
*/
class ConstructFunction {
public:
/// \name Operations
/// @{
/*!
This family of methods
takes a list of coefficients and returns a function. There can be
any number of coeffients passed as arguments (up to about 25 in the
current implementations).
*/
Function operator()(NT a, ...);
/// @}
}; /* end ConstructFunction */
/// @}
/// \name
/// The following functor likewise have a `type_object` method, but
/// these take arguments other than a `Function`. The arguments are
/// given below.
/// @{
/*!
This functor, creation of which
requires two `Root`s, returns the sign of a passed function
between the pair of roots.
*/
typedef Hidden_type Sign_between_roots;
/*!
This functor computes the derivitive of a `Function`. Construction takes no arguments.
*/
typedef Hidden_type Differentiate;
/// @}
/// \name
/// The following methods do not require any arguments to get the
/// functor and take one `Function` as a functor argument.
/// @{
/*!
Map \f$ f(x)\f$ to \f$ f(-x)\f$.
*/
typedef Hidden_type Negate_variable;
/// @}
}; /* end Kinetic::FunctionKernel */
} /* end namespace KineticConcepts */