%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Architecture\label{sec:kds_architecture}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
This package provides a framework to allow exact implementation of
kinetic data structures and sweepline algorithms. Below we discuss in
detail each one of the first four major concepts which help in
implementing kinetic data structures: the \ccc{Kinetic::Simulator},
the \ccc{Kinetic::Kernel}, the \ccc{Kinetic::ActiveObjectsTable} and the
\ccc{Kinetic::InstantaneousKernel}. The \ccc{Kinetic::FunctionKernel}
concept is discussed separately in Section
\ref{sec:kds_algebraic_kernel}.
\begin{figure}
\begin{ccTexOnly}
\begin{center}
\includegraphics[scale=.8,viewport=0 18 470 250, clip]{Kinetic_data_structures/sort_usage_pct}
\end{center}
\end{ccTexOnly}
\begin{ccHtmlOnly}
\end{ccHtmlOnly}
\caption{\label{fig:kds_uml_usage_architecture} The figure, identical
to the one in the overview of the previous chapter, shows the
interaction between the \ccc{Kinetic::Sort} kinetic
data structure and the various pieces of our framework. Other, more
complicated, kinetic data structures will also use the
\ccc{Kinetic::InstantaneousKernel} in order to insert/remove
geometric primitives and audit themselves.
\ccc{Kinetic::Sort} uses the sorting functionality
in STL instead.}
\end{figure}
\subsection{The Kinetic::Simulator\label{sec:kds_simulator}}
The \ccc{Kinetic::Simulator} is the central repository of all active events.
It maintains the event queue and can use its knowledge of the events
in the queue to find times for the kinetic data structures to easily
check their own correctness (this will be discussed in more detail
later in this section). Kinetic data structures call methods of the
\ccc{Kinetic::Simulator} to schedule new events, deschedule old ones and
access and change data contained in already scheduled events (the
operations on existing events are performed using a key which was
returned when the event was scheduled). For controlling the
simulation, methods in the \ccc{Kinetic::Simulator} allow stepping through
events, advancing time and even running the simulation backwards (that
is we run the simulation with the time running in the opposite
direction).
The kinetic sorting example in Figure~\ref{sec:kds_sort_example} shows the
basic usage of the \ccc{Kinetic::Simulator}. First, the \ccc{Simulator}
is created by the \ccc{Kinetic::SimulationTraits}. The kinetic data structure
gets a handle to the simulator from the traits class and uses the
handle to add its events to the simulation. The \ccc{Kinetic::Simulator} is
then told to advance time up until the end of the simulation,
processing all events along the way.
Each event is represented by a \ccc{Kinetic::Simulator::Time} and an instance of a
model of the \ccc{Kinetic::Simulator::Event} concept. Models of the \ccc{Kinetic::Simulator::Event}
concept are responsible for taking the appropriate action in order to
handle the kinetic event they represent. Specifically, the
\ccc{Kinetic::Simulator::Event} concept specifies one method,
\ccc{Kinetic::Simulator::Event::process()}, that is called when the event occurs.
The body of the \ccc{Kinetic::Simulator::Event::process()} method typically
simply calls a method of the kinetic data structure that created the
event; for example in our kinetic sorting example, processing an event
means calling the \ccc{Kinetic::Sort::swap(Iterator)}
method of the kinetic sorting data structure.
In the model of the \ccc{Kinetic::Simulator} concept that we provide,
\ccc{Kinetic:Default_simulator}, any model
of the \ccc{Kinetic::Simulator::Event} concept can be inserted as an
event. This ability implies that events can be mixed at run time,
which is essential when we want to support multiple kinetic data
structures operating on the same set of moving geometric primitives.
The \ccc{Kinetic::Simulator::Time} concept is defined by the simulator, typically to be
some representation of a root of a polynomial, taken from the
\ccc{Kinetic::FunctionKernel} (details of the algebraic side of the package
will be discussed in Section~\ref{sec:kds_algebraic_kernel}). For most
kinetic data structures \ccc{Kinetic::Simulator::Time} only needs to support
comparisons (we need to compare events, in order to process them in
the correct order) and a few other non-arithmetic operations.
When the failure times of certificates are sorted exactly (as opposed
to when we numerically approximate the roots of the certificate
polynomials) the correctness of kinetic data structures can be easily
verified. Let $I$ be an open interval between the last event
processed and the next event to be processed. As was mentioned in the
introduction kinetic data structures do not change combinatorially in
$I$. In addition, although the static data structures can be
degenerate at the roots defining the two ends of the interval, they
are not, in general, degenerate in the interior. An independent check
of the integrity of kinetic data structures can be provided by, for
example, using an \ccc{Kinetic::InstantaneousKernel} (cf. Subsection
\ref{sec:kds_instantaneous_kernel}) to rebuild the static version of the
structure from scratch at some time interior to $I$ and compare it to
the kinetic version. This auditing can typically catch algorithmic or
programming errors much closer to the time they arise in the
simulation than, for example, using visual inspection. Such easy
auditing is one of the powerful advantages of having an exact
computational framework since, as with static data structures, when
using inexact computations differentiating between errors of
implementation and numeric errors is quite tricky.
Kinetic data structures receive alerts of appropriate times to audit
themselves using a notification framework. The same framework is also
used by the \ccc{Kinetic::ActiveObjectsTable} to alert kinetic data
structures when the set of primitives changes (see
Subsection~\ref{sec:kds_active_objects_table}). To use the notification
framework, the kinetic data structure creates a proxy object which
implements a standard \ccc{Listener} interface. It then registers this
proxy with the \ccc{Kinetic::Simulator}. When the
\ccc{Kinetic::Simulator} finds an appropriate time for the kinetic
data structures to audit themselves it calls the function
\ccc{Listener::new_notification(Type)} on each of the registered proxy
objects. A helper for creating such proxy objects, called
\ccc{Kinetic::Simulator_kds_listener}, is provided by the
framework. It translates the notification into a function call
(\ccc{audit()}) on the kinetic data structure. Pointers in the
notification framework are reference counted appropriately to avoid
issues caused by the creation and destruction order of kinetic data
structures and the simulator. See Section~\ref{sec:kds_listener} for a more
complete discussion of this part of the framework.
Internally the \ccc{Kinetic::Simulator} maintains a priority queue
containing the scheduled events. The type of the priority queue is a
template argument to our \ccc{Kinetic::Simulator} model and, as such, it can
be replaced by the user. In our package, we provide two different
types of priority queues, a heap and a two-list priority queue. A
two-list queue is a queue in which there is a sorted front list,
containing all events before some time and an unsorted back list. The
queue tries to maintain a small number of elements in the front list,
leaving most of them in the unsorted main pool. The two-list queue,
although an unconventional choice, is our default queue when using
exact computation because it minimizes comparisons involving events
that are far in the future. These events are likely to be deleted
before they are processed, so extra work done structuring them is
wasted. Our experiments have shown that, for example, the two-list
queue causes a 20\% reduction in running time relative to a binary
heap for Delaunay triangulations with degree 3 polynomial motions and
20 points.
\subsection{The Kinetic::Kernel}
The \ccc{Kinetic::Kernel} is structured very much like static CGAL
kernels. It defines a number of primitives, which in the model
provided are \ccc{Kinetic::Kernel::Point_1},
\ccc{Kinetic::Kernel::Point_2}, \ccc{Kinetic::Kernel::Point_3} and
\ccc{Kinetic::Kernel::Weighted_point_3}. The primitives are defined by
a set of Cartesian coordinates each of which is a function of time, a
\ccc{Kernel::MotionFunction}. In addition it defines constructions
and certificate generators which act on the primitives. The
certificate generators are the direct analog of the non-kinetic
predicates. Each certificate generator take a number of primitives as
arguments, but instead of producing an element from a discrete set
they produce a set of discrete failure times for the certificate.
These failure times are wrapped in a model of \ccc{Kinetic::Certificate}.
A \ccc{Kinetic::Certificate} is a simple object whose primary function is to
produce a \ccc{Kinetic::Simulator::Time} object representing the failure time of the
certificate. Since, the handling of most certificate failures
involves creating a new certificate whose certificate function is the
negation of the old certificate function, a \ccc{Kinetic::Certificate}
object caches any work that could be useful to isolate future roots of
the certificate function (such as the Sturm sequence of the
certificate function). To illustrate this further, if you have two
one-dimensional points with coordinate functions $p_0(t)$ and
$p_1(t)$, the certificate that the first moving point is after the
second corresponds to the inequality $p_0(t) - p_1(t) > 0$. When the
certificate fails and the two points cross, the new certificate is
$p_1(t)- p_0(t) > 0$, which is the negated version of the certificate
just processed and which has the same roots.
The model of \ccc{Kinetic::Kernel} provided includes the certificate
generators necessary for Delaunay triangulations (in one, two and
three dimensions) and regular triangulations (in 3D). New
certificates can be fairly easily added. An example is included in the
distributed code.
\subsection{The Kinetic::ActiveObjectsTable\label{sec:kds_active_objects_table}}
The \ccc{Kinetic::ActiveObjectsTable} stores a set of kinetic primitives.
Its purpose is to notify kinetic data structures when new primitives
are added, when primitives are removed or when a trajectories change.
Each primitive is uniquely identified by a Key, assigned by
the table when the primitive is added, that can be used to change or
remove it. We provide one model of the
\ccc{Kinetic::ActiveObjectsTable} concept, called
\ccc{Kinetic::Active_objects_vector} which stores all the moving
primitives in an \ccc{std::vector}.
Notifications of changes to the set of active objects are handled
using a setup similar to the \ccc{Kinetic::Simulator} audit time
notification. We provide a helper class,
\ccc{Kinetic::Active_objects_listener_helper}, which translates the notifications into \ccc{insert(Key)},
\ccc{erase(Key)} or \ccc{set(Key)} function calls on the kinetic data
structure.
\subsection{The Kinetic::InstantaneousKernel\label{sec:kds_instantaneous_kernel}}
The \ccc{Kinetic::InstantaneousKernel} allows existing CGAL data structures
to be used on moving data as it appears at some instant of time.
Models of this concept are, by definition, models of a CGAL
Kernel or a traits class, and, therefore, can then be used as
the traits class of CGAL's algorithms and data structures.
Consider for example the kinetic Delaunay data structure in either two
or three dimensions. Internally, it uses a
\ccc{Delaunay_triangulation_2} or
\ccc{Delaunay_triangulation_3} to represent the
triangulation, instantiated with a model of the
\ccc{Kinetic::InstantaneousKernel} concept as its traits class. At
initialization, as well as at times during the simulation when we want
to insert a point to the kinetic Delaunay triangulation, a static
version of the Delaunay triangulation is conceptually instantiated.
More precisely, the time for the copy of the model of the
\ccc{Kinetic::InstantaneousKernel} stored in the CGAL triangulation is set
to be the current time (or rather, as discussed in the introduction, a
more convenient time determined by the \ccc{Kinetic::Simulator}
combinatorially equivalent to the current time). The kinetic data
structure then calls the
\ccc{Delaunay_triangulation_3::insert(Point)} insert
method to insert the point. The static insert method called uses
various predicate functors on the moving points which evaluate to the
values that the predicates have at that instant in time. Removal is
handled in an analogous manner. Auditing of the geometric structure is
easily handled in a similar manner (in the case of Delaunay
triangulations by simply calling the \ccc{verify()} method after
setting the time).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Miscellaneous: notification and reference management\label{sec:kds_misc}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
We describe some coding conventions used, graphical display,
notification and reference management support in the framework in the
following sections.
\subsubsection{Reference management}
A number of objects need to maintain pointers to other independent
objects. For example, each kinetic data structure must have access to
the \ccc{Kinetic::Simulator} so that it can schedule and deschedule
events. These pointers are all reference counted in order to guarantee
that they are always valid. We provide a standard reference counting
pointer and object base to facilitate this, namely
\ccc{Ref_counted