casacore
Loading...
Searching...
No Matches
casacore::ArrayAccessor< T, U > Class Template Reference

Fast 1D accessor/iterator for nD array classes. More...

Detailed Description

template<class T, class U>
class casacore::ArrayAccessor< T, U >

Fast 1D accessor/iterator for nD array classes.

Intended use:

Public interface

Review Status

Reviewed By:
Ger van Diepen
Date Reviewed:
2002/12/01
Test programs:
tArrayAccessor
Demo programs:
dArrayAccessor

Prerequisite

Etymology

Array and access, rather than Iterator, which would suggest more standard-like interfaces

Synopsis

Accessing a large multi-dimensional array by varying the indices of the array can be a slow process. Timing indications are that for a cube indexing with 3 indices was about seven times slower than using a standard 1D C-like index into an array of basic int types. Improvements have made this less, partly due to some pre-calculation necessary for this class, but can still be a factor of more than 3 slower. There are a variety of ways to access elements cube(i,j,k):

  • Complete random access in all dimensions will need the use of the indexing: cube(i,j,k); or cube(IPosition(3)) as described in the Array and Cube classes
  • Ordered access of all (or most) elements in an Array (in memory order) can be best achieved by the use of Array's STLIterator classes. This is the fastest way for non-contiguous arrays, and only slightly slower than the use of getStorage for contiguous arrays.
  • Ordered access along memory order can also be achieved by the use of the

    getStorage() method. For contiguous arrays this could be slightly faster than the use of the STLIterator (about 10% faster), but slower for non-contiguous arrays. In addition it needs additional memory resources, which will lead to extra overhead. The general use of getStorage is discouraged with the introduction of the STLIterator. It should only be used when an interface to routines in other languages is needed (like Fortran), or when a large Array is known to be contiguous, and the data have to be referenced many times.

  • Access along one or more axes of a (large) multi-dimensional array is best achieved using the ArrayAccessor class. Its total access time is about 2 times faster than indexing (for cubes, more for more indices),
  • Special iteration (like in chunks) are catered for by the ArrayIterator, MatrixIterator, VectorIterator classes.

The ArrayAccessor class is an iterator like pointer to the data in the array. It is a 1-dimensional accessor. It is created with either a constant (at compile time) axis indicator, or with a run-time axis selector. ArrayAccessor constructor accepts a const Array<>. However, the underlying Array class can be modified at this moment. In future a ConstArrayAccessor class is foreseen.

Matrix<double> mat(1000,500); // A 1000*500 matrix
// Fill Matrix..\.
// Loop over index 1, than index 0:
for (ArrayAccessor<double, Axis<1> > i(mat); i != i.end(); ++i) {
for (ArrayAccessor<double, Axis<0> > j(i); j |= j.end(); ++j) {
// Actions on *j (which points to mat(j,i)) or j[n]
// (which points to mat(j+n,i))
}}
Fast 1D accessor/iterator for nD array classes.

For run-time indices it would look like:

Matrix<double> mat(1000,500); // A 1000*500 matrix
// Fill Matrix..\.
// Loop over index 1, than index 0:
for (ArrayAccessor<double, AxisN> i(mat, AxisN(1));
i != i.end(); ++i) {
for (ArrayAccessor<double, AxisN> j(i,AxisN(0)); j |= j.end(); ++j) {
// Actions on *j (which points to mat(j,i)) or j[n]
// (which points to mat(j+n,i))
}}

Compile-time and run-time axes can be mixed in constructors and assignments.


Tip: Like in all comparable situations, memory allocation within a loop can slow down processes; For that reason the example above can be better written (about 25% faster) as:

Matrix<double> mat(1000,500); // A 1000*500 matrix
ArrayAccessor<double, Axis<0> > j; // accessor pre-allocated
// Fill Matrix ;;;
// Loop over index 1, than index 0:
for (ArrayAccessor<double, Axis<1> > i(mat); i != i;end(); ++i) {
for (j=i; j |= j;end(); ++j) {
// Actions on *j (which points to mat(j,i)) or j[n]
// (which points to mat(j+n,i))
}}



Tip: The underlying Array classes are structured with the first index varying fastest; This means that in general (due to caching and swapping) operations are fastest when Axis<0> > is in the innermost loop (if possible of course);
The demonstrator and test programs have more examples.

The accessors can be dereferenced by the dereference operator (*) and by the index operator ([int]), which can handle negative values. Points around the accessor in any axis direction can be addressed along any axis by the templated methods next(), prev() and index(int). Either run-time or compile-time axes can be used (see example).

An accessor can be re-initialized with the init() function. It can also be reset() to any pointer value. Mthods end(), begin(), rbegin() and rend() are available for loop control (like in the STL iterators). In addition each of these can have an optional integer argument, specifying an offset (in points along the current axis).

Operations ++ – += -= are available.

This class is available for Axis<n> and AxisN specializations only.

Example

// get a cube and fill it
Cube<double> cub(5,2,4);
indgen(cub);
// Loop over axes 2-0 and use index() over axis 1
for (ArrayAccessor<double, Axis<2> > i(cub); i != i.end() ; ++i) {
for (ArrayAccessor<double, Axis<0> > j(i);
j != j.end(); ++j) {
// show result
cout << *j << ", " << j.index<Axis<1> >(1) << endl;
};
};
void indgen(TableVector< T > &tv, T start, T inc)
Definition TabVecMath.h:398

See the demonstrator program in aips/implement/Arrays/test/dArrayAccessor.cc and the test program tArrayAccessor for more examples.

Motivation

To speed up especially interpolation code

Template Type Argument Requirements (T)

  • Any valid Array templating argument

Template Type Argument Requirements (U)

  • A class Axis<n>
  • Class AxisN

Thrown Exceptions

  • Exceptions created in the Array class
  • Addressing errors

To Do

  • add a ConstArrayAccessor class
See also
ArrayAccessor<T, Axis<U> >
ArrayAccessor<T, AxisN >

Definition at line 344 of file ArrayAccessor.h.


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