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

A sparse vector. More...

#include "sparse_vector.h"

Classes

class  const_datarange_t
 A constant reference to a data range. More...
 
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...
 
auto range_const_data (std::size_t i) const
 Like range_data() but with explicitly read-only access to data. 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...
 
std::size_t find_range_number (size_type index) const
 Returns the number (0-based) of range containing index. More...
 
datarange_t 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 contiguous region of the sparse vector which contains all non-void values.

A sparse vector is effectively a sorted collection of ranges. This interface allows:

  • iteration through all ranges (read only)
  • random access to a range by index (read only)
  • access to the data of a selected range (read/write)
  • look-up of the range containing a specified index (read/write; use write with care!)
  • addition (and more generically, combination with existing data) of a new range
  • extension of the sparse vector by appending a range at the end of it
  • remove the data of a range, making it void
const range_list_tget_ranges () const
 Returns the internal list of non-void ranges. More...
 
auto iterate_ranges () -> decltype(auto)
 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...
 
auto range_data (std::size_t i)
 Provides direct access to data of i-th non-void range (zero-based) More...
 
auto range_data (std::size_t const i) const
 Returns the internal list of non-void ranges. 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 an iterator to the range containing the specified index. 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...
 
datarange_t void_range (range_iterator const iRange)
 Turns the specified range into void. More...
 
datarange_t void_range (std::size_t const 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...
 
const datarange_tadd_range_before (size_type offset, vector_t &&new_data, range_iterator nextRange)
 Implementation detail of add_range(), with where to add the range. 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 contiguous 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. More...
 
range_const_iterator find_next_range_iter (size_type index) const
 Returns an iterator to the range after index. 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_range_iter_at_or_after (size_type index)
 Returns an iterator to the range at or after index. More...
 
range_const_iterator find_range_iter_at_or_after (size_type index) const
 Returns an iterator to the range at or after index. 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 that contains the first non-void element 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 that contains the first non-void element 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 305 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 494 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 491 of file sparse_vector.h.

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

Definition at line 493 of file sparse_vector.h.

type of constant iterator over ranges

Definition at line 512 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 510 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 505 of file sparse_vector.h.

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

size type

Definition at line 490 of file sparse_vector.h.

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

Definition at line 482 of file sparse_vector.h.

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

type of the stored values

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

518 : 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 521 of file sparse_vector.h.

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

528  : nominal_size(0), ranges()
529  {
530  add_range(offset, from.begin(), from.end());
531  }
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 537 of file sparse_vector.h.

538  : nominal_size(from.nominal_size), ranges(std::move(from.ranges))
539  {
540  from.nominal_size = 0;
541  }
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 560 of file sparse_vector.h.

560  : nominal_size(0), ranges()
561  {
562  add_range(offset, std::move(from));
563  }
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 1037 of file sparse_vector.h.

1037 { 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 butcher::EventButcher::produce(), and nnet::WaveformRoiFinder::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 862 of file sparse_vector.h.

863  {
864  return add_range(offset, new_data.begin(), new_data.end());
865  }
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 1999 of file sparse_vector.h.

2002 {
2003  // insert the new range before the existing range which starts after offset
2004  return add_range_before(
2005  offset,
2006  std::move(new_data),
2007  std::upper_bound(ranges.begin(),
2008  ranges.end(),
2009  offset,
2011 
2012 } // lar::sparse_vector<T>::add_range(vector)
const datarange_t & add_range_before(size_type offset, vector_t &&new_data, range_iterator nextRange)
Implementation detail of add_range(), with where to add the range.
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>
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 1980 of file sparse_vector.h.

1981 {
1982  // insert the new range before the existing range which starts after offset
1983  range_iterator iInsert = find_next_range_iter(offset);
1984 
1985  // is there a range before this, which includes the offset?
1986  if ((iInsert != ranges.begin()) && std::prev(iInsert)->borders(offset)) {
1987  // then we should extend it
1988  (--iInsert)->extend(offset, first, last);
1989  }
1990  else {
1991  // no range before the insertion one includes the offset of the new range;
1992  // ... we need to add it as a new range
1993  iInsert = insert_range(iInsert, {offset, first, last});
1994  }
1995  return merge_ranges(iInsert);
1996 } // lar::sparse_vector<T>::add_range<ITER>()
range_iterator find_next_range_iter(size_type index)
Returns an iterator to the range after index.
datarange_t & merge_ranges(range_iterator iRange)
Merges all the following contiguous 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 >
const lar::sparse_vector< T >::datarange_t & lar::sparse_vector< T >::add_range_before ( size_type  offset,
vector_t &&  new_data,
range_iterator  nextRange 
)
protected

Implementation detail of add_range(), with where to add the range.

Definition at line 2242 of file sparse_vector.h.

2246 {
2247  // insert the new range before the existing range which starts after offset
2248  range_iterator iInsert = nextRange;
2249 
2250  // is there a range before this, which includes the offset?
2251  if ((iInsert != ranges.begin()) && (iInsert - 1)->borders(offset)) {
2252  // then we should extend it
2253  (--iInsert)->extend(offset, new_data.begin(), new_data.end());
2254  }
2255  else {
2256  // no range before the insertion one includes the offset of the new range;
2257  // ... we need to add it as a new range;
2258  // it is not really clear to me [GP] why I need a std::move here, since
2259  // new_data is a rvalue already; in doubt, I have painted all this kind
2260  // of constructs with move()s, just in case
2261  iInsert = insert_range(iInsert, {offset, std::move(new_data)});
2262  }
2263  return merge_ranges(iInsert);
2264 } // lar::sparse_vector<T>::add_range_before(vector, iterator)
datarange_t & merge_ranges(range_iterator iRange)
Merges all the following contiguous 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 954 of file sparse_vector.h.

955  {
956  return add_range(size(), first, last);
957  }
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 969 of file sparse_vector.h.

970  {
971  return add_range(size(), range_data);
972  }
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.
auto range_data(std::size_t i)
Provides direct access to data of i-th non-void range (zero-based)
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 984 of file sparse_vector.h.

985  {
986  return add_range(size(), std::move(range_data));
987  }
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.
auto range_data(std::size_t i)
Provides direct access to data of i-th non-void range (zero-based)
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 680 of file sparse_vector.h.

681  {
682  clear();
683  append(first, last);
684  }
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 694 of file sparse_vector.h.

695  {
696  clear();
697  append(new_data);
698  }
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 706 of file sparse_vector.h.

707  {
708  clear();
709  append(std::move(new_data));
710  }
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 625 of file sparse_vector.h.

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

Standard iterators interface.

Definition at line 1793 of file sparse_vector.h.

References util::begin().

Referenced by recob::OpWaveform::Signal(), and recob::Wire::Signal().

1794 {
1795  return iterator(*this, typename iterator::special::begin());
1796 }
intermediate_table::iterator iterator
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:69
template<typename T >
lar::sparse_vector< T >::const_iterator lar::sparse_vector< T >::begin ( ) const
inline

Standard iterators interface.

Definition at line 1805 of file sparse_vector.h.

References util::begin().

1806 {
1807  return const_iterator(*this, typename const_iterator::special::begin());
1808 }
intermediate_table::const_iterator const_iterator
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:69
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 779 of file sparse_vector.h.

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

Returns the capacity of the vector (compatibility only)

Definition at line 583 of file sparse_vector.h.

583 { 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 598 of file sparse_vector.h.

598 { 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 599 of file sparse_vector.h.

599 { 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 570 of file sparse_vector.h.

571  {
572  ranges.clear();
573  nominal_size = 0;
574  }
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 933 of file sparse_vector.h.

937  {
938  return combine_range(offset, other.begin(), other.end(), std::forward<OP>(op), void_value);
939  }
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 2016 of file sparse_vector.h.

References util::end().

2022 {
2023  /*
2024  * This is a complicate enough task, that we go brute force:
2025  * 1) combine all the input elements within the datarange where offset falls
2026  * in
2027  * 2) create a new datarange combining void with the remaining input elements
2028  * 3) if the void area is over before the input elements are, repeat steps
2029  * (1) and (2) with the updated offset
2030  * 4) at this point we'll have a train of contiguous ranges, result of
2031  * combination of the input elements alternating with existing elements
2032  * and with void cells: apply the regular merge algorithm
2033  *
2034  */
2035 
2036  auto src = first;
2037  auto const insertionPoint = offset; // saved for later
2038  auto destRange = find_range_iter_at_or_after(offset);
2039  while (src != last) {
2040 
2041  //
2042  // (1) combine all the input elements within the datarange including offset
2043  // (NOT extending the range)
2044  //
2045  if ((destRange != end_range()) && destRange->includes(offset)) {
2046  // combine input data until this range is over (or input data is over)
2047  auto dest = destRange->get_iterator(offset);
2048 
2049  auto const end = destRange->end();
2050  while (src != last) {
2051  *dest = op(*dest, *src);
2052  ++src;
2053  ++offset;
2054  if (++dest == end) break;
2055  } // while
2056  if (src == last) break;
2057  offset = destRange->end_index();
2058  ++destRange;
2059  } // if
2060 
2061  //
2062  // (2) create a new datarange combining void with input elements
2063  //
2064  // at this point, offset is in the void, we do have more input data,
2065  // and `destRange` does _not_ contain the current insertion offset;
2066  // we fill as much void as we can with data, creating a new range.
2067  // When to stop? at the beginning of the next range, or when data is over
2068  //
2069  size_type const newRangeSize =
2070  (destRange == end_range()) ? std::distance(src, last) : (destRange->begin_index() - offset);
2071 
2072  // prepare the data (we'll plug it in directly)
2073  vector_t combinedData;
2074  combinedData.reserve(newRangeSize);
2075  size_type i = 0;
2076  while (i++ < newRangeSize) {
2077  combinedData.push_back(op(void_value, *src));
2078  if (++src == last) break; // no more data
2079  }
2080  // move the data as a new range inserted before the next range we just found
2081  // return value is the iterator to the inserted range
2082  destRange = insert_range(destRange, {offset, std::move(combinedData)});
2083 
2084  //
2085  // (3) if there is more input, repeat steps (1) and (2) with updated offset
2086  //
2087  offset = destRange->end_index();
2088  ++destRange;
2089  } // while
2090 
2091  //
2092  // (4) apply the regular merge algorithm;
2093  // since we did not extend existing ranges, it may happen that we have
2094  // created a new range at `insertionPoint` contiguous to the previous one;
2095  // so we take care of checking that too
2096  //
2097  return merge_ranges(find_extending_range_iter(insertionPoint == 0 ? 0 : insertionPoint - 1));
2098 
2099 } // 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.
iterator end()
Standard iterators interface.
vector_t::size_type size_type
size type
range_iterator find_range_iter_at_or_after(size_type index)
Returns an iterator to the range at or after index.
datarange_t & merge_ranges(range_iterator iRange)
Merges all the following contiguous 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 1860 of file sparse_vector.h.

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

1861 {
1862  return std::accumulate(begin_range(),
1863  end_range(),
1864  size_type(0),
1865  [](size_type s, const datarange_t& rng) { return s + rng.size(); });
1866 } // count()
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 2285 of file sparse_vector.h.

2288 {
2289  if (index <= iRange->begin_index()) return iRange;
2290  if (index >= iRange->end_index()) return ranges.erase(iRange);
2291  iRange->move_head(index);
2292  return iRange;
2293 } // lar::sparse_vector<T>::eat_range_head()
template<typename T>
bool lar::sparse_vector< T >::empty ( ) const
inline

Returns whether the vector is empty.

Definition at line 580 of file sparse_vector.h.

580 { 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 1799 of file sparse_vector.h.

References util::end().

Referenced by recob::OpWaveform::Signal(), and recob::Wire::Signal().

1800 {
1801  return iterator(*this, typename iterator::special::end());
1802 }
intermediate_table::iterator iterator
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
Definition: StdUtils.h:77
template<typename T >
lar::sparse_vector< T >::const_iterator lar::sparse_vector< T >::end ( ) const
inline

Standard iterators interface.

Definition at line 1811 of file sparse_vector.h.

References util::end().

1812 {
1813  return const_iterator(*this, typename const_iterator::special::end());
1814 }
intermediate_table::const_iterator const_iterator
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
Definition: StdUtils.h:77
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 782 of file sparse_vector.h.

782 { return ranges.end(); }
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 2305 of file sparse_vector.h.

2306 {
2307  // apparently, a chunk of heap memory takes at least 32 bytes;
2308  // that means that a vector of 1 or 5 32-bit integers takes the same
2309  // space; the overhead appears to be 8 bytes, which can be allocated
2310  return sizeof(vector_t) + std::max(size_t(32), (alignof(datarange_t) * size + 8));
2311 } // 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.
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 the 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 1138 of file sparse_vector.h.

1139  {
1140  return find_extending_range_iter(index, ranges.begin());
1141  }
range_iterator find_extending_range_iter(size_type index)
Returns an iterator to the range no earlier than index, or end() if none.
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 the 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 1142 of file sparse_vector.h.

1143  {
1144  return find_extending_range_iter(index, ranges.cbegin());
1145  }
range_iterator find_extending_range_iter(size_type index)
Returns an iterator to the range no earlier than index, or end() if none.
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 that contains the first non-void element 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

Note that the returned range can contain index as well.

Definition at line 2219 of file sparse_vector.h.

2222 {
2223  // this range has the offset (first index) above the index argument:
2224  auto it = find_next_range_iter(index, rbegin);
2225  // if index were not void, would it belong to the previous range?
2226  // if so, the previous range is the one we want
2227  return ((it != rbegin) && std::prev(it)->borders(index)) ? std::prev(it) : it;
2228 } // 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.
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 that contains the first non-void element 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

Note that the returned range can contain index as well.

Definition at line 2232 of file sparse_vector.h.

2233 {
2234  // this range has the offset (first index) above the index argument:
2235  auto it = find_next_range_iter(index, rbegin);
2236  // if index were not void, would it belong to the previous range?
2237  // if so, the previus range is the one we want
2238  return ((it != rbegin) && std::prev(it)->borders(index)) ? std::prev(it) : it;
2239 } // 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.
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.

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

Definition at line 1080 of file sparse_vector.h.

1081  {
1082  return find_next_range_iter(index, ranges.begin());
1083  }
range_iterator find_next_range_iter(size_type index)
Returns an iterator to the range after index.
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.

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

Definition at line 1084 of file sparse_vector.h.

1085  {
1086  return find_next_range_iter(index, ranges.cbegin());
1087  }
range_iterator find_next_range_iter(size_type index)
Returns an iterator to the range after index.
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 2177 of file sparse_vector.h.

2180 {
2181  // this range has the offset (first index) above the index argument:
2182  return std::upper_bound(
2183  rbegin, ranges.end(), index, typename datarange_t::less_int_range(datarange_t::less));
2184 } // lar::sparse_vector<T>::find_next_range_iter()
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 2187 of file sparse_vector.h.

2190 {
2191  // this range has the offset (first index) above the index argument:
2192  return std::upper_bound(
2193  rbegin, ranges.end(), index, typename datarange_t::less_int_range(datarange_t::less));
2194 } // lar::sparse_vector<T>::find_next_range_iter() const
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 sought
Returns
the containing range
Exceptions
std::out_of_rangeif index is in no range (how appropriate!)
See also
is_void()

Definition at line 1950 of file sparse_vector.h.

1952 {
1953  if (ranges.empty()) throw std::out_of_range("empty sparse vector");
1954  // range on the index:
1955  range_const_iterator iNextRange = find_range_iterator(index);
1956  if (iNextRange == ranges.end()) throw std::out_of_range("index in no range of the sparse vector");
1957  return *iNextRange;
1958 } // lar::sparse_vector<T>::find_range() const
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 sought
Returns
the containing range
Exceptions
std::out_of_rangeif index is in no range (how appropriate!)
See also
is_void()

Definition at line 1961 of file sparse_vector.h.

1963 {
1964  return const_cast<datarange_t&>(const_cast<const this_t*>(this)->find_range(index));
1965 } // 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_iterator lar::sparse_vector< T >::find_range_iter_at_or_after ( size_type  index)
protected

Returns an iterator to the range at or after index.

Parameters
indexthe absolute index
Returns
iterator to the next range including index or after it, or ranges.end() if none
See also
find_next_range_iter()

If index is in a range, an iterator to that range is returned. If index is in the void, an iterator to the next range after index is returned. If there is no such range after index, ranges.end() is returned.

Definition at line 2208 of file sparse_vector.h.

2210 {
2211  // this range has the offset (first index) above the index argument:
2212  auto after = find_next_range_iter(index);
2213  // if the previous range exists and contains index, that's the one we want
2214  return ((after != ranges.begin()) && (index < std::prev(after)->end_index())) ? std::prev(after) :
2215  after;
2216 } // lar::sparse_vector<T>::find_range_iter_at_or_after()
range_iterator find_next_range_iter(size_type index)
Returns an iterator to the range after index.
template<typename T >
lar::sparse_vector< T >::range_const_iterator lar::sparse_vector< T >::find_range_iter_at_or_after ( size_type  index) const
protected

Returns an iterator to the range at or after index.

Parameters
indexthe absolute index
Returns
iterator to the next range including index or after it, or ranges.end() if none
See also
find_next_range_iter()

If index is in a range, an iterator to that range is returned. If index is in the void, an iterator to the next range after index is returned. If there is no such range after index, ranges.end() is returned.

Definition at line 2198 of file sparse_vector.h.

2199 {
2200  // this range has the offset (first index) above the index argument:
2201  auto after = find_next_range_iter(index);
2202  // if the previous range exists and contains index, that's the one we want
2203  return ((after != ranges.begin()) && (index < std::prev(after)->end_index())) ? std::prev(after) :
2204  after;
2205 } // lar::sparse_vector<T>::find_range_iter_at_or_after() const
range_iterator find_next_range_iter(size_type index)
Returns an iterator to the range after 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 sought
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 1939 of file sparse_vector.h.

1941 {
1942  if (ranges.empty()) throw std::out_of_range("empty sparse vector");
1943  // range after the index:
1944  range_const_iterator iNextRange = find_next_range_iter(index);
1945  return ((iNextRange == ranges.begin()) || (index >= (--iNextRange)->end_index())) ? ranges.end() :
1946  iNextRange;
1947 } // lar::sparse_vector<T>::find_range_iterator() const
range_iterator find_next_range_iter(size_type index)
Returns an iterator to the range after index.
range_list_t::const_iterator range_const_iterator
type of constant iterator over ranges
template<typename T>
range_iterator lar::sparse_vector< T >::find_range_iterator ( size_type  index)
inline

Returns an iterator to the range containing the specified index.

Parameters
indexabsolute index of the element to be sought
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 793 of file sparse_vector.h.

794  {
795  return ranges.begin() + find_range_number(index);
796  }
std::size_t find_range_number(size_type index) const
Returns the number (0-based) of range containing index.
template<typename T>
std::size_t lar::sparse_vector< T >::find_range_number ( size_type  index) const
inline

Returns the number (0-based) of range containing index.

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

Definition at line 806 of file sparse_vector.h.

807  {
808  return find_range_iterator(index) - begin_range();
809  }
range_const_iterator begin_range() const
Returns a constant iterator to the first data range.
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 2296 of file sparse_vector.h.

2297 {
2298  if (!ranges.empty()) nominal_size = std::max(nominal_size, ranges.back().end_index());
2299  return nominal_size;
2300 } // lar::sparse_vector<T>::fix_size()
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 739 of file sparse_vector.h.

Referenced by nnet::EvaluateROIEff::analyze(), hit::HitAnaAlg::FillWireInfo(), hit::DPRawHitFinder::produce(), and dnn::SavePiMu::saveImage().

739 { 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 1169 of file sparse_vector.h.

1170  {
1171  return data.empty() ? iInsert : ranges.insert(iInsert, data);
1172  }
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 1173 of file sparse_vector.h.

1174  {
1175  return data.empty() ? iInsert : ranges.insert(iInsert, std::move(data));
1176  }
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 1046 of file sparse_vector.h.

1046 { 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 1049 of file sparse_vector.h.

1050  {
1051  return is_zero(abs(a - b), thr);
1052  }
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 2156 of file sparse_vector.h.

2157 {
2158  // a sparse vector with no non-null elements can't be detected invalid
2159  if (ranges.empty()) return true;
2160 
2161  range_const_iterator iNext = ranges.begin(), rend = ranges.end();
2162  while (iNext != rend) {
2163  range_const_iterator iRange = iNext++;
2164  if (iRange->empty()) return false;
2165  if (iNext != rend) {
2166  if (!(*iRange < *iNext)) return false;
2167  if (!iRange->separate(*iNext)) return false;
2168  }
2169  } // while
2170  if (nominal_size < ranges.back().end_index()) return false;
2171  return true;
2172 } // lar::sparse_vector<T>::is_valid()
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 1851 of file sparse_vector.h.

References util::size().

1852 {
1853  if (ranges.empty() || (index >= size())) throw std::out_of_range("empty sparse vector");
1854  // range after the index:
1855  range_const_iterator iNextRange = find_next_range_iter(index);
1856  return ((iNextRange == ranges.begin()) || ((--iNextRange)->end_index() <= index));
1857 } // lar::sparse_vector<T>::is_void()
size_type size() const
Returns the size of the vector.
range_iterator find_next_range_iter(size_type index)
Returns an iterator to the range after index.
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 1040 of file sparse_vector.h.

1040 { 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 1043 of file sparse_vector.h.

1043 { 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>
auto lar::sparse_vector< T >::iterate_ranges ( ) -> decltype(auto)

Returns the internal list of non-void ranges.

Referenced by lar::details::const_datarange_iterator< T >::operator!=().

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 2102 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.

2103 {
2104  // iterators have in "currentRange" either the range they point into,
2105  // or the range next to the void they point to
2106 
2107  if ((first.cont != this) || (last.cont != this)) {
2108  throw std::runtime_error("lar::sparse_vector::make_void(): iterators from alien container");
2109  }
2110  // if first is after next, no range is identified
2111  if (first >= last) return;
2112 
2113  range_iterator first_range = ranges.begin() + (first.get_current_range() - ranges.begin()),
2114  last_range = ranges.begin() + (last.get_current_range() - ranges.begin());
2115 
2116  //--- "first": void up to this iterator ---
2117  // if first in the last void region, there is nothing to erase
2118  if (first_range == ranges.end()) return;
2119 
2120  // if first is in the middle of a valid range instead, we have to resize it
2121  if (first.index > first_range->begin_index()) {
2122  if (first_range == last_range) {
2123  // we are going to erase a subset of a range;
2124  // this effectively creates two ranges;
2125  // first create the rightmost (last) range, and add it to the list
2126  last_range = ranges.emplace(++last_range,
2127  last.index,
2128  first_range->begin() + first_range->relative_index(last.index),
2129  first_range->end());
2130  // then cut the existing one
2131  first_range->move_tail(first.index);
2132  return;
2133  }
2134  first_range->move_tail(first.index);
2135  ++first_range; // from next range on, start voiding
2136  }
2137 
2138  //--- "last"
2139  // if the index is inside a range, remove up to it
2140  if ((last_range != ranges.end()) && (last.index > last_range->begin_index()))
2141  eat_range_head(last_range, last.index);
2142 
2143  // finally, remove entirely the ranges in between
2144  ranges.erase(first_range, last_range);
2145 } // 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::iterator range_iterator
type of iterator over ranges
template<typename T >
auto 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
Returns
the range just voided
Exceptions
std::out_of_rangeif index is not in the vector
See also
unset(), make_void()

Definition at line 1968 of file sparse_vector.h.

References util::size().

1969 {
1970  if (ranges.empty() || (index >= size())) throw std::out_of_range("empty sparse vector");
1971  // range after the index:
1972  range_iterator iNextRange = find_next_range_iter(index);
1973  if ((iNextRange == ranges.begin()) || ((--iNextRange)->end_index() <= index)) { return {}; }
1974  return void_range(iNextRange);
1975 } // lar::sparse_vector<T>::make_void_around()
size_type size() const
Returns the size of the vector.
range_iterator find_next_range_iter(size_type index)
Returns an iterator to the range after index.
range_list_t::iterator range_iterator
type of iterator over ranges
datarange_t void_range(range_iterator const iRange)
Turns the specified range into void.
template<typename T >
lar::sparse_vector< T >::datarange_t & lar::sparse_vector< T >::merge_ranges ( range_iterator  iRange)
protected

Merges all the following contiguous ranges.

Parameters
iRangeiterator to the range to merge the following ones into
Returns
iterator to the merged range

Starting from the range next to iRange, if that range is contiguous to iRange the two are merged. The merging continues while there are ranges contiguous to iRange. In the end, an iterator is returned pointing to a range that has the same starting point that iRange had, and that is not followed by a contiuguous range, since all contiguous ranges have been merged into it.

Definition at line 2267 of file sparse_vector.h.

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

2269 {
2270  range_iterator iNext = iRange + 1;
2271  while (iNext != ranges.end()) {
2272  if (!iRange->borders(iNext->begin_index())) break;
2273  // iRange content dominates, but if iNext has data beyond it,
2274  // then we copy it
2275  if (iNext->end_index() > iRange->end_index()) {
2276  iRange->extend(iRange->end_index(), iNext->get_iterator(iRange->end_index()), iNext->end());
2277  }
2278  iNext = ranges.erase(iNext);
2279  } // while
2280  fix_size();
2281  return *iRange;
2282 } // lar::sparse_vector<T>::merge_ranges()
size_type fix_size()
Extends the vector size according to the last range.
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 2314 of file sparse_vector.h.

2315 {
2316  // we assume here that there is no additional overhead by alignment;
2317  // the gap adds the space of another datarange_t, including the vector,
2318  // its data and overhead from heap (apparently, 8 bytes);
2319  //
2320  return (sizeof(datarange_t) + 8) / sizeof(value_type) + 1; // round up
2321 } // 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 1165 of file sparse_vector.h.

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

Returns the internal list of non-void ranges.

Definition at line 743 of file sparse_vector.h.

Referenced by hit::GausHitFinder::produce().

743 { return ranges.size(); }
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 547 of file sparse_vector.h.

548  {
549  ranges = std::move(from.ranges);
550  nominal_size = from.nominal_size;
551  from.nominal_size = 0;
552  return *this;
553  } // operator= (sparse_vector&&)
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 1817 of file sparse_vector.h.

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

1818 {
1819  // first range not including the index
1820  range_const_iterator iNextRange = find_next_range_iter(index);
1821 
1822  // if not even the first range includes the index, we are in the void
1823  // (or in some negative index space, if index signedness allowed);
1824  if (iNextRange == ranges.begin()) return value_zero;
1825 
1826  // otherwise, let's take the previous range;
1827  // if it includes the index, we return its value;
1828  // or it precedes it, and our index is in the void: return zero
1829  const datarange_t& range(*--iNextRange);
1830  return (index < range.end_index()) ? range[index] : value_zero;
1831 } // 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_iterator find_next_range_iter(size_type index)
Returns an iterator to the range after index.
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 1834 of file sparse_vector.h.

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

1835 {
1836  // first range not including the index
1837  range_iterator iNextRange = find_next_range_iter(index);
1838 
1839  // if not even the first range includes the index, we are in the void
1840  // (or in some negative index space, if index signedness allowed);
1841  if (iNextRange == ranges.begin()) return reference();
1842 
1843  // otherwise, let's take the previous range;
1844  // if it includes the index, we return its value;
1845  // or it precedes it, and our index is in the void: return zero
1846  datarange_t& range(*--iNextRange);
1847  return (index < range.end_index()) ? reference(range[index]) : reference();
1848 } // 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_iterator find_next_range_iter(size_type index)
Returns an iterator to the range after index.
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 1028 of file sparse_vector.h.

1028 { 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 1029 of file sparse_vector.h.

1029 { 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 652 of file sparse_vector.h.

652 { 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.
double value
Definition: spectrum.C:18
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 661 of file sparse_vector.h.

662  {
663  if (is_zero(value, thr))
664  resize(size() + 1);
665  else
666  push_back(value);
667  } // 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.
double value
Definition: spectrum.C:18
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 746 of file sparse_vector.h.

Referenced by hit::GausHitFinder::produce().

746 { return ranges[i]; }
template<typename T >
auto lar::sparse_vector< T >::range_const_data ( std::size_t  i) const

Like range_data() but with explicitly read-only access to data.

Definition at line 1932 of file sparse_vector.h.

References r.

1933 {
1934  auto& r = ranges[i];
1935  return details::iteratorRange(r.cbegin(), r.cend());
1936 }
TRandom r
Definition: spectrum.C:23
template<typename T >
auto lar::sparse_vector< T >::range_data ( std::size_t  i)

Provides direct access to data of i-th non-void range (zero-based)

Parameters
iindex of the range
Returns
an object suitable for ranged-for iteration

No information about the positioning of the range itself is provided, which can be obtained with other means (e.g. range(i).begin_index()). The returned object can be used in a ranged-for loop:

for (std::size_t iRange = 0; iRange < sv.n_ranges(); ++iRange) {
for (auto& value: sv.range_data(iRange)) {
v *= 2.0;
}
}

(with sv a lar::sparse_vector instance).

While this is a somehow clumsier interface than get_ranges(), it allows, using the non-const version, write access to the data elements. It intentionally provides no write access to the location of each range, though.

Definition at line 1925 of file sparse_vector.h.

References r.

1926 {
1927  auto& r = ranges[i];
1928  return details::iteratorRange(r.begin(), r.end());
1929 }
TRandom r
Definition: spectrum.C:23
template<typename T>
auto lar::sparse_vector< T >::range_data ( std::size_t const  i) const
inline

Returns the internal list of non-void ranges.

Definition at line 772 of file sparse_vector.h.

772 { return range_const_data(i); }
auto range_const_data(std::size_t i) const
Like range_data() but with explicitly read-only access to data.
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 1752 of file sparse_vector.h.

References util::size().

Referenced by recob::WireCreator::WireCreator().

1753 {
1754  if (new_size >= size()) {
1755  nominal_size = new_size;
1756  return;
1757  }
1758 
1759  // truncating...
1760  range_iterator iLastRange = find_next_range_iter(new_size);
1761  ranges.erase(iLastRange, ranges.end());
1762  if (!ranges.empty()) {
1763  range_iterator iLastRange = ranges.end() - 1;
1764  if (new_size == iLastRange->begin_index())
1765  ranges.erase(iLastRange);
1766  else if (new_size < iLastRange->end_index())
1767  iLastRange->resize(new_size - iLastRange->begin_index());
1768  } // if we have ranges
1769 
1770  // formally resize
1771  nominal_size = new_size;
1772 } // lar::sparse_vector<T>::resize()
size_type size() const
Returns the size of the vector.
range_iterator find_next_range_iter(size_type index)
Returns an iterator to the range after index.
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 1775 of file sparse_vector.h.

References util::size().

1776 {
1777  if (new_size == size()) return;
1778  if (new_size > size()) {
1779 
1780  if (back_is_void()) // add a new range
1781  append(vector_t(new_size - size(), def_value));
1782  else // extend the last range
1783  ranges.back().resize(new_size - ranges.back().begin_index(), def_value);
1784 
1785  nominal_size = new_size;
1786  return;
1787  }
1788  // truncating is the same whether there is a default value or not
1789  resize(new_size);
1790 } // 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.
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 1869 of file sparse_vector.h.

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

1871 {
1872  // first range not including the index
1873  range_iterator iNextRange = find_next_range_iter(index);
1874 
1875  // if not even the first range includes the index, we are in the void
1876  // (or in some negative index space, if index signedness allowed);
1877  if (iNextRange != ranges.begin()) {
1878  // otherwise, let's take the previous range;
1879  // if it includes the index, we set the existing value;
1880  // or it precedes it, and our index is in the void, add the value as a
1881  // range
1882  datarange_t& range(*std::prev(iNextRange));
1883  if (index < range.end_index()) return range[index] = value;
1884  }
1885  // so we are in the void; add the value as a new range
1886  return const_cast<datarange_t&>(add_range(index, {value}))[index];
1887 } // 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_iterator find_next_range_iter(size_type index)
Returns an iterator to the range after index.
double value
Definition: spectrum.C:18
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 2324 of file sparse_vector.h.

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

2326 {
2327  size_type gap_size = (a < b) ? b.begin_index() - a.begin_index() - a.size() :
2328  a.begin_index() - b.begin_index() - b.size();
2329  return expected_vector_size(a.size() + b.size() + gap_size) <=
2330  expected_vector_size(a.size()) + expected_vector_size(b.size());
2331 } // 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 577 of file sparse_vector.h.

Referenced by recob::OpWaveform::NSignal(), and recob::Wire::NSignal().

577 { 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 1890 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().

1891 {
1892  // first range not including the index
1893  range_iterator iNextRange = find_next_range_iter(index);
1894 
1895  // if not even the first range includes the index, we are in the void
1896  // (or in some negative index space, if index signedness allowed);
1897  if (iNextRange == ranges.begin()) return;
1898 
1899  // otherwise, let's take the previous range;
1900  // or it precedes the index, and our index is in the void
1901  datarange_t& range(*--iNextRange);
1902  if (index >= range.end_index()) return; // void already
1903 
1904  // it includes the index:
1905  // - if it's a one-element range, remove the range
1906  if (range.size() == 1) ranges.erase(iNextRange);
1907  // - if it's on a border, resize the range
1908  else if (index == range.begin_index())
1909  range.move_head(index + 1);
1910  else if (index == range.end_index() - 1)
1911  range.move_tail(index);
1912  // - if it's inside, break the range in two
1913  else if (index < range.end_index()) {
1914  // we are going to put a hole in a range;
1915  // this effectively creates two ranges;
1916  // first create the rightmost range, and add it to the list
1917  ranges.emplace(
1918  ++iNextRange, index + 1, range.begin() + range.relative_index(index + 1), range.end());
1919  // then cut the existing one
1920  range.move_tail(index);
1921  }
1922 } // 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_iterator find_next_range_iter(size_type index)
Returns an iterator to the range after index.
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 >
auto lar::sparse_vector< T >::void_range ( range_iterator const  iRange)

Turns the specified range into void.

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

The range is effectively removed from the sparse vector, rendering void the interval it previously covered. The range object itself is returned (no copy is performed).

The specified range must be valid. Trying to void an invalid range (including end_range()) yields undefined behavior.

Definition at line 2148 of file sparse_vector.h.

References r.

2149 {
2150  auto r{std::move(*iRange)}; // triggering move constructor
2151  ranges.erase(iRange); // the emptied range is removed from vector
2152  return r; // returning it as a temporary avoids copies
2153 } // lar::sparse_vector<T>::void_range()
TRandom r
Definition: spectrum.C:23
template<typename T>
datarange_t lar::sparse_vector< T >::void_range ( std::size_t const  iRange)
inline

Turns the specified range into void.

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

The range is effectively removed from the sparse vector, rendering void the interval it previously covered. The range object itself is returned (no copy is performed).

The specified range must be valid. Trying to void an invalid range (including end_range()) yields undefined behavior.

Definition at line 1005 of file sparse_vector.h.

Referenced by lar::sparse_vector< float >::void_range().

1005 { return void_range(ranges.begin() + iRange); }
datarange_t void_range(range_iterator const iRange)
Turns the specified range into void.

Member Data Documentation

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

current size

Definition at line 1070 of file sparse_vector.h.

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

list of ranges

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


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