LArSoft  v06_85_00
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)
 
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 >
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 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 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 458 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 471 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 468 of file sparse_vector.h.

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

Definition at line 470 of file sparse_vector.h.

type of constant iterator over ranges

Definition at line 488 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 486 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 481 of file sparse_vector.h.

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

size type

Definition at line 467 of file sparse_vector.h.

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

Definition at line 459 of file sparse_vector.h.

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

type of the stored values

Definition at line 464 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 465 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 495 of file sparse_vector.h.

495 : 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 499 of file sparse_vector.h.

499  : nominal_size(0), ranges()
500  { 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 507 of file sparse_vector.h.

507  :
508  nominal_size(0), ranges()
509  { 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 515 of file sparse_vector.h.

516  : nominal_size(from.nominal_size)
517  , ranges(std::move(from.ranges))
518  { 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 537 of file sparse_vector.h.

537  :
538  nominal_size(0), ranges()
539  { 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 873 of file sparse_vector.h.

873 { 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 768 of file sparse_vector.h.

769  { 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 1631 of file sparse_vector.h.

1632 {
1633  // insert the new range before the existing range which starts after offset
1634  range_iterator iInsert = std::upper_bound(
1635  ranges.begin(), ranges.end(), offset,
1637  );
1638 
1639  // is there a range before this, which includes the offset?
1640  if ((iInsert != ranges.begin()) && (iInsert-1)->borders(offset)) {
1641  // then we should extend it
1642  (--iInsert)->extend(offset, new_data.begin(), new_data.end());
1643  }
1644  else {
1645  // no range before the insertion one includes the offset of the new range;
1646  // ... we need to add it as a new range;
1647  // it is not really clear to me [GP] why I need a std::move here, since
1648  // new_data is a rvalue already; in doubt, I have painted all this kind
1649  // of constructs with move()s, just in case
1650  iInsert = insert_range(iInsert, { offset, std::move(new_data) });
1651  }
1652  return merge_ranges(iInsert);
1653 } // 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 1607 of file sparse_vector.h.

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

1608 {
1609  // insert the new range before the existing range which starts after offset
1610  range_iterator iInsert = std::upper_bound(
1611  ranges.begin(), ranges.end(), offset,
1613  );
1614 
1615  // is there a range before this, which includes the offset?
1616  if ((iInsert != ranges.begin()) && (iInsert-1)->borders(offset)) {
1617  // then we should extend it
1618  (--iInsert)->extend(offset, first, last);
1619  }
1620  else {
1621  // no range before the insertion one includes the offset of the new range;
1622  // ... we need to add it as a new range
1623  iInsert = insert_range(iInsert, { offset, first, last });
1624  }
1625  return merge_ranges(iInsert);
1626 } // lar::sparse_vector<T>::add_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.
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 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 799 of file sparse_vector.h.

800  { 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 812 of file sparse_vector.h.

813  { 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 825 of file sparse_vector.h.

826  { 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 659 of file sparse_vector.h.

659 { 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 669 of file sparse_vector.h.

669 { 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 677 of file sparse_vector.h.

677 { 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 602 of file sparse_vector.h.

603  { 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 1411 of file sparse_vector.h.

References evd::details::begin().

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

1412  { 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 1420 of file sparse_vector.h.

References evd::details::begin().

1421  { 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 700 of file sparse_vector.h.

700 { 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 558 of file sparse_vector.h.

558 { 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 573 of file sparse_vector.h.

573 { 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 574 of file sparse_vector.h.

574 { 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 548 of file sparse_vector.h.

548 { ranges.clear(); nominal_size = 0; }
range_list_t ranges
list of ranges
size_type nominal_size
current size
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 1478 of file sparse_vector.h.

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

1480 {
1481  return std::accumulate(begin_range(), end_range(), size_type(0),
1482  [](size_type s, const datarange_t& rng) { return s + rng.size(); }
1483  );
1484 } // 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 1774 of file sparse_vector.h.

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

1775 {
1776  if (index <= iRange->begin_index()) return iRange;
1777  if (index >= iRange->end_index()) return ranges.erase(iRange);
1778  iRange->move_head(index);
1779  return iRange;
1780 } // 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 555 of file sparse_vector.h.

555 { 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 1415 of file sparse_vector.h.

References evd::details::end().

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

1416  { 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 1425 of file sparse_vector.h.

References evd::details::end().

1426  { 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 703 of file sparse_vector.h.

703 { 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 1794 of file sparse_vector.h.

References max.

1794  {
1795  // apparently, a chunk of heap memory takes at least 32 bytes;
1796  // that means that a vector of 1 or 5 32-bit integers takes the same
1797  // space; the overhead appears to be 8 bytes, which can be allocated
1798  return sizeof(vector_t)
1799  + std::max(size_t(32), (alignof(datarange_t)*size + 8));
1800 } // 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_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 919 of file sparse_vector.h.

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

920  { 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 921 of file sparse_vector.h.

922  { 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 >
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 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 1730 of file sparse_vector.h.

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

1731 {
1732  // this range has the offset (first index) above the index argument:
1733  return std::upper_bound(
1734  rbegin, ranges.end(), index,
1736  );
1737 } // 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 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 1742 of file sparse_vector.h.

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

1743 {
1744  // this range has the offset (first index) above the index argument:
1745  return std::upper_bound(
1746  rbegin, ranges.end(), index,
1748  );
1749 } // 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 1571 of file sparse_vector.h.

1572 {
1573  if (ranges.empty()) throw std::out_of_range("empty sparse vector");
1574  // range on the index:
1575  range_const_iterator iNextRange = find_range_iterator(index);
1576  if (iNextRange == ranges.end())
1577  throw std::out_of_range("index in no range of the sparse vector");
1578  return *iNextRange;
1579 } // 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 1583 of file sparse_vector.h.

1584 {
1585  return const_cast<datarange_t&>
1586  (const_cast<const this_t*>(this)->find_range(index));
1587 } // 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 1548 of file sparse_vector.h.

1549 {
1550  if (ranges.empty()) throw std::out_of_range("empty sparse vector");
1551  // range after the index:
1552  range_const_iterator iNextRange = find_next_range_iter(index);
1553  return ((iNextRange == ranges.begin())
1554  || (index >= (--iNextRange)->end_index()))?
1555  ranges.end(): iNextRange;
1556 } // 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 1561 of file sparse_vector.h.

1562 {
1563  return ranges.begin() + (
1564  (const_cast<const this_t*>(this)->find_range_iterator(index))
1565  - ranges.begin());
1566 } // 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 1784 of file sparse_vector.h.

References max.

1784  {
1785  if (!ranges.empty())
1786  nominal_size = std::max(nominal_size, ranges.back().end_index());
1787  return nominal_size;
1788 } // 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 691 of file sparse_vector.h.

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

691 { 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 943 of file sparse_vector.h.

944  { 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 945 of file sparse_vector.h.

946  { 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 883 of file sparse_vector.h.

884  { 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 887 of file sparse_vector.h.

888  { 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 1706 of file sparse_vector.h.

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

1706  {
1707  // a sparse vector with no non-null elements can't be detected invalid
1708  if (ranges.empty()) return true;
1709 
1710  range_const_iterator iNext = ranges.begin(), rend = ranges.end();
1711  while (iNext != rend) {
1712  range_const_iterator iRange = iNext++;
1713  if (iRange->empty()) return false;
1714  if (iNext != rend) {
1715  if (!(*iRange < *iNext)) return false;
1716  if (!iRange->separate(*iNext)) return false;
1717  }
1718  } // while
1719  if (nominal_size < ranges.back().end_index()) return false;
1720  return true;
1721 } // 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 1467 of file sparse_vector.h.

1467  {
1468  if (ranges.empty() || (index >= size()))
1469  throw std::out_of_range("empty sparse vector");
1470  // range after the index:
1471  range_const_iterator iNextRange = find_next_range_iter(index);
1472  return ((iNextRange == ranges.begin())
1473  || ((--iNextRange)->end_index() <= index));
1474 } // 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 876 of file sparse_vector.h.

876 { 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 879 of file sparse_vector.h.

880  { 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 1657 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.

1657  {
1658  // iterators have in "currentRange" either the range they point into,
1659  // or the range next to the void they point to
1660 
1661  if ((first.cont != this) || (last.cont != this)) {
1662  throw std::runtime_error
1663  ("lar::sparse_vector::make_void(): iterators from alien container");
1664  }
1665  // if first is after next, no range is identified
1666  if (first >= last) return;
1667 
1669  first_range
1670  = ranges.begin() + (first.get_current_range() - ranges.begin()),
1671  last_range = ranges.begin() + (last.get_current_range() - ranges.begin());
1672 
1673  //--- "first": void up to this iterator ---
1674  // if first in the last void region, there is nothing to erase
1675  if (first_range == ranges.end()) return;
1676 
1677  // if first is in the middle of a valid range instead, we have to resize it
1678  if (first.index > first_range->begin_index()) {
1679  if (first_range == last_range) {
1680  // we are going to erase a subset of a range;
1681  // this effectively creates two ranges;
1682  // first create the rightmost (last) range, and add it to the list
1683  last_range = ranges.emplace(++last_range, last.index,
1684  first_range->begin() + first_range->relative_index(last.index),
1685  first_range->end()
1686  );
1687  // then cut the existing one
1688  first_range->move_tail(first.index);
1689  return;
1690  }
1691  first_range->move_tail(first.index);
1692  ++first_range; // from next range on, start voiding
1693  }
1694 
1695  //--- "last"
1696  // if the index is inside a range, remove up to it
1697  if ((last_range != ranges.end()) && (last.index > last_range->begin_index()))
1698  eat_range_head(last_range, last.index);
1699 
1700  // finally, remove entirely the ranges in between
1701  ranges.erase(first_range, last_range);
1702 } // 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 1591 of file sparse_vector.h.

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

1591  {
1592  if (ranges.empty() || (index >= size()))
1593  throw std::out_of_range("empty sparse vector");
1594  // range after the index:
1595  range_iterator iNextRange = find_next_range_iter(index);
1596  if ((iNextRange == ranges.begin())
1597  || ((--iNextRange)->end_index() <= index))
1598  {
1599  return;
1600  }
1601  ranges.erase(iNextRange);
1602 } // 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 1754 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_next_range_iter().

1755 {
1756  range_iterator iNext = iRange + 1;
1757  while (iNext != ranges.end()) {
1758  if (!iRange->borders(iNext->begin_index())) break;
1759  // iRange content dominates, but if iNext has data beyond it,
1760  // then we copy it
1761  if (iNext->end_index() > iRange->end_index()) {
1762  iRange->extend
1763  (iRange->end_index(), iNext->get_iterator(iRange->end_index()), iNext->end());
1764  }
1765  iNext = ranges.erase(iNext);
1766  } // while
1767  fix_size();
1768  return *iRange;
1769 } // 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 1804 of file sparse_vector.h.

1804  {
1805  // we assume here that there is no additional overhead by alignment;
1806  // the gap adds the space of another datarange_t, including the vector,
1807  // its data and overhead from heap (apparently, 8 bytes);
1808  //
1809  return (sizeof(datarange_t) + 8) / sizeof(value_type) + 1; // round up
1810 } // 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 938 of file sparse_vector.h.

939  { 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 694 of file sparse_vector.h.

694 { 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 524 of file sparse_vector.h.

525  {
526  ranges = std::move(from.ranges);
527  nominal_size = from.nominal_size;
528  from.nominal_size = 0;
529  return *this;
530  } // 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 1430 of file sparse_vector.h.

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

1431 {
1432  // first range not including the index
1433  range_const_iterator iNextRange = find_next_range_iter(index);
1434 
1435  // if not even the first range includes the index, we are in the void
1436  // (or in some negative index space, if index signedness allowed);
1437  if (iNextRange == ranges.begin()) return value_zero;
1438 
1439  // otherwise, let's take the previous range;
1440  // if it includes the index, we return its value;
1441  // or it precedes it, and our index is in the void: return zero
1442  const datarange_t& range(*--iNextRange);
1443  return (index < range.end_index())? range[index]: value_zero;
1444 } // 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 1449 of file sparse_vector.h.

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

1450 {
1451  // first range not including the index
1452  range_iterator iNextRange = find_next_range_iter(index);
1453 
1454  // if not even the first range includes the index, we are in the void
1455  // (or in some negative index space, if index signedness allowed);
1456  if (iNextRange == ranges.begin()) return reference();
1457 
1458  // otherwise, let's take the previous range;
1459  // if it includes the index, we return its value;
1460  // or it precedes it, and our index is in the void: return zero
1461  datarange_t& range(*--iNextRange);
1462  return (index < range.end_index())? reference(range[index]): reference();
1463 } // 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 863 of file sparse_vector.h.

863 { 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 864 of file sparse_vector.h.

864 { 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 632 of file sparse_vector.h.

632 { 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 641 of file sparse_vector.h.

642  {
643  if (is_zero(value, thr)) resize(size() + 1);
644  else push_back(value);
645  } // 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 697 of file sparse_vector.h.

697 { 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 1370 of file sparse_vector.h.

1370  {
1371  if (new_size >= size()) {
1372  nominal_size = new_size;
1373  return;
1374  }
1375 
1376  // truncating...
1377  range_iterator iLastRange = find_next_range_iter(new_size);
1378  ranges.erase(iLastRange, ranges.end());
1379  if (!ranges.empty()) {
1380  range_iterator iLastRange = ranges.end() - 1;
1381  if (new_size == iLastRange->begin_index())
1382  ranges.erase(iLastRange);
1383  else if (new_size < iLastRange->end_index())
1384  iLastRange->resize(new_size - iLastRange->begin_index());
1385  } // if we have ranges
1386 
1387  // formally resize
1388  nominal_size = new_size;
1389 } // 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 1393 of file sparse_vector.h.

1393  {
1394  if (new_size == size()) return;
1395  if (new_size > size()) {
1396 
1397  if (back_is_void()) // add a new range
1398  append(vector_t(new_size - size(), def_value));
1399  else // extend the last range
1400  ranges.back().resize(new_size - ranges.back().begin_index(), def_value);
1401 
1402  nominal_size = new_size;
1403  return;
1404  }
1405  // truncating is the same whether there is a default value or not
1406  resize(new_size);
1407 } // 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 1489 of file sparse_vector.h.

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

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

1490 {
1491  // first range not including the index
1492  range_iterator iNextRange = find_next_range_iter(index);
1493 
1494  // if not even the first range includes the index, we are in the void
1495  // (or in some negative index space, if index signedness allowed);
1496  if (iNextRange != ranges.begin()) {
1497  // otherwise, let's take the previous range;
1498  // if it includes the index, we set the existing value;
1499  // or it precedes it, and our index is in the void, add the value as a
1500  // range
1501  datarange_t& range(*--iNextRange);
1502  if (index < range.end_index()) return range[index] = value;
1503  }
1504  // so we are in the void; add the value as a new range
1505  return const_cast<datarange_t&>(add_range(index, { value }))[index];
1506 } // 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 1814 of file sparse_vector.h.

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

1818 {
1819  size_type gap_size = (a < b)?
1820  b.begin_index() - a.begin_index() - a.size():
1821  a.begin_index() - b.begin_index() - b.size();
1822  return expected_vector_size(a.size() + b.size() + gap_size)
1823  <= expected_vector_size(a.size()) + expected_vector_size(b.size());
1824 } // 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 552 of file sparse_vector.h.

Referenced by operator<<().

552 { 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 1510 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().

1510  {
1511  // first range not including the index
1512  range_iterator iNextRange = find_next_range_iter(index);
1513 
1514  // if not even the first range includes the index, we are in the void
1515  // (or in some negative index space, if index signedness allowed);
1516  if (iNextRange == ranges.begin()) return;
1517 
1518  // otherwise, let's take the previous range;
1519  // or it precedes the index, and our index is in the void
1520  datarange_t& range(*--iNextRange);
1521  if (index >= range.end_index()) return; // void already
1522 
1523  // it includes the index:
1524  // - if it's a one-element range, remove the range
1525  if (range.size() == 1) ranges.erase(iNextRange);
1526  // - if it's on a border, resize the range
1527  else if (index == range.begin_index())
1528  range.move_head(index + 1);
1529  else if (index == range.end_index() - 1)
1530  range.move_tail(index);
1531  // - if it's inside, break the range in two
1532  else if (index < range.end_index()) {
1533  // we are going to put a hole in a range;
1534  // this effectively creates two ranges;
1535  // first create the rightmost range, and add it to the list
1536  ranges.emplace(++iNextRange, index + 1,
1537  range.begin() + range.relative_index(index + 1),
1538  range.end()
1539  );
1540  // then cut the existing one
1541  range.move_tail(index);
1542  }
1543 } // 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 836 of file sparse_vector.h.

836 { 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 837 of file sparse_vector.h.

837 { 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 909 of file sparse_vector.h.

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

list of ranges

Definition at line 910 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 870 of file sparse_vector.h.


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