Workspace 6.21.5
Classes | Public Member Functions | List of all members
DataSeries Class Referenceabstract

Interface for accessing data types as though they were a read-only const array of doubles. More...

#include <DataAnalysis/DataStructures/dataseries.h>

Inheritance diagram for DataSeries:
[legend]

Classes

class  const_iterator
 Iterator providing const random access to a DataSeries. More...
 

Public Member Functions

 ~DataSeries () override=default
 
double back () const
 
const_iterator begin () const
 
DataSeriesclone () const override=0
 
virtual void destroy ()=0
 
virtual bool empty () const =0
 
const_iterator end () const
 
double front () const
 
bool isInfinite () const
 
 operator QVector< double > () const
 
virtual double operator[] (int i) const =0
 
virtual unsigned size () const =0
 
- Public Member Functions inherited from Clonable
virtual ~Clonable ()=default
 
virtual Clonableclone () const =0
 

Detailed Description

A DataSeries is an interface for accessing some underlying data as though it was a const array of doubles. More precisely, the array can be assumed to support random access through operator[](int). Normally, this implies constant time lookup for any argument passed to operator[](int), but here we relax the requirement such that lookup is O(d) where d is the absolute difference between the parameter passed to the current and the previous call. This is important, because the typical usage of a DataSeries is to iterate through it from beginning to end, or over some sequential sub-range. In such cases, the lookup then effectively reduces to constant time and the performance characteristics are similar to a regular array. This relaxation of the complexity requirements allows subclasses to be constructed over containers that support bi-directional iterators but not true random access iterators, such as a linked list. Even more powerfully, a DataSeries subclass can then be a proxy for some arbitrary data that is not even stored as a sequential array, but can be made to appear so.

It should be noted that subclasses are not expected to be thread-safe. This is so that subclasses are free to employ internal caching mechanisms to improve the performance of operator[]() if they represent data that supports bi-directional iterators rather than random access iterators (eg a linked list), as described above.

Algorithm implementers should ensure they consider the relaxed complexity requirements and anticipate that DataSeries subclasses will be optimized for sequential access. Calls to operator[]() should aim to differ by no more than one index from a previous call if at all possible. Perhaps the best approach is to avoid directly calling operator[]() altogether and instead use iterator-based access with only increment or decrement operations on the iterators.

Note that as a special case, a data series can be considered infinite. An infinite data series returns zero from size() but false from empty(). The isInfinite() function is provided as a convenience for testing this and to make client code clearer. For an infinite data series, any valid integer may be passed to operator[](int) and a meaningful return value can be expected. This has implications for iterators though, since the series technically has no beginning or end. So that iterators can still be used by algorithms operating on a subrange within an infinite series, some of the requirements on iterators are modified from the standard requirements of a random access iterator when isInfinite() returns true:

Finally, although DataSeries is derived from Clonable, this should be understood to mean that the subclass is cloned but not necessarily the data it represents (and indeed will usually not mean the underlying data is cloned). The DataSeries class is meant to act as an adaptor to some other underlying data that is managed by something else. Clients of the DataSeries class should be able to call clone() and expect the call to be relatively cheap.

See also
NullDataSeries, SequenceDataSeries, DataSeriesAdaptor

Constructor & Destructor Documentation

◆ ~DataSeries()

~DataSeries ( )
overridedefault

Member Function Documentation

◆ back()

double back ( ) const
inline

◆ begin()

const_iterator begin ( ) const
inline

◆ clone()

DataSeries * clone ( ) const
overridepure virtual
Returns
A clone of this object.
Note
Subclasses would normally return their own type rather than the Clonable type. The C++ language rules allow a more derived type to be returned from a virtual function and the compiler will still treat it as a valid override.

Note that this implementation of clone should not clone the underlying data of the series. Rather, just the interface to it should be cloned. This is important, because workspaces will frequently pass around clones of DataSeries objects like handles to the underlying data which could be expensive to copy.

Implements Clonable.

Implemented in NullDataSeries, SequenceDataSeries, and StandardDataSeries< T, Evaluator >.

◆ destroy()

virtual void destroy ( )
pure virtual

◆ empty()

virtual bool empty ( ) const
pure virtual

◆ end()

const_iterator end ( ) const
inline

◆ front()

double front ( ) const
inline

◆ isInfinite()

bool isInfinite ( ) const
inline

◆ operator QVector< double >()

operator QVector< double > ( ) const
Returns
The data series as a QVector<double>. Note that because QVector uses implicit sharing, returning the result by value does not involve any extra deep copies of the data beyond the first one used to construct the QVector.

◆ operator[]()

virtual double operator[] ( int  i) const
pure virtual

◆ size()

virtual unsigned size ( ) const
pure virtual