LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
lar::sparse_vector< T > Class Template Reference

A sparse vector. More...

#include "sparse_vector.h"

Classes

class  const_iterator
 Iterator to the sparse vector values. More...
 
class  const_reference
 Special little box to allow void elements to be treated as references. More...
 
class  datarange_t
 Range class, with range and data. More...
 
class  iterator
 Iterator to the sparse vector values. More...
 
class  reference
 A class representing a cell in a sparse vector. More...
 

Public Types

typedef T value_type
 type of the stored values More...
 
typedef std::vector< value_typevector_t
 type of STL vector holding this data More...
 
typedef vector_t::size_type size_type
 size type More...
 
typedef vector_t::difference_type difference_type
 index difference type More...
 
typedef vector_t::pointer pointer
 
typedef vector_t::const_pointer const_pointer
 
typedef std::vector< datarange_trange_list_t
 type of sparse vector data More...
 
typedef range_list_t::iterator range_iterator
 type of iterator over ranges More...
 
typedef range_list_t::const_iterator range_const_iterator
 type of constant iterator over ranges More...
 

Public Member Functions

 sparse_vector ()
 Default constructor: an empty vector. More...
 
 sparse_vector (size_type new_size)
 Constructor: a vector with new_size elements in the void. More...
 
 sparse_vector (const vector_t &from, size_type offset=0)
 Constructor: a solid vector from an existing STL vector. More...
 
 sparse_vector (sparse_vector const &)=default
 Copy constructor: default. More...
 
 sparse_vector (sparse_vector &&from)
 Move constructor. More...
 
sparse_vectoroperator= (sparse_vector const &)=default
 Copy assignment: default. More...
 
sparse_vectoroperator= (sparse_vector &&from)
 Move assignment. More...
 
 sparse_vector (vector_t &&from, size_type offset=0)
 Constructor: a solid vector from an existing STL vector. More...
 
 ~sparse_vector ()=default
 Destructor: default. More...
 
void clear ()
 Removes all the data, making the vector empty. More...
 
size_type size () const
 Returns the size of the vector. More...
 
bool empty () const
 Returns whether the vector is empty. More...
 
size_type capacity () const
 Returns the capacity of the vector (compatibility only) More...
 
value_type operator[] (size_type index) const
 Access to an element (read only) More...
 
reference operator[] (size_type index)
 Access to an element (read/write for non-void elements only!) More...
 
void make_void_around (size_type index)
 Casts the whole range with the specified item into the void. More...
 
bool is_valid () const
 Returns if the vector is in a valid state. More...
 
void make_void (iterator first, iterator last)
 Makes all the elements from first and before last void. More...
 
template<typename ITER >
const lar::sparse_vector< T >::datarange_tadd_range (size_type offset, ITER first, ITER last)
 
template<typename ITER , typename OP >
auto combine_range (size_type offset, ITER first, ITER last, OP &&op, value_type void_value) -> const datarange_t &
 
void resize (size_type new_size)
 Resizes the vector to the specified size, adding void. More...
 
void resize (size_type new_size, value_type def_value)
 Resizes the vector to the specified size, adding def_value. More...
 
iterator begin ()
 Standard iterators interface. More...
 
iterator end ()
 Standard iterators interface. More...
 
const_iterator begin () const
 Standard iterators interface. More...
 
const_iterator end () const
 Standard iterators interface. More...
 
const_iterator cbegin () const
 Standard iterators interface. More...
 
const_iterator cend () const
 Standard iterators interface. More...
 
Cell test

The methods in this group test the single vector cells.

bool is_void (size_type index) const
 Returns whether the specified position is void. More...
 
bool back_is_void () const
 Returns whether the sparse vector ends with void. More...
 
size_type count () const
 Returns the number of non-void cells. More...
 
Cell set

The methods in this group access and/or change the cell values.

value_typeset_at (size_type index, value_type value)
 Writes into an element (creating or expanding a range if needed) More...
 
void unset_at (size_type index)
 Casts the element with the specified index into the void. More...
 
void push_back (value_type value)
 
void push_back (value_type value, value_type thr)
 Adds one element to the end of the vector (if zero, just adds void) More...
 
template<typename ITER >
void assign (ITER first, ITER last)
 Copies data from a sequence between two iterators. More...
 
template<typename CONT >
void assign (const CONT &new_data)
 Copies data from a container. More...
 
void assign (vector_t &&new_data)
 Moves data from a vector. More...
 
Ranges

A range is a region of the sparse vector which contains all non-void values.

const range_list_tget_ranges () const
 Returns the internal list of non-void ranges. More...
 
size_type n_ranges () const
 Returns the internal list of non-void ranges. More...
 
const datarange_trange (size_t i) const
 Returns the i-th non-void range (zero-based) More...
 
range_const_iterator begin_range () const
 Returns a constant iterator to the first data range. More...
 
range_const_iterator end_range () const
 Returns a constant iterator to after the last data range. More...
 
range_const_iterator find_range_iterator (size_type index) const
 Returns an iterator to the range containing the specified index. More...
 
range_iterator find_range_iterator (size_type index)
 Returns the internal list of non-void ranges. More...
 
const datarange_tfind_range (size_type index) const
 Returns the range containing the specified index. More...
 
datarange_tfind_range (size_type index)
 Returns the range containing the specified index. More...
 
template<typename ITER >
const datarange_tadd_range (size_type offset, ITER first, ITER last)
 Adds a sequence of elements as a range with specified offset. More...
 
template<typename CONT >
const datarange_tadd_range (size_type offset, const CONT &new_data)
 Copies the elements in container to a range with specified offset. More...
 
const datarange_tadd_range (size_type offset, vector_t &&new_data)
 Adds a sequence of elements as a range with specified offset. More...
 
template<typename ITER , typename OP >
const datarange_tcombine_range (size_type offset, ITER first, ITER last, OP &&op, value_type void_value=value_zero)
 Combines a sequence of elements as a range with data at offset. More...
 
template<typename CONT , typename OP >
const datarange_tcombine_range (size_type offset, const CONT &other, OP &&op, value_type void_value=value_zero)
 Combines the elements in container with the data at offset. More...
 
template<typename ITER >
const datarange_tappend (ITER first, ITER last)
 Adds a sequence of elements as a range at the end of the vector. More...
 
template<typename CONT >
const datarange_tappend (const CONT &range_data)
 Adds a sequence of elements as a range at the end of the vector. More...
 
const datarange_tappend (vector_t &&range_data)
 Adds a sequence of elements as a range at the end of the vector. More...
 
void void_range (range_iterator iRange)
 Turns the specified range into void. More...
 
void void_range (size_t iRange)
 Turns the specified range into void. More...
 
bool optimize ()
 Performs internal optimization, returns whether the object was changed. More...
 
bool optimize (size_t)
 Performs internal optimization, returns whether the object was changed. More...
 

Static Public Member Functions

Static members related to data size and optimization
static size_t expected_vector_size (size_t size)
 Returns the expected size taken by a vector of specified size. More...
 
static size_t min_gap ()
 Minimum optimal gap between ranges (a guess) More...
 
static bool should_merge (const typename datarange_t::base_t &a, const typename datarange_t::base_t &b)
 Returns if merging the two specified ranges would save memory. More...
 

Protected Member Functions

size_type minimum_size () const
 Returns the size determined by the ranges already present. More...
 
range_iterator eat_range_head (range_iterator iRange, size_t index)
 Voids the starting elements up to index (excluded) of a given range. More...
 
datarange_tmerge_ranges (range_iterator iRange)
 Merges all the following ranges. More...
 
size_type fix_size ()
 Extends the vector size according to the last range. More...
 
range_iterator find_next_range_iter (size_type index)
 Returns an iterator to the range after index, or end() if none. More...
 
range_const_iterator find_next_range_iter (size_type index) const
 Returns an iterator to the range after index, or end() if none. More...
 
range_iterator find_next_range_iter (size_type index, range_iterator rbegin)
 Returns an iterator to the range after index, or ranges.end() if none. More...
 
range_const_iterator find_next_range_iter (size_type index, range_const_iterator rbegin) const
 Returns an iterator to the range after index, or ranges.end() if none. More...
 
range_iterator find_extending_range_iter (size_type index)
 Returns an iterator to the range no earlier than index, or end() if none. More...
 
range_const_iterator find_extending_range_iter (size_type index) const
 Returns an iterator to the range no earlier than index, or end() if none. More...
 
range_iterator find_extending_range_iter (size_type index, range_iterator rbegin)
 Returns an iterator to the range after index, or end() if none. More...
 
range_const_iterator find_extending_range_iter (size_type index, range_const_iterator rbegin) const
 Returns an iterator to the range after index, or end() if none. More...
 
range_iterator insert_range (range_iterator iInsert, const datarange_t &data)
 Plug a new data range in the specified position; no check performed. More...
 
range_iterator insert_range (range_iterator iInsert, datarange_t &&data)
 Plug a new data range in the specified position; no check performed. More...
 

Protected Attributes

size_type nominal_size
 current size More...
 
range_list_t ranges
 list of ranges More...
 

Private Types

typedef sparse_vector< T > this_t
 

Static members for dealing with this type of value

static constexpr value_type value_zero {0}
 a representation of 0 More...
 
static value_type abs (value_type v)
 Returns the module of the specified value. More...
 
static value_type is_zero (value_type v)
 Returns whether the value is exactly zero. More...
 
static value_type is_zero (value_type v, value_type thr)
 Returns whether the value is zero below a given threshold. More...
 
static value_type is_equal (value_type a, value_type b)
 Returns whether two values are the same. More...
 
static value_type is_equal (value_type a, value_type b, value_type thr)
 Returns whether two values are the same below a given threshold. More...
 

Detailed Description

template<typename T>
class lar::sparse_vector< T >

A sparse vector.


Template Parameters
Ttype of data stored in the vector
Todo:
backward iteration; reverse iterators; iterator on non-void elements only; iterator on non-void elements only, returning a pair (index;value)

A sparse_vector is a container of items marked by consecutive indices (that is, a vector like std::vector), where only non-zero elements are actually stored. The implementation is a container of ranges of non-zero consecutive values; the zero elements are effectively not stored in the object, and a zero is returned whenever they are accessed. In the following, the regions of zeros between the non-zero ranges are collectively called "the void".

See sparse_vector_test.cc for examples of usage.

Although some level of dynamic assignment is present, the class is not very flexible and it is best assigned just once, by adding ranges (add_range(); or by push_back(), which is less efficient). While this class mimics a good deal of the STL vector interface, it is not a std::vector and it does not support all the tricks of it.

For the following, let's assume:

std::vector<double> buffer;

Supported usage

for (const auto& value: sv) std::cout << " " << value;
lar::sparse_vector<double>::const_iterator iValue = sv.cbegin(), vend = sv.cend();
while (iSV != sv.end()) std::cout << " " << *(iSV++);
for (auto value: sv) { ... }

Common iteration on all elements. Better to do a constant one. The first two examples print the full content of the sparse vector, void included.


sv[10] = 3.;

Assign to an existing (not void) element. Assigning to void elements is not supported, and there is no way to make an existing element to become void (assigning 0 will yield to an existing element with value 0).


sv.set_at(10, 3.);

Assign a value to an element. The element could be in the void; in any case, after this call the element will not be in the void anymore (even if the assigned value is zero; to cast a cell into the void, use unset_at()).


sv.add_range(20, buffer)
sv.add_range(20, buffer.begin(), buffer.end())
sv.add_range(20, std::move(buffer))

Add the content of buffer starting at the specified position. The last line will attempt to use the buffer directly (only happens if the start of the new range – 20 in the example – is in the void and therefore a new range will be added). The new range is merged with the existing ones when needed, and it overwrites their content in case of overlap. If the specified position is beyond the current end of the sparse vector, the gap will be filled by void.


sv.append(buffer)
sv.append(buffer.begin(), buffer.end())
sv.append(std::move(buffer))

Add the content of buffer at the end of the sparse vector. The last line will attempt to use the buffer directly (only happens if the end of the sparse vector is in the void and therefore a new range will be added).


sv.resize(30)

Resizes the sparse vector to the specified size. Truncation may occur, in which case the data beyond the new size is removed. If an extension occurs instead, the new area is void.


for (const lar::sparse_vector<double>::datarange_t& range: sv.get_ranges()) {
size_t first_item = range.begin_index(); // index of the first item
size_t nItems = range.size(); // number of items in this range
for (double value: range) { ... }
}

A sparse vector can be parsed range by range, skipping the void. Each range object itself supports iteration. Neither the content nor the shape of the ranges can be changed this way.

Possible future improvements

sv[10] = 3.;

is not supported if the vector is shorter than 11 (similarly to a std::vector too), and not even if the item #10 is currently in the void. This latter could be changed to create a new element/range; this would require to ship the pointer to the container with the reference (the return value of "sv[10]"), just in case an assignment will occur, or to create the element regardless, like for std::map (but this would provoke a disaster if the caller uses the non-constant operator[] for iteration). So far, set_at() is the closest thing to it.

Non-supported usage

sv.reserve(20);

This has no clear meaning. A usage analogous to STL would precede a sequence of push_back's. In that case, we should create a new empty range at the end of the vector, and reserve that. Empty ranges are currently not allowed. A replacement of this pattern is to create a new std::vector, reserve space for it and fill it, and finally use sparse_vector::append(). If the end of the vector is void, there will be no performance penalty, otherwise a reserve + copy will happen.


for (auto& value: sv) { ... }

In order to allow for assignment in an item which is currently not void, the non-constant iterators do not dereference directly into a reference to the vector element (which would be non-existent if in the void), but instead into a lightweight object (still called "reference"). These objects are semantically working as references, but they are formally rvalues (i.e., just values, not C++ references), so they can't be assigned to references (like "auto&"). Nevertheless they work as references and assigning to them does change the original value. Currently assigning to void cells is not supported (see above).

Definition at line 457 of file sparse_vector.h.

Member Typedef Documentation

template<typename T>
typedef vector_t::const_pointer lar::sparse_vector< T >::const_pointer

Definition at line 470 of file sparse_vector.h.

template<typename T>
typedef vector_t::difference_type lar::sparse_vector< T >::difference_type

index difference type

Definition at line 467 of file sparse_vector.h.

template<typename T>
typedef vector_t::pointer lar::sparse_vector< T >::pointer

Definition at line 469 of file sparse_vector.h.

type of constant iterator over ranges

Definition at line 487 of file sparse_vector.h.

template<typename T>
typedef range_list_t::iterator lar::sparse_vector< T >::range_iterator

type of iterator over ranges

Definition at line 485 of file sparse_vector.h.

template<typename T>
typedef std::vector<datarange_t> lar::sparse_vector< T >::range_list_t

type of sparse vector data

Definition at line 480 of file sparse_vector.h.

template<typename T>
typedef vector_t::size_type lar::sparse_vector< T >::size_type

size type

Definition at line 466 of file sparse_vector.h.

template<typename T>
typedef sparse_vector<T> lar::sparse_vector< T >::this_t
private

Definition at line 458 of file sparse_vector.h.

template<typename T>
typedef T lar::sparse_vector< T >::value_type

type of the stored values

Definition at line 463 of file sparse_vector.h.

template<typename T>
typedef std::vector<value_type> lar::sparse_vector< T >::vector_t

type of STL vector holding this data

Definition at line 464 of file sparse_vector.h.

Constructor & Destructor Documentation

template<typename T>
lar::sparse_vector< T >::sparse_vector ( )
inline

Default constructor: an empty vector.

Definition at line 494 of file sparse_vector.h.

494 : nominal_size(0), ranges() {}
range_list_t ranges
list of ranges
size_type nominal_size
current size
template<typename T>
lar::sparse_vector< T >::sparse_vector ( size_type  new_size)
inline

Constructor: a vector with new_size elements in the void.

Definition at line 498 of file sparse_vector.h.

498  : nominal_size(0), ranges()
499  { resize(new_size); }
void resize(size_type new_size)
Resizes the vector to the specified size, adding void.
range_list_t ranges
list of ranges
size_type nominal_size
current size
template<typename T>
lar::sparse_vector< T >::sparse_vector ( const vector_t from,
size_type  offset = 0 
)
inline

Constructor: a solid vector from an existing STL vector.

Parameters
fromvector to copy data from
offset(default: 0) index the data starts from (preceeded by void)

Definition at line 506 of file sparse_vector.h.

506  :
507  nominal_size(0), ranges()
508  { add_range(offset, from.begin(), from.end()); }
const datarange_t & add_range(size_type offset, ITER first, ITER last)
Adds a sequence of elements as a range with specified offset.
range_list_t ranges
list of ranges
size_type nominal_size
current size
template<typename T>
lar::sparse_vector< T >::sparse_vector ( sparse_vector< T > const &  )
default

Copy constructor: default.

template<typename T>
lar::sparse_vector< T >::sparse_vector ( sparse_vector< T > &&  from)
inline

Move constructor.

Definition at line 514 of file sparse_vector.h.

515  : nominal_size(from.nominal_size)
516  , ranges(std::move(from.ranges))
517  { from.nominal_size = 0; }
range_list_t ranges
list of ranges
size_type nominal_size
current size
template<typename T>
lar::sparse_vector< T >::sparse_vector ( vector_t &&  from,
size_type  offset = 0 
)
inline

Constructor: a solid vector from an existing STL vector.

Parameters
fromvector to move data from
offset(default: 0) index the data starts from (preceeded by void)

Definition at line 536 of file sparse_vector.h.

536  :
537  nominal_size(0), ranges()
538  { add_range(offset, std::move(from)); }
const datarange_t & add_range(size_type offset, ITER first, ITER last)
Adds a sequence of elements as a range with specified offset.
range_list_t ranges
list of ranges
size_type nominal_size
current size
template<typename T>
lar::sparse_vector< T >::~sparse_vector ( )
default

Destructor: default.

Member Function Documentation

template<typename T>
static value_type lar::sparse_vector< T >::abs ( value_type  v)
inlinestatic

Returns the module of the specified value.

Definition at line 931 of file sparse_vector.h.

931 { return (v < value_zero)? -v: v; }
static constexpr value_type value_zero
a representation of 0
template<typename T>
template<typename ITER >
const datarange_t& lar::sparse_vector< T >::add_range ( size_type  offset,
ITER  first,
ITER  last 
)

Adds a sequence of elements as a range with specified offset.

Template Parameters
ITERtype of iterator
Parameters
offsetwhere to add the elements
firstiterator to the first element to be added
lastiterator after the last element to be added
Returns
the range where the new data was added

If the offset is beyond the current end of the sparse vector, void is added before the new range.

Existing ranges can be merged with the new data if they overlap.

Referenced by lar::sparse_vector< T >::add_range(), lar::sparse_vector< T >::make_void_around(), and butcher::EventButcher::produce().

template<typename T>
template<typename CONT >
const datarange_t& lar::sparse_vector< T >::add_range ( size_type  offset,
const CONT &  new_data 
)
inline

Copies the elements in container to a range with specified offset.

Template Parameters
CONTtype of container supporting the standard begin/end interface
Parameters
offsetwhere to add the elements
new_datacontainer holding the data to be copied
Returns
the range where the new data was added

If the offset is beyond the current end of the sparse vector, void is added before the new range.

Existing ranges can be merged with the new data if they overlap.

Definition at line 767 of file sparse_vector.h.

768  { return add_range(offset, new_data.begin(), new_data.end()); }
const datarange_t & add_range(size_type offset, ITER first, ITER last)
Adds a sequence of elements as a range with specified offset.
template<typename T >
const lar::sparse_vector< T >::datarange_t & lar::sparse_vector< T >::add_range ( size_type  offset,
vector_t &&  new_data 
)

Adds a sequence of elements as a range with specified offset.

Parameters
offsetwhere to add the elements
new_datacontainer holding the data to be moved
Returns
the range where the new data was added

If the offset is beyond the current end of the sparse vector, void is added before the new range.

Existing ranges can be merged with the new data if they overlap. If no merging happens, new_data vector is directly used as the new range added; otherwise, it is just copied.

Definition at line 1746 of file sparse_vector.h.

1747 {
1748  // insert the new range before the existing range which starts after offset
1749  range_iterator iInsert = std::upper_bound(
1750  ranges.begin(), ranges.end(), offset,
1752  );
1753 
1754  // is there a range before this, which includes the offset?
1755  if ((iInsert != ranges.begin()) && (iInsert-1)->borders(offset)) {
1756  // then we should extend it
1757  (--iInsert)->extend(offset, new_data.begin(), new_data.end());
1758  }
1759  else {
1760  // no range before the insertion one includes the offset of the new range;
1761  // ... we need to add it as a new range;
1762  // it is not really clear to me [GP] why I need a std::move here, since
1763  // new_data is a rvalue already; in doubt, I have painted all this kind
1764  // of constructs with move()s, just in case
1765  iInsert = insert_range(iInsert, { offset, std::move(new_data) });
1766  }
1767  return merge_ranges(iInsert);
1768 } // lar::sparse_vector<T>::add_range(vector)
range_list_t ranges
list of ranges
static bool less(const range_t &a, const range_t &b)
Returns if a is "less" than b.
datarange_t & merge_ranges(range_iterator iRange)
Merges all the following ranges.
range_iterator insert_range(range_iterator iInsert, const datarange_t &data)
Plug a new data range in the specified position; no check performed.
bool(* less_int_range)(size_type, const range_t &b)
Helper type to be used for binary searches.
range_list_t::iterator range_iterator
type of iterator over ranges
template<typename T>
template<typename ITER >
const lar::sparse_vector<T>::datarange_t& lar::sparse_vector< T >::add_range ( size_type  offset,
ITER  first,
ITER  last 
)

Definition at line 1725 of file sparse_vector.h.

References lar::sparse_vector< T >::add_range().

1726 {
1727  // insert the new range before the existing range which starts after offset
1728  range_iterator iInsert = find_next_range_iter(offset);
1729 
1730  // is there a range before this, which includes the offset?
1731  if ((iInsert != ranges.begin()) && (iInsert-1)->borders(offset)) {
1732  // then we should extend it
1733  (--iInsert)->extend(offset, first, last);
1734  }
1735  else {
1736  // no range before the insertion one includes the offset of the new range;
1737  // ... we need to add it as a new range
1738  iInsert = insert_range(iInsert, { offset, first, last });
1739  }
1740  return merge_ranges(iInsert);
1741 } // lar::sparse_vector<T>::add_range<ITER>()
range_list_t ranges
list of ranges
range_iterator find_next_range_iter(size_type index)
Returns an iterator to the range after index, or end() if none.
datarange_t & merge_ranges(range_iterator iRange)
Merges all the following ranges.
range_iterator insert_range(range_iterator iInsert, const datarange_t &data)
Plug a new data range in the specified position; no check performed.
range_list_t::iterator range_iterator
type of iterator over ranges
template<typename T>
template<typename ITER >
const datarange_t& lar::sparse_vector< T >::append ( ITER  first,
ITER  last 
)
inline

Adds a sequence of elements as a range at the end of the vector.

Parameters
firstiterator to the first element to be added
lastiterator after the last element to be added
Returns
the range where the new data was added

The input range is copied at the end of the sparse vector. If the end of the sparse vector was the end of a range, that range is expanded, otherwise a new one is created.

Definition at line 857 of file sparse_vector.h.

858  { return add_range(size(), first, last); }
size_type size() const
Returns the size of the vector.
const datarange_t & add_range(size_type offset, ITER first, ITER last)
Adds a sequence of elements as a range with specified offset.
template<typename T>
template<typename CONT >
const datarange_t& lar::sparse_vector< T >::append ( const CONT &  range_data)
inline

Adds a sequence of elements as a range at the end of the vector.

Parameters
range_datacontained holding the data to be copied or moved
Returns
the range where the new data was added

The input data is copied at the end of the sparse vector. If the end of the sparse vector was the end of a range, that range is expanded, otherwise a new one is created.

Definition at line 870 of file sparse_vector.h.

871  { return add_range(size(), range_data); }
size_type size() const
Returns the size of the vector.
const datarange_t & add_range(size_type offset, ITER first, ITER last)
Adds a sequence of elements as a range with specified offset.
template<typename T>
const datarange_t& lar::sparse_vector< T >::append ( vector_t &&  range_data)
inline

Adds a sequence of elements as a range at the end of the vector.

Parameters
range_datacontained holding the data to be copied or moved
Returns
the range where the new data was added

If there is a range at the end of the sparse vector, it will be expanded with the new data. Otherwise, this method will use the data vector directly as a new range added at the end of the sparse vector.

Definition at line 883 of file sparse_vector.h.

884  { return add_range(size(), std::move(range_data)); }
size_type size() const
Returns the size of the vector.
const datarange_t & add_range(size_type offset, ITER first, ITER last)
Adds a sequence of elements as a range with specified offset.
template<typename T>
template<typename ITER >
void lar::sparse_vector< T >::assign ( ITER  first,
ITER  last 
)
inline

Copies data from a sequence between two iterators.

Template Parameters
ITERtype of iterator
Parameters
firstiterator pointing to the first element to be copied
lastiterator pointing after the last element to be copied

The previous content of the sparse vector is lost.

Definition at line 658 of file sparse_vector.h.

658 { clear(); append(first, last); }
void clear()
Removes all the data, making the vector empty.
const datarange_t & append(ITER first, ITER last)
Adds a sequence of elements as a range at the end of the vector.
template<typename T>
template<typename CONT >
void lar::sparse_vector< T >::assign ( const CONT &  new_data)
inline

Copies data from a container.

Template Parameters
CONTtype of container supporting the standard begin/end interface
Parameters
new_datacontainer with the data to be copied

The previous content of the sparse vector is lost.

Definition at line 668 of file sparse_vector.h.

668 { clear(); append(new_data); }
void clear()
Removes all the data, making the vector empty.
const datarange_t & append(ITER first, ITER last)
Adds a sequence of elements as a range at the end of the vector.
template<typename T>
void lar::sparse_vector< T >::assign ( vector_t &&  new_data)
inline

Moves data from a vector.

Parameters
new_datavector with the data to be moved

The previous content of the sparse vector is lost.

Definition at line 676 of file sparse_vector.h.

676 { clear(); append(std::move(new_data)); }
void clear()
Removes all the data, making the vector empty.
const datarange_t & append(ITER first, ITER last)
Adds a sequence of elements as a range at the end of the vector.
template<typename T>
bool lar::sparse_vector< T >::back_is_void ( ) const
inline

Returns whether the sparse vector ends with void.

See also
is_void()

Definition at line 601 of file sparse_vector.h.

602  { return ranges.empty() || (ranges.back().end_index() < size()); }
size_type size() const
Returns the size of the vector.
range_list_t ranges
list of ranges
template<typename T >
lar::sparse_vector< T >::iterator lar::sparse_vector< T >::begin ( )
inline

Standard iterators interface.

Definition at line 1529 of file sparse_vector.h.

References evd::details::begin().

Referenced by operator<<(), and recob::Wire::Signal().

1530  { return iterator(*this, typename iterator::special::begin()); }
intermediate_table::iterator iterator
std::vector< evd::details::RawDigitInfo_t >::const_iterator begin(RawDigitCacheDataClass const &cache)
template<typename T >
lar::sparse_vector< T >::const_iterator lar::sparse_vector< T >::begin ( ) const
inline

Standard iterators interface.

Definition at line 1538 of file sparse_vector.h.

References evd::details::begin().

1539  { return const_iterator(*this, typename const_iterator::special::begin()); }
intermediate_table::const_iterator const_iterator
std::vector< evd::details::RawDigitInfo_t >::const_iterator begin(RawDigitCacheDataClass const &cache)
template<typename T>
range_const_iterator lar::sparse_vector< T >::begin_range ( ) const
inline

Returns a constant iterator to the first data range.

Definition at line 699 of file sparse_vector.h.

699 { return ranges.begin(); }
range_list_t ranges
list of ranges
template<typename T>
size_type lar::sparse_vector< T >::capacity ( ) const
inline

Returns the capacity of the vector (compatibility only)

Definition at line 557 of file sparse_vector.h.

557 { return nominal_size; }
size_type nominal_size
current size
template<typename T>
const_iterator lar::sparse_vector< T >::cbegin ( ) const
inline

Standard iterators interface.

Definition at line 572 of file sparse_vector.h.

572 { return begin(); }
iterator begin()
Standard iterators interface.
template<typename T>
const_iterator lar::sparse_vector< T >::cend ( ) const
inline

Standard iterators interface.

Definition at line 573 of file sparse_vector.h.

573 { return end(); }
iterator end()
Standard iterators interface.
template<typename T>
void lar::sparse_vector< T >::clear ( )
inline

Removes all the data, making the vector empty.

Definition at line 547 of file sparse_vector.h.

547 { ranges.clear(); nominal_size = 0; }
range_list_t ranges
list of ranges
size_type nominal_size
current size
template<typename T>
template<typename ITER , typename OP >
const datarange_t& lar::sparse_vector< T >::combine_range ( size_type  offset,
ITER  first,
ITER  last,
OP &&  op,
value_type  void_value = value_zero 
)

Combines a sequence of elements as a range with data at offset.

Template Parameters
ITERtype of iterator
OPcombination operation
Parameters
offsetwhere to add the elements
firstiterator to the first element to be added
lastiterator after the last element to be added
opoperation to be executed element by element
void_value(default: value_zero) the value to use for void cells
Returns
the range where the new data landed

This is a more generic version of add_range(), where instead of replacing the target data with the data in [ first, last [, the existing data is combined with the one in that interval. The operation op is a binary operation with signature equivalent to Data_t op(Data_t, Data_t), and the operation is equivalent to v[i + offset] = op(v[i + offset], *(first + offset)): op is a binary operation whose first operand is the existing value and the second one is the one being provided. If the cell i + offset is currently void, it will be created and the value used in the combination will be void_value.

If the offset is beyond the current end of the sparse vector, void is added before the new range.

Existing ranges can be merged with the new data if they overlap.

template<typename T>
template<typename CONT , typename OP >
const datarange_t& lar::sparse_vector< T >::combine_range ( size_type  offset,
const CONT &  other,
OP &&  op,
value_type  void_value = value_zero 
)
inline

Combines the elements in container with the data at offset.

Template Parameters
CONTtype of container supporting the standard begin/end interface
OPcombination operation
Parameters
offsetwhere to add the elements
othercontainer holding the data to be combined
opoperation to be executed element by element
void_value(default: value_zero) the value to use for void cells
Returns
the range where the new data was added
See also
combine_range()

This is equivalent to combine_range(size_type, ITER, ITER, OP, Data_t) using as the new data range the full content of other container.

Definition at line 835 of file sparse_vector.h.

839  {
840  return combine_range(offset, other.begin(), other.end(),
841  std::forward<OP>(op), void_value);
842  }
const datarange_t & combine_range(size_type offset, ITER first, ITER last, OP &&op, value_type void_value=value_zero)
Combines a sequence of elements as a range with data at offset.
template<typename T>
template<typename ITER , typename OP >
auto lar::sparse_vector< T >::combine_range ( size_type  offset,
ITER  first,
ITER  last,
OP &&  op,
value_type  void_value 
) -> const datarange_t&

Definition at line 1773 of file sparse_vector.h.

References evd::details::end(), and lar::sparse_vector< T >::datarange_t::get_iterator().

1778 {
1779  /*
1780  * This is a complicate enough task, that we go brute force:
1781  * 1) combine all the input elements within the datarange where offset falls
1782  * in
1783  * 2) create a new datarange combining void with the remaining input elements
1784  * 3) if the void area is over before the input elements are, repeat steps
1785  * (1) and (2) with the updated offset
1786  * 4) at this point we'll have a train of contiguous ranges, result of
1787  * combination of the input elements alternating with existing elements
1788  * and with void cells: apply the regular merge algorithm
1789  *
1790  */
1791 
1792  auto src = first;
1793  auto const insertionPoint = offset; // saved for later
1794  auto destRange = find_extending_range_iter(offset, ranges.begin());
1795  while (src != last) {
1796 
1797  //
1798  // (1) combine all the input elements within the datarange including offset
1799  //
1800  if ((destRange != end_range()) && (offset < destRange->end_index())) {
1801  // this means `destRange` contains offset:
1802  // combine input data until this range is over (or input data is over)
1803  auto dest = destRange->get_iterator(offset);
1804 
1805  auto const end = destRange->end();
1806  while (src != last) {
1807  *dest = op(*dest, *src);
1808  ++src;
1809  ++offset;
1810  if (++dest == end) break;
1811  } // while
1812  if (src == last) break;
1813  offset = destRange->end_index();
1814  } // if
1815 
1816  //
1817  // (2) create a new datarange combining void with input elements
1818  //
1819  // at this point, offset is in the void, and we do have more input data;
1820  // we fill as much void as we can with data, creating a new range.
1821  // When to stop? at the beginning of the next range, or when data is over
1822  ++destRange;
1823  size_type const newRangeSize = (destRange == end_range())
1824  ? std::distance(src, last): (destRange->begin_index() - offset);
1825 
1826  // prepare the data (we'll plug it in directly)
1827  vector_t combinedData;
1828  combinedData.reserve(newRangeSize);
1829  size_type i = 0;
1830  while (i++ < newRangeSize) {
1831  combinedData.push_back(op(void_value, *src));
1832  if (++src == last) break; // no more data
1833  }
1834  // move the data as a new range inserted before the next range we just found
1835  // return value is the iterator to the inserted range
1836  destRange = insert_range(destRange, { offset, std::move(combinedData) });
1837 
1838  //
1839  // (3) if there is more input, repeat steps (1) and (2) with updated offset
1840  //
1841  offset = destRange->end_index();
1842  ++destRange;
1843  } // while
1844 
1845  //
1846  // (4) apply the regular merge algorithm
1847  //
1848  return merge_ranges(find_extending_range_iter(insertionPoint));
1849 
1850 } // lar::sparse_vector<T>::combine_range<ITER>()
std::vector< value_type > vector_t
type of STL vector holding this data
range_iterator find_extending_range_iter(size_type index)
Returns an iterator to the range no earlier than index, or end() if none.
range_list_t ranges
list of ranges
iterator end()
Standard iterators interface.
vector_t::size_type size_type
size type
datarange_t & merge_ranges(range_iterator iRange)
Merges all the following ranges.
range_iterator insert_range(range_iterator iInsert, const datarange_t &data)
Plug a new data range in the specified position; no check performed.
range_const_iterator end_range() const
Returns a constant iterator to after the last data range.
template<typename T >
lar::sparse_vector< T >::size_type lar::sparse_vector< T >::count ( ) const
inline

Returns the number of non-void cells.

Definition at line 1596 of file sparse_vector.h.

References s, lar::sparse_vector< T >::set_at(), and lar::range_t< SIZE >::size().

1598 {
1599  return std::accumulate(begin_range(), end_range(), size_type(0),
1600  [](size_type s, const datarange_t& rng) { return s + rng.size(); }
1601  );
1602 } // count()
Float_t s
Definition: plot.C:23
vector_t::size_type size_type
size type
range_const_iterator begin_range() const
Returns a constant iterator to the first data range.
range_const_iterator end_range() const
Returns a constant iterator to after the last data range.
template<typename T >
lar::sparse_vector< T >::range_iterator lar::sparse_vector< T >::eat_range_head ( range_iterator  iRange,
size_t  index 
)
protected

Voids the starting elements up to index (excluded) of a given range.

Definition at line 1997 of file sparse_vector.h.

Referenced by lar::sparse_vector< T >::merge_ranges().

1998 {
1999  if (index <= iRange->begin_index()) return iRange;
2000  if (index >= iRange->end_index()) return ranges.erase(iRange);
2001  iRange->move_head(index);
2002  return iRange;
2003 } // lar::sparse_vector<T>::eat_range_head()
range_list_t ranges
list of ranges
template<typename T>
bool lar::sparse_vector< T >::empty ( ) const
inline

Returns whether the vector is empty.

Definition at line 554 of file sparse_vector.h.

554 { return size() == 0; }
size_type size() const
Returns the size of the vector.
template<typename T >
lar::sparse_vector< T >::iterator lar::sparse_vector< T >::end ( )
inline

Standard iterators interface.

Definition at line 1533 of file sparse_vector.h.

References evd::details::end().

Referenced by operator<<(), and recob::Wire::Signal().

1534  { return iterator(*this, typename iterator::special::end()); }
intermediate_table::iterator iterator
std::vector< evd::details::RawDigitInfo_t >::const_iterator end(RawDigitCacheDataClass const &cache)
template<typename T >
lar::sparse_vector< T >::const_iterator lar::sparse_vector< T >::end ( ) const
inline

Standard iterators interface.

Definition at line 1543 of file sparse_vector.h.

References evd::details::end().

1544  { return const_iterator(*this, typename const_iterator::special::end()); }
intermediate_table::const_iterator const_iterator
std::vector< evd::details::RawDigitInfo_t >::const_iterator end(RawDigitCacheDataClass const &cache)
template<typename T>
range_const_iterator lar::sparse_vector< T >::end_range ( ) const
inline

Returns a constant iterator to after the last data range.

Definition at line 702 of file sparse_vector.h.

702 { return ranges.end(); }
range_list_t ranges
list of ranges
template<typename T >
size_t lar::sparse_vector< T >::expected_vector_size ( size_t  size)
inlinestatic

Returns the expected size taken by a vector of specified size.

Definition at line 2017 of file sparse_vector.h.

References max.

2017  {
2018  // apparently, a chunk of heap memory takes at least 32 bytes;
2019  // that means that a vector of 1 or 5 32-bit integers takes the same
2020  // space; the overhead appears to be 8 bytes, which can be allocated
2021  return sizeof(vector_t)
2022  + std::max(size_t(32), (alignof(datarange_t)*size + 8));
2023 } // lar::sparse_vector<T>::expected_vector_size()
std::vector< value_type > vector_t
type of STL vector holding this data
size_type size() const
Returns the size of the vector.
Int_t max
Definition: plot.C:27
template<typename T>
range_iterator lar::sparse_vector< T >::find_extending_range_iter ( size_type  index)
inlineprotected

Returns an iterator to the range no earlier than index, or end() if none.

Parameters
indexthe absolute index
Returns
iterator to the range including index, or the next range if none

The returned iterator points to a range that "borders" the specified index, meaning that teh cell at index is either within the range, or it is the one immediately after that range. If index is in the middle of the void, though (i.e. if the previous cell is void), the next range is returned instead. Finally, if there is no next range, end_range() is returned.

The result may be also interpreted as follow: if the start of the returned range is lower than index, then the cell at index belongs to that range. Otherwise, it initiates its own range (but that range might end up being contiguous to the next(.

Definition at line 1015 of file sparse_vector.h.

Referenced by lar::sparse_vector< T >::find_extending_range_iter(), and lar::sparse_vector< T >::find_next_range_iter().

1016  { return find_extending_range_iter(index, ranges.begin()); }
range_iterator find_extending_range_iter(size_type index)
Returns an iterator to the range no earlier than index, or end() if none.
range_list_t ranges
list of ranges
template<typename T>
range_const_iterator lar::sparse_vector< T >::find_extending_range_iter ( size_type  index) const
inlineprotected

Returns an iterator to the range no earlier than index, or end() if none.

Parameters
indexthe absolute index
Returns
iterator to the range including index, or the next range if none

The returned iterator points to a range that "borders" the specified index, meaning that teh cell at index is either within the range, or it is the one immediately after that range. If index is in the middle of the void, though (i.e. if the previous cell is void), the next range is returned instead. Finally, if there is no next range, end_range() is returned.

The result may be also interpreted as follow: if the start of the returned range is lower than index, then the cell at index belongs to that range. Otherwise, it initiates its own range (but that range might end up being contiguous to the next(.

Definition at line 1017 of file sparse_vector.h.

1018  { return find_extending_range_iter(index, ranges.cbegin()); }
range_iterator find_extending_range_iter(size_type index)
Returns an iterator to the range no earlier than index, or end() if none.
range_list_t ranges
list of ranges
template<typename T >
lar::sparse_vector< T >::range_iterator lar::sparse_vector< T >::find_extending_range_iter ( size_type  index,
range_iterator  rbegin 
)
protected

Returns an iterator to the range after index, or end() if none.

Parameters
indexthe absolute index
rbeginconsider only from this range on
Returns
iterator to the next range not including index, or ranges.end() if none

Definition at line 1952 of file sparse_vector.h.

References lar::sparse_vector< T >::find_extending_range_iter().

1953 {
1954  // this range has the offset (first index) above the index argument:
1955  auto it = find_next_range_iter(index, rbegin);
1956  // if index were not void, would it belong to the previous range?
1957  // if so, the previus range is the one we want
1958  return ((it != rbegin) && std::prev(it)->borders(index))? std::prev(it): it;
1959 } // lar::sparse_vector<T>::find_extending_range_iter()
range_iterator find_next_range_iter(size_type index)
Returns an iterator to the range after index, or end() if none.
template<typename T >
lar::sparse_vector< T >::range_const_iterator lar::sparse_vector< T >::find_extending_range_iter ( size_type  index,
range_const_iterator  rbegin 
) const
protected

Returns an iterator to the range after index, or end() if none.

Parameters
indexthe absolute index
rbeginconsider only from this range on
Returns
iterator to the next range not including index, or ranges.end() if none

Definition at line 1965 of file sparse_vector.h.

References lar::sparse_vector< T >::merge_ranges().

1966 {
1967  // this range has the offset (first index) above the index argument:
1968  auto it = find_next_range_iter(index, rbegin);
1969  // if index were not void, would it belong to the previous range?
1970  // if so, the previus range is the one we want
1971  return ((it != rbegin) && std::prev(it)->borders(index))? std::prev(it): it;
1972 } // lar::sparse_vector<T>::find_extending_range_iter() const
range_iterator find_next_range_iter(size_type index)
Returns an iterator to the range after index, or end() if none.
template<typename T>
range_iterator lar::sparse_vector< T >::find_next_range_iter ( size_type  index)
inlineprotected

Returns an iterator to the range after index, or end() if none.

Parameters
indexthe absolute index
Returns
iterator to the next range not including index, or ranges.end() if none

Definition at line 977 of file sparse_vector.h.

Referenced by lar::sparse_vector< T >::find_next_range_iter(), and lar::sparse_vector< T >::is_valid().

978  { return find_next_range_iter(index, ranges.begin()); }
range_list_t ranges
list of ranges
range_iterator find_next_range_iter(size_type index)
Returns an iterator to the range after index, or end() if none.
template<typename T>
range_const_iterator lar::sparse_vector< T >::find_next_range_iter ( size_type  index) const
inlineprotected

Returns an iterator to the range after index, or end() if none.

Parameters
indexthe absolute index
Returns
iterator to the next range not including index, or ranges.end() if none

Definition at line 979 of file sparse_vector.h.

980  { return find_next_range_iter(index, ranges.cbegin()); }
range_list_t ranges
list of ranges
range_iterator find_next_range_iter(size_type index)
Returns an iterator to the range after index, or end() if none.
template<typename T >
lar::sparse_vector< T >::range_iterator lar::sparse_vector< T >::find_next_range_iter ( size_type  index,
range_iterator  rbegin 
)
protected

Returns an iterator to the range after index, or ranges.end() if none.

Parameters
indexthe absolute index
rbeginconsider only from this range on
Returns
iterator to the next range not including index, or ranges.end() if none

Definition at line 1927 of file sparse_vector.h.

References lar::sparse_vector< T >::find_next_range_iter().

1928 {
1929  // this range has the offset (first index) above the index argument:
1930  return std::upper_bound(
1931  rbegin, ranges.end(), index,
1933  );
1934 } // lar::sparse_vector<T>::find_next_range_iter()
range_list_t ranges
list of ranges
static bool less(const range_t &a, const range_t &b)
Returns if a is "less" than b.
bool(* less_int_range)(size_type, const range_t &b)
Helper type to be used for binary searches.
template<typename T >
lar::sparse_vector< T >::range_const_iterator lar::sparse_vector< T >::find_next_range_iter ( size_type  index,
range_const_iterator  rbegin 
) const
protected

Returns an iterator to the range after index, or ranges.end() if none.

Parameters
indexthe absolute index
rbeginconsider only from this range on
Returns
iterator to the next range not including index, or ranges.end() if none

Definition at line 1939 of file sparse_vector.h.

References lar::sparse_vector< T >::find_extending_range_iter().

1940 {
1941  // this range has the offset (first index) above the index argument:
1942  return std::upper_bound(
1943  rbegin, ranges.end(), index,
1945  );
1946 } // lar::sparse_vector<T>::find_next_range_iter() const
range_list_t ranges
list of ranges
static bool less(const range_t &a, const range_t &b)
Returns if a is "less" than b.
bool(* less_int_range)(size_type, const range_t &b)
Helper type to be used for binary searches.
template<typename T >
const lar::sparse_vector< T >::datarange_t & lar::sparse_vector< T >::find_range ( size_type  index) const

Returns the range containing the specified index.

Parameters
indexabsolute index of the element to be seeked
Returns
the containing range
Exceptions
std::out_of_rangeif index is in no range (how appropriate!)
See also
is_void()

Definition at line 1689 of file sparse_vector.h.

1690 {
1691  if (ranges.empty()) throw std::out_of_range("empty sparse vector");
1692  // range on the index:
1693  range_const_iterator iNextRange = find_range_iterator(index);
1694  if (iNextRange == ranges.end())
1695  throw std::out_of_range("index in no range of the sparse vector");
1696  return *iNextRange;
1697 } // lar::sparse_vector<T>::find_range() const
range_list_t ranges
list of ranges
range_list_t::const_iterator range_const_iterator
type of constant iterator over ranges
range_const_iterator find_range_iterator(size_type index) const
Returns an iterator to the range containing the specified index.
template<typename T >
lar::sparse_vector< T >::datarange_t & lar::sparse_vector< T >::find_range ( size_type  index)
inline

Returns the range containing the specified index.

Parameters
indexabsolute index of the element to be seeked
Returns
the containing range
Exceptions
std::out_of_rangeif index is in no range (how appropriate!)
See also
is_void()

Definition at line 1701 of file sparse_vector.h.

1702 {
1703  return const_cast<datarange_t&>
1704  (const_cast<const this_t*>(this)->find_range(index));
1705 } // lar::sparse_vector<T>::find_range()
sparse_vector< T > this_t
const datarange_t & find_range(size_type index) const
Returns the range containing the specified index.
template<typename T >
lar::sparse_vector< T >::range_const_iterator lar::sparse_vector< T >::find_range_iterator ( size_type  index) const

Returns an iterator to the range containing the specified index.

Parameters
indexabsolute index of the element to be seeked
Returns
iterator to containing range, or get_ranges().end() if in void
Exceptions
std::out_of_rangeif index is not in the vector
See also
is_void()

Definition at line 1666 of file sparse_vector.h.

1667 {
1668  if (ranges.empty()) throw std::out_of_range("empty sparse vector");
1669  // range after the index:
1670  range_const_iterator iNextRange = find_next_range_iter(index);
1671  return ((iNextRange == ranges.begin())
1672  || (index >= (--iNextRange)->end_index()))?
1673  ranges.end(): iNextRange;
1674 } // lar::sparse_vector<T>::find_range_iterator() const
range_list_t ranges
list of ranges
range_iterator find_next_range_iter(size_type index)
Returns an iterator to the range after index, or end() if none.
range_list_t::const_iterator range_const_iterator
type of constant iterator over ranges
template<typename T >
lar::sparse_vector< T >::range_iterator lar::sparse_vector< T >::find_range_iterator ( size_type  index)
inline

Returns the internal list of non-void ranges.

Definition at line 1679 of file sparse_vector.h.

1680 {
1681  return ranges.begin() + (
1682  (const_cast<const this_t*>(this)->find_range_iterator(index))
1683  - ranges.begin());
1684 } // lar::sparse_vector<T>::find_range_iterator()
range_list_t ranges
list of ranges
sparse_vector< T > this_t
range_const_iterator find_range_iterator(size_type index) const
Returns an iterator to the range containing the specified index.
template<typename T >
lar::sparse_vector< T >::size_type lar::sparse_vector< T >::fix_size ( )
protected

Extends the vector size according to the last range.

Definition at line 2007 of file sparse_vector.h.

References max.

2007  {
2008  if (!ranges.empty())
2009  nominal_size = std::max(nominal_size, ranges.back().end_index());
2010  return nominal_size;
2011 } // lar::sparse_vector<T>::fix_size()
range_list_t ranges
list of ranges
Int_t max
Definition: plot.C:27
size_type nominal_size
current size
template<typename T>
const range_list_t& lar::sparse_vector< T >::get_ranges ( ) const
inline

Returns the internal list of non-void ranges.

Definition at line 690 of file sparse_vector.h.

Referenced by hit::HitAnaAlg::FillWireInfo(), hit::GausHitFinder::produce(), and hit::DPRawHitFinder::produce().

690 { return ranges; }
range_list_t ranges
list of ranges
template<typename T>
range_iterator lar::sparse_vector< T >::insert_range ( range_iterator  iInsert,
const datarange_t data 
)
inlineprotected

Plug a new data range in the specified position; no check performed.

Definition at line 1041 of file sparse_vector.h.

1042  { return data.empty()? iInsert: ranges.insert(iInsert, data); }
range_list_t ranges
list of ranges
template<typename T>
range_iterator lar::sparse_vector< T >::insert_range ( range_iterator  iInsert,
datarange_t &&  data 
)
inlineprotected

Plug a new data range in the specified position; no check performed.

Definition at line 1043 of file sparse_vector.h.

1044  { return data.empty()? iInsert: ranges.insert(iInsert, std::move(data)); }
range_list_t ranges
list of ranges
template<typename T>
static value_type lar::sparse_vector< T >::is_equal ( value_type  a,
value_type  b 
)
inlinestatic

Returns whether two values are the same.

Definition at line 941 of file sparse_vector.h.

942  { return is_zero(abs(a - b)); }
static value_type abs(value_type v)
Returns the module of the specified value.
static value_type is_zero(value_type v)
Returns whether the value is exactly zero.
template<typename T>
static value_type lar::sparse_vector< T >::is_equal ( value_type  a,
value_type  b,
value_type  thr 
)
inlinestatic

Returns whether two values are the same below a given threshold.

Definition at line 945 of file sparse_vector.h.

946  { return is_zero(abs(a - b), thr); }
static value_type abs(value_type v)
Returns the module of the specified value.
static value_type is_zero(value_type v)
Returns whether the value is exactly zero.
template<typename T >
bool lar::sparse_vector< T >::is_valid ( ) const

Returns if the vector is in a valid state.

The vector is in a valid state if:

  • no ranges overlap or touch each other (a void gap must exist)
  • no range is empty
  • all ranges are sorted
  • the size of the vector is not smaller than the sum of the size of the ranges plus the internal gaps An invalid state can be the result of “too smart” use of this class, or of a bug, which should be reported to the author.

Definition at line 1903 of file sparse_vector.h.

References lar::sparse_vector< T >::find_next_range_iter().

1903  {
1904  // a sparse vector with no non-null elements can't be detected invalid
1905  if (ranges.empty()) return true;
1906 
1907  range_const_iterator iNext = ranges.begin(), rend = ranges.end();
1908  while (iNext != rend) {
1909  range_const_iterator iRange = iNext++;
1910  if (iRange->empty()) return false;
1911  if (iNext != rend) {
1912  if (!(*iRange < *iNext)) return false;
1913  if (!iRange->separate(*iNext)) return false;
1914  }
1915  } // while
1916  if (nominal_size < ranges.back().end_index()) return false;
1917  return true;
1918 } // lar::sparse_vector<T>::is_valid()
range_list_t ranges
list of ranges
range_list_t::const_iterator range_const_iterator
type of constant iterator over ranges
size_type nominal_size
current size
template<typename T >
bool lar::sparse_vector< T >::is_void ( size_type  index) const

Returns whether the specified position is void.

Parameters
indexposition of the cell to be tested
Exceptions
out_of_rangeif index is not in the vector
See also
is_back_void()

Definition at line 1585 of file sparse_vector.h.

1585  {
1586  if (ranges.empty() || (index >= size()))
1587  throw std::out_of_range("empty sparse vector");
1588  // range after the index:
1589  range_const_iterator iNextRange = find_next_range_iter(index);
1590  return ((iNextRange == ranges.begin())
1591  || ((--iNextRange)->end_index() <= index));
1592 } // lar::sparse_vector<T>::is_void()
size_type size() const
Returns the size of the vector.
range_list_t ranges
list of ranges
range_iterator find_next_range_iter(size_type index)
Returns an iterator to the range after index, or end() if none.
range_list_t::const_iterator range_const_iterator
type of constant iterator over ranges
template<typename T>
static value_type lar::sparse_vector< T >::is_zero ( value_type  v)
inlinestatic

Returns whether the value is exactly zero.

Definition at line 934 of file sparse_vector.h.

934 { return v == value_zero; }
static constexpr value_type value_zero
a representation of 0
template<typename T>
static value_type lar::sparse_vector< T >::is_zero ( value_type  v,
value_type  thr 
)
inlinestatic

Returns whether the value is zero below a given threshold.

Definition at line 937 of file sparse_vector.h.

938  { return abs(v - value_zero) <= thr; }
static value_type abs(value_type v)
Returns the module of the specified value.
static constexpr value_type value_zero
a representation of 0
template<typename T >
void lar::sparse_vector< T >::make_void ( iterator  first,
iterator  last 
)

Makes all the elements from first and before last void.

Definition at line 1854 of file sparse_vector.h.

References lar::sparse_vector< T >::const_iterator::cont, lar::sparse_vector< T >::const_iterator::get_current_range(), and lar::sparse_vector< T >::const_iterator::index.

1854  {
1855  // iterators have in "currentRange" either the range they point into,
1856  // or the range next to the void they point to
1857 
1858  if ((first.cont != this) || (last.cont != this)) {
1859  throw std::runtime_error
1860  ("lar::sparse_vector::make_void(): iterators from alien container");
1861  }
1862  // if first is after next, no range is identified
1863  if (first >= last) return;
1864 
1866  first_range
1867  = ranges.begin() + (first.get_current_range() - ranges.begin()),
1868  last_range = ranges.begin() + (last.get_current_range() - ranges.begin());
1869 
1870  //--- "first": void up to this iterator ---
1871  // if first in the last void region, there is nothing to erase
1872  if (first_range == ranges.end()) return;
1873 
1874  // if first is in the middle of a valid range instead, we have to resize it
1875  if (first.index > first_range->begin_index()) {
1876  if (first_range == last_range) {
1877  // we are going to erase a subset of a range;
1878  // this effectively creates two ranges;
1879  // first create the rightmost (last) range, and add it to the list
1880  last_range = ranges.emplace(++last_range, last.index,
1881  first_range->begin() + first_range->relative_index(last.index),
1882  first_range->end()
1883  );
1884  // then cut the existing one
1885  first_range->move_tail(first.index);
1886  return;
1887  }
1888  first_range->move_tail(first.index);
1889  ++first_range; // from next range on, start voiding
1890  }
1891 
1892  //--- "last"
1893  // if the index is inside a range, remove up to it
1894  if ((last_range != ranges.end()) && (last.index > last_range->begin_index()))
1895  eat_range_head(last_range, last.index);
1896 
1897  // finally, remove entirely the ranges in between
1898  ranges.erase(first_range, last_range);
1899 } // lar::sparse_vector<T>::make_void()
range_iterator eat_range_head(range_iterator iRange, size_t index)
Voids the starting elements up to index (excluded) of a given range.
range_list_t ranges
list of ranges
range_list_t::iterator range_iterator
type of iterator over ranges
template<typename T >
void lar::sparse_vector< T >::make_void_around ( size_type  index)

Casts the whole range with the specified item into the void.

Parameters
indexabsolute index of the element whose range is cast to void
Exceptions
std::out_of_rangeif index is not in the vector
See also
unset(), make_void()

Definition at line 1709 of file sparse_vector.h.

References lar::sparse_vector< T >::add_range().

1709  {
1710  if (ranges.empty() || (index >= size()))
1711  throw std::out_of_range("empty sparse vector");
1712  // range after the index:
1713  range_iterator iNextRange = find_next_range_iter(index);
1714  if ((iNextRange == ranges.begin())
1715  || ((--iNextRange)->end_index() <= index))
1716  {
1717  return;
1718  }
1719  ranges.erase(iNextRange);
1720 } // lar::sparse_vector<T>::make_void_around()
size_type size() const
Returns the size of the vector.
range_list_t ranges
list of ranges
range_iterator find_next_range_iter(size_type index)
Returns an iterator to the range after index, or end() if none.
range_list_t::iterator range_iterator
type of iterator over ranges
template<typename T >
lar::sparse_vector< T >::datarange_t & lar::sparse_vector< T >::merge_ranges ( range_iterator  iRange)
protected

Merges all the following ranges.

Definition at line 1977 of file sparse_vector.h.

References lar::sparse_vector< T >::eat_range_head(), and lar::sparse_vector< T >::datarange_t::extend().

Referenced by lar::sparse_vector< T >::find_extending_range_iter().

1978 {
1979  range_iterator iNext = iRange + 1;
1980  while (iNext != ranges.end()) {
1981  if (!iRange->borders(iNext->begin_index())) break;
1982  // iRange content dominates, but if iNext has data beyond it,
1983  // then we copy it
1984  if (iNext->end_index() > iRange->end_index()) {
1985  iRange->extend
1986  (iRange->end_index(), iNext->get_iterator(iRange->end_index()), iNext->end());
1987  }
1988  iNext = ranges.erase(iNext);
1989  } // while
1990  fix_size();
1991  return *iRange;
1992 } // lar::sparse_vector<T>::merge_ranges()
size_type fix_size()
Extends the vector size according to the last range.
range_list_t ranges
list of ranges
range_list_t::iterator range_iterator
type of iterator over ranges
template<typename T >
size_t lar::sparse_vector< T >::min_gap ( )
inlinestatic

Minimum optimal gap between ranges (a guess)

Definition at line 2027 of file sparse_vector.h.

2027  {
2028  // we assume here that there is no additional overhead by alignment;
2029  // the gap adds the space of another datarange_t, including the vector,
2030  // its data and overhead from heap (apparently, 8 bytes);
2031  //
2032  return (sizeof(datarange_t) + 8) / sizeof(value_type) + 1; // round up
2033 } // lar::sparse_vector<T>::min_gap()
T value_type
type of the stored values
template<typename T>
size_type lar::sparse_vector< T >::minimum_size ( ) const
inlineprotected

Returns the size determined by the ranges already present.

Definition at line 1036 of file sparse_vector.h.

1037  { return ranges.empty()? 0: ranges.back().end_index(); }
range_list_t ranges
list of ranges
template<typename T>
size_type lar::sparse_vector< T >::n_ranges ( ) const
inline

Returns the internal list of non-void ranges.

Definition at line 693 of file sparse_vector.h.

693 { return ranges.size(); }
range_list_t ranges
list of ranges
template<typename T>
sparse_vector& lar::sparse_vector< T >::operator= ( sparse_vector< T > const &  )
default

Copy assignment: default.

template<typename T>
sparse_vector& lar::sparse_vector< T >::operator= ( sparse_vector< T > &&  from)
inline

Move assignment.

Definition at line 523 of file sparse_vector.h.

524  {
525  ranges = std::move(from.ranges);
526  nominal_size = from.nominal_size;
527  from.nominal_size = 0;
528  return *this;
529  } // operator= (sparse_vector&&)
range_list_t ranges
list of ranges
size_type nominal_size
current size
template<typename T >
lar::sparse_vector< T >::value_type lar::sparse_vector< T >::operator[] ( size_type  index) const

Access to an element (read only)

Definition at line 1548 of file sparse_vector.h.

References lar::range_t< SIZE >::end_index().

1549 {
1550  // first range not including the index
1551  range_const_iterator iNextRange = find_next_range_iter(index);
1552 
1553  // if not even the first range includes the index, we are in the void
1554  // (or in some negative index space, if index signedness allowed);
1555  if (iNextRange == ranges.begin()) return value_zero;
1556 
1557  // otherwise, let's take the previous range;
1558  // if it includes the index, we return its value;
1559  // or it precedes it, and our index is in the void: return zero
1560  const datarange_t& range(*--iNextRange);
1561  return (index < range.end_index())? range[index]: value_zero;
1562 } // lar::sparse_vector<T>::operator[]
const datarange_t & range(size_t i) const
Returns the i-th non-void range (zero-based)
static constexpr value_type value_zero
a representation of 0
size_type end_index() const
Returns the first absolute index not included in the range.
range_list_t ranges
list of ranges
range_iterator find_next_range_iter(size_type index)
Returns an iterator to the range after index, or end() if none.
range_list_t::const_iterator range_const_iterator
type of constant iterator over ranges
template<typename T >
lar::sparse_vector< T >::reference lar::sparse_vector< T >::operator[] ( size_type  index)

Access to an element (read/write for non-void elements only!)

Definition at line 1567 of file sparse_vector.h.

References lar::range_t< SIZE >::end_index().

1568 {
1569  // first range not including the index
1570  range_iterator iNextRange = find_next_range_iter(index);
1571 
1572  // if not even the first range includes the index, we are in the void
1573  // (or in some negative index space, if index signedness allowed);
1574  if (iNextRange == ranges.begin()) return reference();
1575 
1576  // otherwise, let's take the previous range;
1577  // if it includes the index, we return its value;
1578  // or it precedes it, and our index is in the void: return zero
1579  datarange_t& range(*--iNextRange);
1580  return (index < range.end_index())? reference(range[index]): reference();
1581 } // lar::sparse_vector<T>::operator[]
const datarange_t & range(size_t i) const
Returns the i-th non-void range (zero-based)
size_type end_index() const
Returns the first absolute index not included in the range.
range_list_t ranges
list of ranges
range_iterator find_next_range_iter(size_type index)
Returns an iterator to the range after index, or end() if none.
range_list_t::iterator range_iterator
type of iterator over ranges
template<typename T>
bool lar::sparse_vector< T >::optimize ( )
inline

Performs internal optimization, returns whether the object was changed.

Definition at line 921 of file sparse_vector.h.

921 { return optimize(min_gap()); }
static size_t min_gap()
Minimum optimal gap between ranges (a guess)
bool optimize()
Performs internal optimization, returns whether the object was changed.
template<typename T>
bool lar::sparse_vector< T >::optimize ( size_t  )
inline

Performs internal optimization, returns whether the object was changed.

Definition at line 922 of file sparse_vector.h.

922 { return false; /* no optimization implemented yet */ }
template<typename T>
void lar::sparse_vector< T >::push_back ( value_type  value)
inline

Adds one element to the end of the vector (zero values too)

Parameters
valuevalue to be added

Definition at line 631 of file sparse_vector.h.

631 { resize(size() + 1, value); }
void resize(size_type new_size)
Resizes the vector to the specified size, adding void.
size_type size() const
Returns the size of the vector.
std::string value(boost::any const &)
template<typename T>
void lar::sparse_vector< T >::push_back ( value_type  value,
value_type  thr 
)
inline

Adds one element to the end of the vector (if zero, just adds void)

Parameters
valuevalue to be added
thrthreshold below which the value is considered zero

If the threshold is strictly negative, all values are pushed back

Definition at line 640 of file sparse_vector.h.

641  {
642  if (is_zero(value, thr)) resize(size() + 1);
643  else push_back(value);
644  } // push_back()
void resize(size_type new_size)
Resizes the vector to the specified size, adding void.
size_type size() const
Returns the size of the vector.
static value_type is_zero(value_type v)
Returns whether the value is exactly zero.
std::string value(boost::any const &)
void push_back(value_type value)
template<typename T>
const datarange_t& lar::sparse_vector< T >::range ( size_t  i) const
inline

Returns the i-th non-void range (zero-based)

Definition at line 696 of file sparse_vector.h.

696 { return ranges[i]; }
range_list_t ranges
list of ranges
template<typename T >
void lar::sparse_vector< T >::resize ( size_type  new_size)

Resizes the vector to the specified size, adding void.

Definition at line 1488 of file sparse_vector.h.

1488  {
1489  if (new_size >= size()) {
1490  nominal_size = new_size;
1491  return;
1492  }
1493 
1494  // truncating...
1495  range_iterator iLastRange = find_next_range_iter(new_size);
1496  ranges.erase(iLastRange, ranges.end());
1497  if (!ranges.empty()) {
1498  range_iterator iLastRange = ranges.end() - 1;
1499  if (new_size == iLastRange->begin_index())
1500  ranges.erase(iLastRange);
1501  else if (new_size < iLastRange->end_index())
1502  iLastRange->resize(new_size - iLastRange->begin_index());
1503  } // if we have ranges
1504 
1505  // formally resize
1506  nominal_size = new_size;
1507 } // lar::sparse_vector<T>::resize()
size_type size() const
Returns the size of the vector.
range_list_t ranges
list of ranges
range_iterator find_next_range_iter(size_type index)
Returns an iterator to the range after index, or end() if none.
size_type nominal_size
current size
range_list_t::iterator range_iterator
type of iterator over ranges
template<typename T >
void lar::sparse_vector< T >::resize ( size_type  new_size,
value_type  def_value 
)

Resizes the vector to the specified size, adding def_value.

Definition at line 1511 of file sparse_vector.h.

1511  {
1512  if (new_size == size()) return;
1513  if (new_size > size()) {
1514 
1515  if (back_is_void()) // add a new range
1516  append(vector_t(new_size - size(), def_value));
1517  else // extend the last range
1518  ranges.back().resize(new_size - ranges.back().begin_index(), def_value);
1519 
1520  nominal_size = new_size;
1521  return;
1522  }
1523  // truncating is the same whether there is a default value or not
1524  resize(new_size);
1525 } // lar::sparse_vector<T>::resize()
std::vector< value_type > vector_t
type of STL vector holding this data
void resize(size_type new_size)
Resizes the vector to the specified size, adding void.
size_type size() const
Returns the size of the vector.
range_list_t ranges
list of ranges
bool back_is_void() const
Returns whether the sparse vector ends with void.
const datarange_t & append(ITER first, ITER last)
Adds a sequence of elements as a range at the end of the vector.
size_type nominal_size
current size
template<typename T >
lar::sparse_vector< T >::value_type & lar::sparse_vector< T >::set_at ( size_type  index,
value_type  value 
)

Writes into an element (creating or expanding a range if needed)

Parameters
indexthe index of the element to set
valuethe value to be set
Returns
a reference to the changed value
See also
unset_at()

Note that setting the value to zero will not cast the element into void. Use unset_at for that.

Definition at line 1607 of file sparse_vector.h.

References lar::range_t< SIZE >::end_index().

Referenced by lar::sparse_vector< T >::count().

1608 {
1609  // first range not including the index
1610  range_iterator iNextRange = find_next_range_iter(index);
1611 
1612  // if not even the first range includes the index, we are in the void
1613  // (or in some negative index space, if index signedness allowed);
1614  if (iNextRange != ranges.begin()) {
1615  // otherwise, let's take the previous range;
1616  // if it includes the index, we set the existing value;
1617  // or it precedes it, and our index is in the void, add the value as a
1618  // range
1619  datarange_t& range(*--iNextRange);
1620  if (index < range.end_index()) return range[index] = value;
1621  }
1622  // so we are in the void; add the value as a new range
1623  return const_cast<datarange_t&>(add_range(index, { value }))[index];
1624 } // lar::sparse_vector<T>::set_at()
const datarange_t & range(size_t i) const
Returns the i-th non-void range (zero-based)
const datarange_t & add_range(size_type offset, ITER first, ITER last)
Adds a sequence of elements as a range with specified offset.
size_type end_index() const
Returns the first absolute index not included in the range.
range_list_t ranges
list of ranges
range_iterator find_next_range_iter(size_type index)
Returns an iterator to the range after index, or end() if none.
std::string value(boost::any const &)
range_list_t::iterator range_iterator
type of iterator over ranges
template<typename T >
bool lar::sparse_vector< T >::should_merge ( const typename datarange_t::base_t a,
const typename datarange_t::base_t b 
)
inlinestatic

Returns if merging the two specified ranges would save memory.

Definition at line 2037 of file sparse_vector.h.

References lar::range_t< SIZE >::begin_index(), and lar::range_t< SIZE >::size().

2041 {
2042  size_type gap_size = (a < b)?
2043  b.begin_index() - a.begin_index() - a.size():
2044  a.begin_index() - b.begin_index() - b.size();
2045  return expected_vector_size(a.size() + b.size() + gap_size)
2046  <= expected_vector_size(a.size()) + expected_vector_size(b.size());
2047 } // lar::sparse_vector<T>::should_merge()
static size_t expected_vector_size(size_t size)
Returns the expected size taken by a vector of specified size.
vector_t::size_type size_type
size type
template<typename T>
size_type lar::sparse_vector< T >::size ( ) const
inline

Returns the size of the vector.

Definition at line 551 of file sparse_vector.h.

Referenced by operator<<().

551 { return nominal_size; }
size_type nominal_size
current size
template<typename T >
void lar::sparse_vector< T >::unset_at ( size_type  index)

Casts the element with the specified index into the void.

Definition at line 1628 of file sparse_vector.h.

References lar::sparse_vector< T >::datarange_t::begin(), lar::range_t< SIZE >::begin_index(), lar::sparse_vector< T >::datarange_t::end(), lar::range_t< SIZE >::end_index(), lar::sparse_vector< T >::datarange_t::move_head(), lar::sparse_vector< T >::datarange_t::move_tail(), lar::range_t< SIZE >::relative_index(), and lar::range_t< SIZE >::size().

1628  {
1629  // first range not including the index
1630  range_iterator iNextRange = find_next_range_iter(index);
1631 
1632  // if not even the first range includes the index, we are in the void
1633  // (or in some negative index space, if index signedness allowed);
1634  if (iNextRange == ranges.begin()) return;
1635 
1636  // otherwise, let's take the previous range;
1637  // or it precedes the index, and our index is in the void
1638  datarange_t& range(*--iNextRange);
1639  if (index >= range.end_index()) return; // void already
1640 
1641  // it includes the index:
1642  // - if it's a one-element range, remove the range
1643  if (range.size() == 1) ranges.erase(iNextRange);
1644  // - if it's on a border, resize the range
1645  else if (index == range.begin_index())
1646  range.move_head(index + 1);
1647  else if (index == range.end_index() - 1)
1648  range.move_tail(index);
1649  // - if it's inside, break the range in two
1650  else if (index < range.end_index()) {
1651  // we are going to put a hole in a range;
1652  // this effectively creates two ranges;
1653  // first create the rightmost range, and add it to the list
1654  ranges.emplace(++iNextRange, index + 1,
1655  range.begin() + range.relative_index(index + 1),
1656  range.end()
1657  );
1658  // then cut the existing one
1659  range.move_tail(index);
1660  }
1661 } // lar::sparse_vector<T>::unset_at()
const datarange_t & range(size_t i) const
Returns the i-th non-void range (zero-based)
size_type begin_index() const
Returns the first absolute index included in the range.
void move_tail(size_type to_index, value_type def_value=value_zero)
Moves the end of this range.
size_type end_index() const
Returns the first absolute index not included in the range.
range_list_t ranges
list of ranges
range_iterator find_next_range_iter(size_type index)
Returns an iterator to the range after index, or end() if none.
void move_head(size_type to_index, value_type def_value=value_zero)
Moves the begin of this range.
size_type size() const
Returns the size of the range.
range_list_t::iterator range_iterator
type of iterator over ranges
iterator begin()
begin and end iterators
iterator end()
begin and end iterators
size_type relative_index(size_type index) const
Returns the position within the range of the absolute index specified.
template<typename T>
void lar::sparse_vector< T >::void_range ( range_iterator  iRange)
inline

Turns the specified range into void.

Parameters
iRangeiterator or index of range to be deleted
See also
make_void(), unset_at()

Definition at line 894 of file sparse_vector.h.

894 { ranges.erase(iRange); }
range_list_t ranges
list of ranges
template<typename T>
void lar::sparse_vector< T >::void_range ( size_t  iRange)
inline

Turns the specified range into void.

Parameters
iRangeiterator or index of range to be deleted
See also
make_void(), unset_at()

Definition at line 895 of file sparse_vector.h.

895 { ranges.erase(ranges.begin() + iRange); }
range_list_t ranges
list of ranges

Member Data Documentation

template<typename T>
size_type lar::sparse_vector< T >::nominal_size
protected

current size

Definition at line 967 of file sparse_vector.h.

template<typename T>
range_list_t lar::sparse_vector< T >::ranges
protected

list of ranges

Definition at line 968 of file sparse_vector.h.

template<typename T>
constexpr lar::sparse_vector< T >::value_type lar::sparse_vector< T >::value_zero {0}
static

a representation of 0

Definition at line 928 of file sparse_vector.h.


The documentation for this class was generated from the following file: