casa
$Rev:20696$
|
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