- N = AX
- Specify the constant axis
Default constructor (for use in e.g. containers)
Construct from an Array
Copy constructor (copy semantics)
Assignment (copy semantics)
(Re-)initialize from Array
Dereferencing.
Index along current axis
End of index on line
Start of index on line
End when reverse indexing
Begin when reverse indexing
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.
Default ctor. Note only available to accommodate containers of
ArrayAccessors. Use init() to initialize.
Construct an accessor from specified Array along the selected axis.
The accessor will point to the first element along the axis (i.e.
at (0,0,...)).
Construct from an ArrayAccessor along same axis. The accessor will point
at the same element as the originator.
Construct from accessor along another (or run-time) axis.
The accessor will point to the same element (but will be oriented
along another axis).
Assignment (copy semantics)
Assign from other compile-time accessor along another axis
Assignment (copy semantics)
Assign from run-time accessor along any axis
Assignment (copy semantics)
(Re-)initialization to start of array (i.e. element (0,0,0,...))
Indexing operations along another axis than the one of the current
object. See for the indexing and iterator operations along the
object's axis ArrayBaseAccessor
Reset to start of dimension or to specified pointer
Indexing operations along another axis than the one of the current
object. See for the indexing and iterator operations along the
object's axis ArrayBaseAccessor
Get the value 'next' along the specified axis (e.g. with
a.next<Axis<2> >())
Indexing operations along another axis than the one of the current
object. See for the indexing and iterator operations along the
object's axis ArrayBaseAccessor
Get the value 'previous' along the specified axis (e.g. with
a.prev<Axis<2> >())
Indexing operations along another axis than the one of the current
object. See for the indexing and iterator operations along the
object's axis ArrayBaseAccessor
Get the next or previous along the specified run-time axis. E.g.
a.prev(AxisN(2)).
Indexing operations along another axis than the one of the current
object. See for the indexing and iterator operations along the
object's axis ArrayBaseAccessor
Comparison. The comparisons are done for the accessor pointer
value. They can be used to control loops.
Initialize some internal values
Note that the name of the class is ArrayAccessor. The special
name is only to bypass cxx2html problems with duplicate class names.
Destructor
(Re-)initialization to start of array (i.e. element (0,0,0,...)) or
re-initialize to an axis.
Reset to start of dimension or to specified pointer
Indexing operations along another axis than the one of the current
object. See for the indexing and iterator operations along the
object's axis ArrayBaseAccessor
Comparisons
Initialize some internal values
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.
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))
}}
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.
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
Member Description
ArrayAccessor() : ArrayBaseAccessor<T>()
Constructors
explicit ArrayAccessor(const Array<T> &arr) : ArrayBaseAccessor<T>(arr)
Constructors
ArrayAccessor(const ArrayAccessor<T, Axis<U> > &other) : U<T>(other)
Constructors
template <uInt X> explicit ArrayAccessor(const ArrayAccessor<T, Axis<X> > &other) : ArrayBaseAccessor<T>(other)
Constructors
explicit ArrayAccessor(const ArrayAccessor<T, T > &other) : ArrayBaseAccessor<T>(other)
~ArrayAccessor()
Constructors
template <uInt X> ArrayAccessor &operator=(const ArrayAccessor<T, T<X> > &other)
ArrayAccessor &operator=(const ArrayAccessor<T, AxisN> &other)
ArrayAccessor &operator=(const ArrayAccessor<T, Axis<U> > &other)
void init(const Array<T> &arr)
void reset()
void reset(const T * p)
template <class X> const T &next() const
template <class X> T &next()
template <class X> const T &prev() const
template <class X> T &prev()
const T &next(const AxisN ax) const
T &next(const AxisN ax)
const T &prev(const AxisN ax) const
T &prev(const AxisN ax)
template <class X> const T &index(const Int ix) const
template <class X> T &index(const Int ix)
const T &index(const Int ix, const AxisN ax) const
T &index(const Int ix, const AxisN ax)
Bool operator==(const ArrayAccessor<T, Axis<U> > &other) const
Bool operator!=(const ArrayAccessor<T, Axis<U> > &other) const
Bool operator==(const T *other) const
Bool operator!=(const T *other) const
Int initOff(Int x, uInt ax)
Get proper offset
void initStep()
template <class T> class ArrayAccessor_RT<T, AxisN> :public ArrayBaseAccessor<T>
Interface
Description
Synopsis
This class is a specialization for run-time axis selection within the
array accessor. The axis is specified in the constructors and in the
special indexing operators (prev, next, index) with
a parameter AxisN(n) in stead of a template parameter
<Axis<n> >.
Member Description
explicit ArrayAccessor_RT(const AxisN ax=AxisN(0)) : ax<T>()
Constructors
explicit ArrayAccessor_RT(Array<T> &arr, const T ax=T(0)) : ArrayBaseAccessor<T>(arr, ax.N)
ArrayAccessor_RT(ArrayAccessor_RT<T, AxisN> &other) : ArrayBaseAccessor<T>(other)
explicit ArrayAccessor_RT(ArrayAccessor_RT<T, T> &other, const T ax) : other<T>(other, ax.N)
template <uInt X> explicit ArrayAccessor_RT(ArrayAccessor_RT<T, Axis<X> > &other, const AxisN ax=AxisN(0)) : other<T>(other, ax.N)
ArrayAccessor_RT &operator=(const ArrayAccessor_RT<T, AxisN> &other)
template <uInt X> ArrayAccessor_RT &operator=(const ArrayAccessor_RT<T, T<X> > &other)
~ArrayAccessor_RT()
void init(const Array<T> &arr, const AxisN ax)
void init(const AxisN ax)
void reset()
void reset(const T *p)
template <class X> const T &next() const
template <class X> T &next()
template <class X> const T &prev() const
template <class X> T &prev()
const T &next(const AxisN ax) const
T &next(const AxisN ax)
const T &prev(const AxisN ax) const
T &prev(const AxisN ax)
template <class X> const T &index(const Int ix) const
template <class X> T &index(const Int ix)
const T &index(const Int ix, const ix(ax)) const
T &index(const Int ix, const ix(ax))
Bool operator==(const ArrayAccessor_RT<T, AxisN> &other) const
Bool operator!=(const ArrayAccessor_RT<T, AxisN> &other) const
Bool operator==(const T *other) const
Bool operator!=(const T *other) const
Int initOff(Int x, uInt ax)
Get proper offset
void initStep()