casacore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
casacore::ArrayAccessor< T, U > Class Template Reference

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

#include <ArrayAccessor.h>

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):

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))
}}

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;
};
};

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)

Template Type Argument Requirements (U)

Thrown Exceptions

To Do

See Also
ArrayAccessor<T, Axis<U> >
ArrayAccessor<T, AxisN >

Definition at line 347 of file ArrayAccessor.h.


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