casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
ArrayPosIter.h
Go to the documentation of this file.
00001 //# ArrayPosIter.h: Iterate an IPosition through the shape of an Array
00002 //# Copyright (C) 1993,1994,1995,1998,1999,2004
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //# 
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //# 
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //# 
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //# 
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //#
00026 //# $Id: ArrayPosIter.h 21285 2012-11-14 15:36:59Z gervandiepen $
00027 
00028 #ifndef CASA_ARRAYPOSITER_H
00029 #define CASA_ARRAYPOSITER_H
00030 
00031 #include <casa/aips.h>
00032 //# Change the following to a forward declare?
00033 #include <casa/Arrays/IPosition.h>
00034 
00035 namespace casa { //# NAMESPACE CASA - BEGIN
00036 
00037 //# Forward Declarations
00038 class ArrayBase;
00039 
00040 
00041 // <summary> Iterate an IPosition through the shape of an Array </summary>
00042 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
00043 // </reviewed>
00044 
00045 // <synopsis>
00046 // ArrayPositionIterator manipulates an IPosition "cursor" through some
00047 // volume defined by an origin and shape. This position can in turn be
00048 // used to index into, or otherwise define a position in, an Array. Normally
00049 // users won't use this class directly, rather they will use an ArrayIterator,
00050 // VectorIterator or MatrixIterator object, which in turn uses this class.
00051 // ArrayPositionIterator is also used in the implementation of Array.
00052 //
00053 // <srcblock>
00054 // template<class T> void verySlowArrayCopy(Array<T> &to, const Array<T> &from)
00055 // {
00056 //     if (! to.conform(from)) {
00057 //        // throw some error
00058 //     }
00059 //     ArrayPositionIterator toiter(to.shape(), to.origin(),0);
00060 //     ArrayPositionIterator fromiter(from.shape(), from.origin(),0);
00061 //     // If to.origin() == from.origin() we only need one iterator
00062 //     // or we could offset positions by the difference in origins.
00063 //     // The "0" means we are stepping by scalars.
00064 //     while (! toiter.pastEnd()) {    // we know arrays conform
00065 //         to(toiter.pos()) = fromiter(fromiter.pos());
00066 //         toiter.next(); fromiter.next();
00067 //     }
00068 // }
00069 // </srcblock>
00070 //
00071 // Iteration can be done by any combination of axes, but it can only be
00072 // done for full axes.
00073 // <br>The iteration step always "fills up" its dimensionality.
00074 // E.g., if we are stepping through a cube by matrices, the matrix completely
00075 // fills up the plane.
00076 // Class <linkto class=ArrayLattice>ArrayLattice</linkto> in the lattices
00077 // package can be used to iterate with partial volumes.
00078 //
00079 // <p>
00080 // ArrayPositionIterator also serves as the base class of ArrayIterator.
00081 // Function <src>makeIterator</src> in class ArrayBase can be used to make an
00082 // ArrayIterator without having to know the template type. Function
00083 // <src>getArray</src> in this class can be used to obtain the current
00084 // contents of the cursor as an ArrayBase object.
00085 // </synopsis>
00086 
00087 class ArrayPositionIterator
00088 {
00089 public:
00090     // Define the shape and origin of the volume the cursor will step
00091     // through. Also define the dimensionality of the step. byDim==0 implies
00092     // we are stepping by scalars (i.e. every element), byDim==1 implies that
00093     // we are stepping by vector, ==2 by matrices, and so on.
00094     // If uses the first byDim axes as the cursor volume and it steps
00095     // through the remaining axes.
00096     // <group>
00097     ArrayPositionIterator(const IPosition &shape, const IPosition &origin,
00098                           uInt byDim);
00099     ArrayPositionIterator(const IPosition &shape,
00100                           uInt byDim);
00101     // </group>
00102 
00103     // Step through an array using the given axes.
00104     // The axes can be given in two ways:
00105     // <ol>
00106     // <li>axesAreCursor=True means that the axes form the cursor axes.
00107     //     The remaining axes will form the iteration axes.
00108     //     This is the default.
00109     // <li>axesAreCursor=False means the opposite.
00110     //     In this case the iteration axes can be given in any order.
00111     // </ol>
00112     // E.g. when using iteration axes 2,0 for an array with shape [5,3,7], each
00113     // iteration step returns a cursor (containing the data of axis 1).
00114     // During the iteration axis 2 will vary most rapidly (as it was
00115     // given first).
00116     // <br>E.g. for a shape of [3,4,5,6] and cursor axes [2,0], the cursor size
00117     // is [3,5] (axes 0 and 2), while the iteration is done over axes 1 and 3
00118     // (1 the fastest varying one).
00119     ArrayPositionIterator(const IPosition &shape,
00120                           const IPosition &axes,
00121                           Bool axesAreCursor=True);
00122 
00123     virtual ~ArrayPositionIterator() {};
00124 
00125     // Reset the cursor to the beginning of the volume.
00126     // <group>
00127     virtual void reset();
00128     void origin()
00129       { reset(); }
00130     // </group>
00131 
00132     // Returns true of the cursor is at the origin.
00133     Bool atStart() const;
00134 
00135     // Returns true if the cursor has moved past the end of its volume.
00136     Bool pastEnd() const;
00137 
00138     // Return the position of the cursor.
00139     // This include all axes
00140     const IPosition &pos() const {return Cursor;}
00141 
00142     // Return the end position of the cursor.
00143     IPosition endPos() const;
00144 
00145     // Advance the cursor to its next position.
00146     virtual void next();
00147 
00148     // Set the cursor to the given position.
00149     // The position can only contain the iteration axes or it can be the full
00150     // position.
00151     // <br>In the first case the position must to be given in the order
00152     // of the iteration axes as given in the constructor.
00153     // In the latter case the position must be given in natural order
00154     // (as given by function <src>pos</src> and only the cursor axes are taken
00155     // into account.
00156     virtual void set (const IPosition& cursorPos);
00157 
00158     // What is the dimensionality of the volume we are iterating through?
00159     uInt ndim() const;
00160 
00161     // Return the iteration axes.
00162     const IPosition &iterAxes() const {return iterationAxes;}
00163 
00164     // Return the cursor axes.
00165     const IPosition &cursorAxes() const {return cursAxes;}
00166 
00167     // Get the array in the cursor.
00168     // This is only implemented in the derived ArrayIterator class.
00169     // By default it throws an exception.
00170     virtual ArrayBase& getArray();
00171 
00172 protected:
00173     // Advance cursor to its next position and tell which dimension stepped.
00174     uInt nextStep();
00175     // What is the dimensionality of the "step" the cursor takes, i.e.
00176     // 0 for scalars, 1 for vector, ....
00177     uInt dimIter() const {return cursAxes.nelements();}
00178 
00179 private:
00180     // Setup the object for the constructor.
00181     // <group>
00182     void setup(uInt byDim);
00183     void setup(const IPosition &axes, Bool axesAreCursor);
00184     // </group>
00185 
00186     //# We should probably have mf's for getting at Start,Shape and End.
00187     IPosition Start, Shape, End, Cursor;
00188     Bool atOrBeyondEnd;
00189     IPosition cursAxes, iterationAxes;
00190 };
00191 
00192 // Dimensionality of the array we are iterating through.
00193 inline uInt ArrayPositionIterator::ndim() const
00194 {
00195     return Start.nelements();
00196 }
00197 
00198 // We are at the "end" if we cannot advance any more.
00199 inline Bool ArrayPositionIterator::pastEnd() const
00200 {
00201     return atOrBeyondEnd;
00202 }
00203 
00204 
00205 } //# NAMESPACE CASA - END
00206 
00207 #endif