signalpointset.h

Back to SignalPointSet class

tim/core/

// Description: SignalPointSet class
// Detail: Models a semi-dynamic point set

#ifndef TIM_SIGNALPOINTSET_H
#define TIM_SIGNALPOINTSET_H

#include "tim/core/mytypes.h"
#include "tim/core/signal.h"

#include <pastel/geometry/pointkdtree/pointkdtree.h>

#include <pastel/sys/range.h>
#include <pastel/sys/array/array.h>
#include <pastel/sys/locator/pointer_locator.h>

#include <vector>
#include <deque>

namespace Tim
{

    //! SignalPointSet class
    class TIM SignalPointSet
    {
    public:
        using Settings = PointKdTree_Settings<Pointer_Locator<dreal>>;
        typedef PointKdTree<Settings> KdTree;
        typedef KdTree::Point_ConstIterator Point_ConstIterator;
        typedef KdTree::Point Point;

        typedef std::vector<Point_ConstIterator> PointSet;
        typedef PointSet::const_iterator Point_ConstIterator_Iterator;

    public:
        SignalPointSet() = default;

        //! Constructs using the given ensemble of signals.
        template <ranges::forward_range Signal_Range>
        explicit SignalPointSet(
            const Signal_Range& signalSet);

        SignalPointSet(const SignalPointSet& that) = delete;

        SignalPointSet(SignalPointSet&& that);

        //! Constructs using given subdimensions and initial time-window.
        /*!
       Preconditions:
       dimensionBegin <= dimensionEnd
       dimensionBegin >= 0
       dimensionEnd <= std::begin(signalSet)->dimension()

       The subdimension integer interval is
       given by [dimensionBegin, dimensionEnd[. If 'startFull' is true,
       then initially all samples are contained in the time-window.
       Otherwise no samples are initially contained in the time-window.
       */
        template <ranges::forward_range Signal_Range>
        SignalPointSet(
            const Signal_Range& signalSet,
            integer dimensionBegin,
            integer dimensionEnd);

        //! Swaps the contents of two SignalPointSet's.
        /*!
       Time complexity: constant
       */
        void swap(SignalPointSet& that);

        //! Copies the contents of another SignalPointSet.
        SignalPointSet& operator=(SignalPointSet that);

        //! Set the time-window.
        /*!
       Preconditions:
       tNewBegin <= tNewEnd

       The more the old time-window and the new time-window
       overlap, the less work needs to be done.
       */
        void setTimeWindow(integer tNewBegin, integer tNewEnd);

        //! Returns a non-mutable reference to the multi-resolution kd-tree.
        const KdTree& kdTree() const;

        //! First iterator to set of points currently in the window.
        Point_ConstIterator_Iterator begin() const;

        //! One-past-last iterator to set of points currently in the window.
        Point_ConstIterator_Iterator end() const;

        //! Returns the beginning time of the current time-window.
        /*!
       The interval of the time-window is given by [windowBegin(), windowEnd()[.
       */
        integer windowBegin() const;

        //! Returns the one-past-last time of the current time-window.
        /*!
       The interval of the time-window is given by [windowBegin(), windowEnd()[.
       */
        integer windowEnd() const;

        //! Returns the total number of points in the point set.
        integer samples() const;

        //! Returns the dimension of the point set.
        /*!
       Note that the dimension of the point set is not
       necessarily the same as the dimension of the input
       signals. This is because you can choose a subinterval
       of the dimensions in construction.
       */
        integer dimension() const;

        //! Returns the dimension offset of the signal data.
        /*!
       Using a dimension offset allows you to select a subrange
       of the dimensions of a signal.
       */
        integer dimensionBegin() const;

        //! Returns a vector that corresponds to a given point.
        VectorD point(const Point& object) const;

    private:
        // Extracts points from the given ensemble of signals.
        /*
       Each point is a pointer to the beginning of its coordinate
       data. These pointers are placed in 'pointSet_'.
       */
        template <ranges::forward_range Signal_Range>
        void createPointSet(
            const Signal_Range& signalSet);

        void hide(
            const AlignedBox<integer, 1>& range);

        void show(
            const AlignedBox<integer, 1>& range);

        /*
       kdTree_:
       A multi-resolution kd-tree that has been subdivided with
       all available points but which only contains the points
       in the time-window at any time instant. Note multi-resolution
       kd-tree adapts itself automatically to smaller number of points.

       signalSet_:
       Contains the ensemble of signals that are the input 
       data.

       pointSet_:
       Contains a set of pointers with each pointer pointing
       to the beginning of point coordinate data. This set represents
       the set of all available points without culling by a 
       time-window. Note that kdTree_ uses a PointPolicy
       in which the point is a const dreal*. This container is
       needed to insert points when the time-window is moved.

       samples_:
       Contains the number of samples that are considered
       for each signal.

       windowBegin_, windowEnd_:
       The position of the time-window is given by the
       integer interval [windowBegin_, windowEnd_[.

       dimensionBegin_, dimension_:
       The signals can also be considered by their
       marginal signals. The integer interval 
       [dimensionBegin_, dimensionBegin_ + dimension_]
       denotes a subdimension interval inside
       the signals.

       timeBegin_:
       The time instant t corresponding to 'pointSet_[i]'
       is given by 't = timeBegin_ + (i / signals_)'.
       */

        KdTree kdTree_;
        PointSet pointSet_;
        integer signals_;
        integer samples_;
        integer windowBegin_;
        integer windowEnd_;
        integer dimensionBegin_;
        integer dimension_;
        integer timeBegin_;
    };

}

#include "tim/core/signalpointset.hpp"

#endif