Reference documentation for deal.II version 9.1.0-pre
Public Types | Public Member Functions | Protected Member Functions | Protected Attributes | Friends | List of all members
TableBase< N, T > Class Template Reference

#include <deal.II/base/table.h>

Inheritance diagram for TableBase< N, T >:
[legend]

Public Types

using size_type = typename AlignedVector< T >::size_type
 

Public Member Functions

 TableBase ()=default
 
 TableBase (const TableIndices< N > &sizes)
 
template<typename InputIterator >
 TableBase (const TableIndices< N > &sizes, InputIterator entries, const bool C_style_indexing=true)
 
 TableBase (const TableBase< N, T > &src)
 
template<typename T2 >
 TableBase (const TableBase< N, T2 > &src)
 
 TableBase (TableBase< N, T > &&src) noexcept
 
 ~TableBase () override=default
 
TableBase< N, T > & operator= (const TableBase< N, T > &src)
 
template<typename T2 >
TableBase< N, T > & operator= (const TableBase< N, T2 > &src)
 
TableBase< N, T > & operator= (TableBase< N, T > &&src) noexcept
 
bool operator== (const TableBase< N, T > &T2) const
 
void reset_values ()
 
void reinit (const TableIndices< N > &new_size, const bool omit_default_initialization=false)
 
size_type size (const unsigned int i) const
 
const TableIndices< N > & size () const
 
size_type n_elements () const
 
bool empty () const
 
template<typename InputIterator >
void fill (InputIterator entries, const bool C_style_indexing=true)
 
void fill (const T &value)
 
AlignedVector< T >::reference operator() (const TableIndices< N > &indices)
 
AlignedVector< T >::const_reference operator() (const TableIndices< N > &indices) const
 
void swap (TableBase< N, T > &v)
 
std::size_t memory_consumption () const
 
template<class Archive >
void serialize (Archive &ar, const unsigned int version)
 
- Public Member Functions inherited from Subscriptor
 Subscriptor ()
 
 Subscriptor (const Subscriptor &)
 
 Subscriptor (Subscriptor &&) noexcept
 
virtual ~Subscriptor ()
 
Subscriptoroperator= (const Subscriptor &)
 
Subscriptoroperator= (Subscriptor &&) noexcept
 
void subscribe (const char *identifier=nullptr) const
 
void unsubscribe (const char *identifier=nullptr) const
 
unsigned int n_subscriptions () const
 
template<typename StreamType >
void list_subscribers (StreamType &stream) const
 
void list_subscribers () const
 
template<class Archive >
void serialize (Archive &ar, const unsigned int version)
 

Protected Member Functions

size_type position (const TableIndices< N > &indices) const
 
AlignedVector< T >::reference el (const TableIndices< N > &indices)
 
AlignedVector< T >::const_reference el (const TableIndices< N > &indices) const
 

Protected Attributes

AlignedVector< T > values
 
TableIndices< N > table_size
 

Friends

template<int , typename >
class TableBase
 

Additional Inherited Members

- Static Public Member Functions inherited from Subscriptor
static::ExceptionBase & ExcInUse (int arg1, std::string arg2, std::string arg3)
 
static::ExceptionBase & ExcNoSubscriber (std::string arg1, std::string arg2)
 

Detailed Description

template<int N, typename T>
class TableBase< N, T >

General class holding an array of objects of templated type in multiple dimensions. If the template parameter indicating the number of dimensions is one, then this is more or less a vector, if it is two then it is a matrix, and so on.

Previously, this data type was emulated in this library by constructs like std::vector<std::vector<T>>, or even higher nested constructs. However, this has the disadvantage that it is hard to initialize, and most importantly that it is very inefficient if all rows have the same size (which is the usual case), since then the memory for each row is allocated independently, both wasting time and memory. This can be made more efficient by allocating only one chunk of memory for the entire object.

Therefore, this data type was invented. Its implementation is rather straightforward, with two exceptions. The first thing to think about is how to pass the size in each of the coordinate directions to the object; this is done using the TableIndices class. Second, how to access the individual elements. The basic problem here is that we would like to make the number of arguments to be passed to the constructor as well as the access functions dependent on the template parameter N indicating the number of dimensions. Of course, this is not possible.

The way out of the first problem (and partly the second one as well) is to have a common base class TableBase and a derived class for each value of N. This derived class has a constructor with the correct number of arguments, namely N. These then transform their arguments into the data type the base class (this class in fact) uses in the constructor as well as in element access through operator() functions.

The second problem is that we would like to allow access through a sequence of operator[] calls. This mostly because, as said, this class is a replacement for previous use of nested std::vector objects, where we had to use the operator[] access function recursively until we were at the innermost object. Emulating this behavior without losing the ability to do index checks, and in particular without losing performance is possible but nontrivial, and done in the TableBaseAccessors namespace.

Comparison with the Tensor class

In some way, this class is similar to the Tensor class, in that it templatizes on the number of dimensions. However, there are two major differences. The first is that the Tensor class stores only numeric values (as doubles), while the Table class stores arbitrary objects. The second is that the Tensor class has fixed dimensions, also given as a template argument, while this class can handle arbitrary dimensions, which may also be different between different indices.

This has two consequences. First, since the size is not known at compile time, it has to do explicit memory allocating. Second, the layout of individual elements is not known at compile time, so access is slower than for the Tensor class where the number of elements are their location is known at compile time and the compiler can optimize with this knowledge (for example when unrolling loops). On the other hand, this class is of course more flexible, for example when you want a two-dimensional table with the number of rows equal to the number of degrees of freedom on a cell, and the number of columns equal to the number of quadrature points. Both numbers may only be known at run-time, so a flexible table is needed here. Furthermore, you may want to store, say, the gradients of shape functions, so the data type is not a single scalar value, but a tensor itself.

Author
Wolfgang Bangerth, 2002.

Definition at line 35 of file table.h.

Member Typedef Documentation

template<int N, typename T>
using TableBase< N, T >::size_type = typename AlignedVector<T>::size_type

Integer type used to count the number of elements in this container.

Definition at line 429 of file table.h.

Constructor & Destructor Documentation

template<int N, typename T>
TableBase< N, T >::TableBase ( )
default

Default constructor. Set all dimensions to zero.

template<int N, typename T>
TableBase< N, T >::TableBase ( const TableIndices< N > &  sizes)

Constructor. Initialize the array with the given dimensions in each index component.

template<int N, typename T>
template<typename InputIterator >
TableBase< N, T >::TableBase ( const TableIndices< N > &  sizes,
InputIterator  entries,
const bool  C_style_indexing = true 
)

Constructor. Initialize the array with the given dimensions in each index component, and then initialize the elements of the table using the second and third argument by calling fill(entries,C_style_indexing).

template<int N, typename T>
TableBase< N, T >::TableBase ( const TableBase< N, T > &  src)

Copy constructor. Performs a deep copy.

template<int N, typename T>
template<typename T2 >
TableBase< N, T >::TableBase ( const TableBase< N, T2 > &  src)

Copy constructor. Performs a deep copy from a table object storing some other data type.

template<int N, typename T>
TableBase< N, T >::TableBase ( TableBase< N, T > &&  src)
noexcept

Move constructor. Transfers the contents of another Table.

template<int N, typename T>
TableBase< N, T >::~TableBase ( )
overridedefault

Destructor. Free allocated memory.

Member Function Documentation

template<int N, typename T>
TableBase<N, T>& TableBase< N, T >::operator= ( const TableBase< N, T > &  src)

Assignment operator. Copy all elements of src into the matrix. The size is adjusted if needed.

We can't use the other, templatized version since if we don't declare this one, the compiler will happily generate a predefined copy operator which is not what we want.

template<int N, typename T>
template<typename T2 >
TableBase<N, T>& TableBase< N, T >::operator= ( const TableBase< N, T2 > &  src)

Copy operator. Copy all elements of src into the array. The size is adjusted if needed.

This function requires that the type T2 is convertible to T.

template<int N, typename T>
TableBase<N, T>& TableBase< N, T >::operator= ( TableBase< N, T > &&  src)
noexcept

Move assignment operator. Transfer all elements of src into the table.

template<int N, typename T>
bool TableBase< N, T >::operator== ( const TableBase< N, T > &  T2) const

Test for equality of two tables.

template<int N, typename T>
void TableBase< N, T >::reset_values ( )

Set all entries to their default value (i.e. copy them over with default constructed objects). Do not change the size of the table, though.

template<int N, typename T>
void TableBase< N, T >::reinit ( const TableIndices< N > &  new_size,
const bool  omit_default_initialization = false 
)

Set the dimensions of this object to the sizes given in the first argument, and allocate the required memory for table entries to accommodate these sizes. If omit_default_initialization is set to false, all elements of the table are set to a default constructed object for the element type. Otherwise the memory is left in an uninitialized or otherwise undefined state.

template<int N, typename T>
size_type TableBase< N, T >::size ( const unsigned int  i) const

Size of the table in direction i.

template<int N, typename T>
const TableIndices<N>& TableBase< N, T >::size ( ) const

Return the sizes of this object in each direction.

template<int N, typename T>
size_type TableBase< N, T >::n_elements ( ) const

Return the number of elements stored in this object, which is the product of the extensions in each dimension.

template<int N, typename T>
bool TableBase< N, T >::empty ( ) const

Return whether the object is empty, i.e. one of the directions is zero. This is equivalent to n_elements()==0.

template<int N, typename T>
template<typename InputIterator >
void TableBase< N, T >::fill ( InputIterator  entries,
const bool  C_style_indexing = true 
)

Fill this table (which is assumed to already have the correct size) from a source given by dereferencing the given forward iterator (which could, for example, be a pointer to the first element of an array, or an inserting std::istream_iterator). The second argument denotes whether the elements pointed to are arranged in a way that corresponds to the last index running fastest or slowest. The default is to use C-style indexing where the last index runs fastest (as opposed to Fortran-style where the first index runs fastest when traversing multidimensional arrays. For example, if you try to fill an object of type Table<2,T>, then calling this function with the default value for the second argument will result in the equivalent of doing

for (unsigned int i=0; i<t.size(0); ++i)
for (unsigned int j=0; j<t.size(1); ++j)
t[i][j] = *entries++;

On the other hand, if the second argument to this function is false, then this would result in code of the following form:

for (unsigned int j=0; j<t.size(1); ++j)
for (unsigned int i=0; i<t.size(0); ++i)
t[i][j] = *entries++;

Note the switched order in which we fill the table elements by traversing the given set of iterators.

Parameters
entriesAn iterator to a set of elements from which to initialize this table. It is assumed that iterator can be incremented and dereferenced a sufficient number of times to fill this table.
C_style_indexingIf true, run over elements of the table with the last index changing fastest as we dereference subsequent elements of the input range. If false, change the first index fastest.
template<int N, typename T>
void TableBase< N, T >::fill ( const T &  value)

Fill all table entries with the same value.

template<int N, typename T>
AlignedVector<T>::reference TableBase< N, T >::operator() ( const TableIndices< N > &  indices)

Return a read-write reference to the indicated element.

template<int N, typename T>
AlignedVector<T>::const_reference TableBase< N, T >::operator() ( const TableIndices< N > &  indices) const

Return the value of the indicated element as a read-only reference.

We return the requested value as a constant reference rather than by value since this object may hold data types that may be large, and we don't know here whether copying is expensive or not.

template<int N, typename T>
void TableBase< N, T >::swap ( TableBase< N, T > &  v)

Swap the contents of this table and the other table v. One could do this operation with a temporary variable and copying over the data elements, but this function is significantly more efficient since it only swaps the pointers to the data of the two vectors and therefore does not need to allocate temporary storage and move data around.

This function is analogous to the swap function of all C++ standard containers. Also, there is a global function swap(u,v) that simply calls u.swap(v), again in analogy to standard functions.

template<int N, typename T>
std::size_t TableBase< N, T >::memory_consumption ( ) const

Determine an estimate for the memory consumption (in bytes) of this object.

template<int N, typename T>
template<class Archive >
void TableBase< N, T >::serialize ( Archive &  ar,
const unsigned int  version 
)

Write or read the data of this object to or from a stream for the purpose of serialization.

template<int N, typename T>
size_type TableBase< N, T >::position ( const TableIndices< N > &  indices) const
protected

Return the position of the indicated element within the array of elements stored one after the other. This function does no index checking.

template<int N, typename T>
AlignedVector<T>::reference TableBase< N, T >::el ( const TableIndices< N > &  indices)
protected

Return a read-write reference to the indicated element.

This function does no bounds checking and is only to be used internally and in functions already checked.

template<int N, typename T>
AlignedVector<T>::const_reference TableBase< N, T >::el ( const TableIndices< N > &  indices) const
protected

Return the value of the indicated element as a read-only reference.

This function does no bounds checking and is only to be used internally and in functions already checked.

We return the requested value as a constant reference rather than by value since this object may hold data types that may be large, and we don't know here whether copying is expensive or not.

Friends And Related Function Documentation

template<int N, typename T>
template<int , typename >
friend class TableBase
friend

Make all other table classes friends.

Definition at line 692 of file table.h.

Member Data Documentation

template<int N, typename T>
AlignedVector<T> TableBase< N, T >::values
protected

Component-array.

Definition at line 681 of file table.h.

template<int N, typename T>
TableIndices<N> TableBase< N, T >::table_size
protected

Size in each direction of the table.

Definition at line 686 of file table.h.


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