casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
MaskArrMath.h
Go to the documentation of this file.
00001 //# MaskArrMath.h: Simple mathematics done with MaskedArray's.
00002 //# Copyright (C) 1993,1994,1995,1996,1999,2001
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: MaskArrMath.h 20551 2009-03-25 00:11:33Z Malte.Marquarding $
00027 
00028 #ifndef CASA_MASKARRMATH_H
00029 #define CASA_MASKARRMATH_H
00030 
00031 
00032 #include <casa/aips.h>
00033 #include <casa/BasicMath/Math.h>
00034 #include <casa/Arrays/Array.h>
00035 #include <casa/Arrays/MaskedArray.h>
00036 #include <casa/Arrays/IPosition.h>
00037 //# Needed to get the proper Complex typedef's
00038 #include <casa/BasicSL/Complex.h>
00039 
00040 
00041 namespace casa { //# NAMESPACE CASA - BEGIN
00042 
00043 // <summary> Mathematical operations for MaskedArrays (and with Arrays) </summary>
00044 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="tMaskArrMath0 tMaskArrMath1 tMaskArrMath2 tMaskArrExcp">
00045 //
00046 // <prerequisite>
00047 //   <li> <linkto class=Array>Array</linkto>
00048 //   <li> <linkto class=MaskedArray>MaskedArray</linkto>
00049 // </prerequisite>
00050 //
00051 // <etymology>
00052 // MaskArrMath is short for MaskedArrayMath, which is too long by
00053 // AIPS++ file naming conventions.  This file contains global functions
00054 // which perform element by element mathematical operations on masked arrays.
00055 // </etymology>
00056 //
00057 // <synopsis>
00058 // These functions perform element by element mathematical operations on
00059 // masked arrays.  With two arrays, they must both conform, and the result
00060 // is done element by element, for those locations where the mask of the
00061 // MaskedArray is True.  For two MaskedArrays, the "and" of the masks is used.
00062 // </synopsis>
00063 //
00064 // <example>
00065 // <srcblock>
00066 //   Vector<Int> a(10);
00067 //   Vector<Int> b(10);
00068 //   Vector<Int> c(10);
00069 //      . . .
00070 //   c = a(a>0) + b(b>0);
00071 // </srcblock>
00072 // This example sets those elements of c where ((a>0) && (b>0)) to (a+b).
00073 // Elements of c where !((a>0) && (b>0)) are unchanged.  The result of
00074 // this operation is a MaskedArray.  The assignment from this
00075 // MaskedArray to the Vector c only assigns those elements
00076 // where the mask is True.
00077 // </example>
00078 //
00079 // <example>
00080 // <srcblock>
00081 //   Vector<Double> a(10);
00082 //   Vector<Double> b(10);
00083 //   Vector<Double> c(10);
00084 //      . . .
00085 //   c = atan2 (a, b(b>0);
00086 // </srcblock>
00087 // This example sets those elements of c where (b>0) to atan2 (a,b).
00088 // Elements of c where !(b>0) are unchanged.  The result of
00089 // this operation is a MaskedArray.  The assignment from this
00090 // MaskedArray to the Vector c only assigns those elements
00091 // where the mask is True.
00092 // </example>
00093 //
00094 // <example>
00095 // <srcblock>
00096 //   Vector<Int> a(10);
00097 //   Int result;
00098 //      . . .
00099 //   result = sum (a(a>0));
00100 // </srcblock>
00101 // This example sums a, for those elements of a which are greater than 0.
00102 // </example>
00103 //
00104 // <motivation>
00105 // One wants to be able to mask arrays and perform mathematical operations on
00106 // those masked arrays.  Since the masked arrays are only defined where
00107 // the masks are True, the result must be a MaskedArray, or a simple number.
00108 // </motivation>
00109 //
00110 // <linkfrom anchor="MaskedArray mathematical operations" classes="MaskedArray Array Vector Matrix Cube">
00111 //    <here>MaskedArray mathematical operations</here> -- Mathematical
00112 //    operations for MaskedArrays, and between MaskedArrays and Arrays.
00113 // </linkfrom>
00114 //
00115 // <group name="MaskedArray mathematical operations">
00116 
00117 // Element by element arithmetic modifying left in-place. left and other
00118 // must be conformant.
00119 // 
00120 // <thrown>
00121 //   <li> ArrayConformanceError
00122 // </thrown>
00123 //
00124 // <group>
00125 template<class T> const MaskedArray<T> & operator+= (const MaskedArray<T> &left, const Array<T> &other);
00126 template<class T> const MaskedArray<T> & operator-= (const MaskedArray<T> &left, const Array<T> &other);
00127 template<class T> const MaskedArray<T> & operator*= (const MaskedArray<T> &left, const Array<T> &other);
00128 template<class T> const MaskedArray<T> & operator/= (const MaskedArray<T> &left, const Array<T> &other);
00129 template<class T> Array<T> & operator+= (Array<T> &left, const MaskedArray<T> &other);
00130 template<class T> Array<T> & operator-= (Array<T> &left, const MaskedArray<T> &other);
00131 template<class T> Array<T> & operator*= (Array<T> &left, const MaskedArray<T> &other);
00132 template<class T> Array<T> & operator/= (Array<T> &left, const MaskedArray<T> &other);
00133 template<class T> const MaskedArray<T> & operator+= (const MaskedArray<T> &left, const MaskedArray<T> &other);
00134 template<class T> const MaskedArray<T> & operator-= (const MaskedArray<T> &left, const MaskedArray<T> &other);
00135 template<class T> const MaskedArray<T> & operator*= (const MaskedArray<T> &left, const MaskedArray<T> &other);
00136 template<class T> const MaskedArray<T> & operator/= (const MaskedArray<T> &left,const MaskedArray<T> &other);
00137 template<class T,class S> const MaskedArray<T> & operator/= (const MaskedArray<T> &left,const MaskedArray<S> &other);
00138 // </group>
00139 
00140 // 
00141 // Element by element arithmetic modifying left in-place. The scalar "other"
00142 // behaves as if it were a conformant Array to left filled with constant values.
00143 // <group>
00144 template<class T> const MaskedArray<T> & operator+= (const MaskedArray<T> &left,const T &other);
00145 template<class T> const MaskedArray<T> & operator-= (const MaskedArray<T> &left,const T &other);
00146 template<class T> const MaskedArray<T> & operator*= (const MaskedArray<T> &left,const T &other);
00147 template<class T> const MaskedArray<T> & operator/= (const MaskedArray<T> &left,const T &other);
00148 // </group>
00149 
00150 // Unary arithmetic operation.
00151 // 
00152 // <group>
00153 template<class T> MaskedArray<T> operator+(const MaskedArray<T> &a);
00154 template<class T> MaskedArray<T> operator-(const MaskedArray<T> &a);
00155 // </group>
00156 
00157 // 
00158 // Element by element arithmetic on MaskedArrays, returns a MaskedArray.
00159 //
00160 // <thrown>
00161 //   <li> ArrayConformanceError
00162 // </thrown>
00163 //
00164 // <group>
00165 template<class T> MaskedArray<T> operator+ (const MaskedArray<T> &left, const Array<T> &right);
00166 template<class T> MaskedArray<T> operator- (const MaskedArray<T> &left, const Array<T> &right);
00167 template<class T> MaskedArray<T> operator* (const MaskedArray<T> &left, const Array<T> &right);
00168 template<class T> MaskedArray<T> operator/ (const MaskedArray<T> &left, const Array<T> &right);
00169 template<class T> MaskedArray<T> operator+ (const Array<T> &left, const MaskedArray<T> &right);
00170 template<class T> MaskedArray<T> operator- (const Array<T> &left, const MaskedArray<T> &right);
00171 template<class T> MaskedArray<T> operator* (const Array<T> &left, const MaskedArray<T> &right);
00172 template<class T> MaskedArray<T> operator/ (const Array<T> &left, const MaskedArray<T> &right);
00173 template<class T> MaskedArray<T> operator+ (const MaskedArray<T> &left,const MaskedArray<T> &right);
00174 template<class T> MaskedArray<T> operator- (const MaskedArray<T> &left,const MaskedArray<T> &right);
00175 template<class T> MaskedArray<T> operator* (const MaskedArray<T> &left,const MaskedArray<T> &right);
00176 template<class T> MaskedArray<T> operator/ (const MaskedArray<T> &left,const MaskedArray<T> &right);
00177 // </group>
00178 
00179 // 
00180 // Element by element arithmetic between a MaskedArray and a scalar, returning
00181 // a MaskedArray.
00182 // <group>
00183 template<class T> MaskedArray<T> operator+ (const MaskedArray<T> &left, const T &right);
00184 template<class T> MaskedArray<T> operator- (const MaskedArray<T> &left, const T &right);
00185 template<class T> MaskedArray<T> operator* (const MaskedArray<T> &left, const T &right);
00186 template<class T> MaskedArray<T> operator/ (const MaskedArray<T> &left, const T &right);
00187                   MaskedArray<Complex> operator* (const MaskedArray<Complex> &left, const Float &right);
00188 // </group>
00189 
00190 // 
00191 // Element by element arithmetic between a scalar and a MaskedArray, returning
00192 // a MaskedArray.
00193 // <group>
00194 template<class T>  MaskedArray<T> operator+ (const T &left, const MaskedArray<T> &right);
00195 template<class T>  MaskedArray<T> operator- (const T &left, const MaskedArray<T> &right);
00196 template<class T>  MaskedArray<T> operator* (const T &left, const MaskedArray<T> &right);
00197 template<class T>  MaskedArray<T> operator/ (const T &left, const MaskedArray<T> &right);
00198                    MaskedArray<Complex> operator* (const Float &left, const MaskedArray<Complex> &right);
00199 // </group>
00200 
00201 // 
00202 // Transcendental function applied to the array on an element-by-element
00203 // basis. Although a template function, this may not make sense for all
00204 // numeric types.
00205 // <group>
00206 template<class T> MaskedArray<T> sin(const MaskedArray<T> &left);
00207 template<class T> MaskedArray<T> cos(const MaskedArray<T> &left);
00208 template<class T> MaskedArray<T> tan(const MaskedArray<T> &left);
00209 template<class T> MaskedArray<T> asin(const MaskedArray<T> &left);
00210 template<class T> MaskedArray<T> acos(const MaskedArray<T> &left);
00211 template<class T> MaskedArray<T> atan(const MaskedArray<T> &left);
00212 template<class T> MaskedArray<T> sinh(const MaskedArray<T> &left);
00213 template<class T> MaskedArray<T> cosh(const MaskedArray<T> &left);
00214 template<class T> MaskedArray<T> tanh(const MaskedArray<T> &left);
00215 template<class T> MaskedArray<T> exp(const MaskedArray<T> &left);
00216 template<class T> MaskedArray<T> log(const MaskedArray<T> &left);
00217 template<class T> MaskedArray<T> log10(const MaskedArray<T> &left);
00218 template<class T> MaskedArray<T> sqrt(const MaskedArray<T> &left);
00219 template<class T> MaskedArray<T> abs(const MaskedArray<T> &left);
00220 template<class T> MaskedArray<T> fabs(const MaskedArray<T> &left);
00221 template<class T> MaskedArray<T> ceil(const MaskedArray<T> &left);
00222 template<class T> MaskedArray<T> floor(const MaskedArray<T> &left);
00223 // </group>
00224 
00225 // Transcendental functions requiring two arguments applied on an element-by-element
00226 // basis. Although a template function, this may not make sense for all
00227 // numeric types.
00228 // <thrown>
00229 //   <li> ArrayConformanceError
00230 // </thrown>
00231 //
00232 // <group>
00233 template<class T> MaskedArray<T> atan2(const MaskedArray<T> &left, const Array<T> &right);
00234 template<class T> MaskedArray<T> fmod(const MaskedArray<T> &left, const Array<T> &right);
00235 template<class T> MaskedArray<T> atan2(const Array<T> &left, const MaskedArray<T> &right);
00236 template<class T> MaskedArray<T> fmod(const Array<T> &left, const MaskedArray<T> &right);
00237 template<class T> MaskedArray<T> atan2(const MaskedArray<T> &left,const MaskedArray<T> &right);
00238 template<class T> MaskedArray<T> fmod(const MaskedArray<T> &left,const MaskedArray<T> &right);
00239 template<class T> MaskedArray<T> atan2(const MaskedArray<T> &left, const T &right);
00240 template<class T> MaskedArray<T> fmod(const MaskedArray<T> &left, const T &right);
00241 template<class T> MaskedArray<T> atan2(const T &left, const MaskedArray<T> &right);
00242 template<class T> MaskedArray<T> fmod(const T &left, const MaskedArray<T> &right);
00243 template<class T, class U> MaskedArray<T> pow(const MaskedArray<T> &left, const Array<U> &right);
00244 template<class T, class U> MaskedArray<T> pow(const Array<T> &left, const MaskedArray<U> &right);
00245 template<class T, class U> MaskedArray<T> pow(const MaskedArray<T> &left,const MaskedArray<U> &right);
00246 template<class T> MaskedArray<T> pow(const MaskedArray<T> &left, const Double &right);
00247 // </group>
00248 
00249 // 
00250 // Find the minimum and maximum values of a MaskedArray.
00251 // Also find the IPositions of the minimum and maximum values.
00252 //
00253 // <thrown>
00254 //    <li> ArrayError
00255 // </thrown>
00256 //
00257 // <group>
00258 template<class T> void minMax(T &minVal, T &maxVal, IPosition &minPos, IPosition &maxPos,const MaskedArray<T> &marray);
00259 template<class T> void minMax(T &minVal, T &maxVal,const MaskedArray<T> &marray);
00260 // </group>
00261 
00262 
00263 // 
00264 // The "min" and "max" functions require that the type "T" have comparison 
00265 // operators.
00266 // The minimum element of the array.
00267 template<class T> T min(const MaskedArray<T> &left);
00268 
00269 
00270 // Return an array that contains the minimum of "left" and "right" at each
00271 // position.
00272 //
00273 // "left" and "right" must be conformant.
00274 //
00275 // <thrown>
00276 //    <li> ArrayError
00277 // </thrown>
00278 // <group>
00279 template<class T> MaskedArray<T> min(const MaskedArray<T> &left, const Array<T> &right);
00280 template<class T> MaskedArray<T> min(const Array<T> &left, const MaskedArray<T> &right);
00281 template<class T> MaskedArray<T> min(const MaskedArray<T> &left, const MaskedArray<T> &right);
00282 template<class T> MaskedArray<T> min(const T &left, const MaskedArray<T> &right);
00283 template<class T> MaskedArray<T> min(const MaskedArray<T> &left, const T &right);
00284 // </group>
00285 
00286 
00287 // "result" contains the minimum of "left" and "right" at each position.
00288 // "result", "left", and "right" must be conformant.
00289 //
00290 // <thrown>
00291 //   <li> ArrayConformanceError
00292 // </thrown>
00293 //
00294 template<class T> void min(const MaskedArray<T> &result, const Array<T> &left, const Array<T> &right);
00295 
00296 
00297 // The maximum element of the array.
00298 template<class T> T max(const MaskedArray<T> &left);
00299 
00300 
00301 // Return an array that contains the maximum of "left" and "right" at each
00302 // position.
00303 //
00304 // "left" and "right" must be conformant.
00305 // <thrown>
00306 //    <li> ArrayError
00307 // </thrown>
00308 //
00309 // <group>
00310 template<class T> MaskedArray<T> max(const MaskedArray<T> &left, const Array<T> &right);
00311 template<class T> MaskedArray<T> max(const Array<T> &left, const MaskedArray<T> &right);
00312 template<class T> MaskedArray<T> max(const MaskedArray<T> &left, const MaskedArray<T> &right);
00313 template<class T> MaskedArray<T> max(const T &left, const MaskedArray<T> &right);
00314 template<class T> MaskedArray<T> max(const MaskedArray<T> &left, const T &right);
00315 // </group>
00316 
00317 
00318 // "result" contains the maximum of "left" and "right" at each position.
00319 // "result", "left", and "right" must be conformant.
00320 //
00321 // <thrown>
00322 //   <li> ArrayConformanceError
00323 // </thrown>
00324 //
00325 template<class T> void max(const MaskedArray<T> &result,const Array<T> &left, const Array<T> &right);
00326 
00327 // 
00328 // Fills all elements of "array" where the mask is True with a sequence
00329 // starting with "start" and incrementing by "inc" for each element
00330 // where the mask is True.
00331 // The first axis varies most rapidly.
00332 template<class T> void indgen(MaskedArray<T> &a, T start, T inc);
00333 
00334 // 
00335 // Fills all elements of "array" where the mask is True with a sequence
00336 // starting with 0 and incremented by one for each element
00337 // where the  mask is True.
00338 // The first axis varies most rapidly.
00339 template<class T>  void indgen(MaskedArray<T> &a);
00340 
00341 // 
00342 // Fills all elements of "array" where the mask is True with a sequence
00343 // starting with "start" and incremented by one for each element
00344 // where the  mask is True.
00345 // The first axis varies most rapidly.
00346 template<class T>  void indgen(MaskedArray<T> &a, T start);
00347 
00348 
00349 // <thrown>
00350 //    <li> ArrayError
00351 // </thrown>
00352 //
00353 // Sum of every element of the MaskedArray where the Mask is True.
00354 template<class T> T sum(const MaskedArray<T> &a);
00355 
00356 // 
00357 // Sum of the squares of every element of the MaskedArray where the Mask is True.
00358 template<class T> T sumsquares(const MaskedArray<T> &a);
00359 
00360 // 
00361 // Product of every element of the MaskedArray where the Mask is True.
00362 // This could of course easily overflow.
00363 template<class T> T product(const MaskedArray<T> &a);
00364 
00365 // 
00366 // The mean of "a" is the sum of all elements of "a" divided by the number
00367 // of elements of "a".
00368 template<class T> T mean(const MaskedArray<T> &a);
00369 
00370 // 
00371 // The variance of "a" is the sum of (a(i) - mean(a))**2/(a.nelements() - 1).
00372 // N.B. N-1, not N in the denominator).
00373 template<class T> T variance(const MaskedArray<T> &a);
00374 
00375 // 
00376 // The variance of "a" is the sum of (a(i) - mean(a))**2/(a.nelements() - 1).
00377 // N.B. N-1, not N in the denominator).
00378 // Rather than using a computed mean, use the supplied value.
00379 template<class T> T variance(const MaskedArray<T> &a, T mean);
00380 
00381 // 
00382 // The standard deviation of "a" is the sqare root of its variance.
00383 template<class T> T stddev(const MaskedArray<T> &a);
00384 
00385 // 
00386 // The standard deviation of "a" is the sqare root of its variance.
00387 // Rather than using a computed mean, use the supplied value.
00388 template<class T> T stddev(const MaskedArray<T> &a, T mean);
00389 
00390 // 
00391 // The average deviation of "a" is the sum of abs(a(i) - mean(a))/N. (N.B.
00392 // N, not N-1 in the denominator).
00393 template<class T> T avdev(const MaskedArray<T> &a);
00394 
00395 // 
00396 // The average deviation of "a" is the sum of abs(a(i) - mean(a))/N. (N.B.
00397 // N, not N-1 in the denominator).
00398 // Rather than using a computed mean, use the supplied value.
00399 template<class T> T avdev(const MaskedArray<T> &a,T mean);
00400 
00401 // 
00402 // The root-mean-square of "a" is the sqrt of sum(a*a)/N.
00403 template<class T> T rms(const MaskedArray<T> &a);
00404 
00405 // 
00406 // The median of "a" is a(n/2).
00407 // When a has an even number of elements and the switch takeEvenMean is set,
00408 // the median is 0.5*(a(n/2) + a((n+1)/2)).
00409 // According to Numerical Recipes (2nd edition) it makes little sense to take
00410 // the mean when the array is large enough (> 100 elements). Therefore
00411 // the default for takeEvenMean is False when the array has > 100 elements,
00412 // otherwise it is True.
00413 // <br>If "sorted"==True we assume the data is already sorted and we
00414 // compute the median directly. Otherwise the function GenSort::kthLargest
00415 // is used to find the median (kthLargest is about 6 times faster
00416 // than a full quicksort).
00417 // <group>
00418 template<class T> inline T median(const MaskedArray<T> &a)
00419     { return median (a, False, (a.nelements() <= 100)); }
00420 template<class T> inline T median(const MaskedArray<T> &a, Bool sorted)
00421     { return median (a, sorted, (a.nelements() <= 100)); }
00422 template<class T> T median(const MaskedArray<T> &a, Bool sorted,
00423                            Bool takeEvenMean);
00424 // </group>
00425 
00426 
00427 // Returns a MaskedArray where every element is squared.
00428 template<class T> MaskedArray<T> square(const MaskedArray<T> &val);
00429 
00430 // Returns a MaskedArray where every element is cubed.
00431 template<class T> MaskedArray<T> cube(const MaskedArray<T> &val);
00432 
00433 // </group>
00434 
00435 
00436 template<typename T> class MaskedSumFunc {
00437 public:
00438   T operator() (const MaskedArray<T>& arr) const { return sum(arr); }
00439 };
00440 template<typename T> class MaskedProductFunc {
00441 public:
00442   T operator() (const MaskedArray<T>& arr) const { return product(arr); }
00443 };
00444 template<typename T> class MaskedMinFunc {
00445 public:
00446   T operator() (const MaskedArray<T>& arr) const { return min(arr); }
00447 };
00448 template<typename T> class MaskedMaxFunc {
00449 public:
00450   T operator() (const MaskedArray<T>& arr) const { return max(arr); }
00451 };
00452 template<typename T> class MaskedMeanFunc {
00453 public:
00454   T operator() (const MaskedArray<T>& arr) const { return mean(arr); }
00455 };
00456 template<typename T> class MaskedVarianceFunc {
00457 public:
00458   T operator() (const MaskedArray<T>& arr) const { return variance(arr); }
00459 };
00460 template<typename T> class MaskedStddevFunc {
00461 public:
00462   T operator() (const MaskedArray<T>& arr) const { return stddev(arr); }
00463 };
00464 template<typename T> class MaskedAvdevFunc {
00465 public:
00466   T operator() (const MaskedArray<T>& arr) const { return avdev(arr); }
00467 };
00468 template<typename T> class MaskedRmsFunc {
00469 public:
00470   T operator() (const MaskedArray<T>& arr) const { return rms(arr); }
00471 };
00472 template<typename T> class MaskedMedianFunc {
00473 public:
00474   explicit MaskedMedianFunc (Bool sorted=False, Bool takeEvenMean=True)
00475     : itsSorted(sorted), itsTakeEvenMean(takeEvenMean) {}
00476   T operator() (const MaskedArray<T>& arr) const
00477     { return median(arr, itsSorted, itsTakeEvenMean); }
00478 private:
00479   Bool     itsSorted;
00480   Bool     itsTakeEvenMean;
00481   Bool     itsInPlace;
00482 };
00483 
00484 // Apply the given ArrayMath reduction function objects
00485 // to each box in the array.
00486 // <example>
00487 // Downsample an array by taking the mean of every [25,25] elements.
00488 // <srcblock>
00489 //    Array<Float> downArr = boxedArrayMath(in, IPosition(2,25,25),
00490 //                                          MaskedMeanFunc<Float>());
00491 // </srcblock>
00492 // </example>
00493 // The dimensionality of the array can be larger than the box; in that
00494 // case the missing axes of the box are assumed to have length 1.
00495 // A box axis length <= 0 means the full array axis.
00496 template <typename T, typename FuncType>
00497 MaskedArray<T> boxedArrayMath (const MaskedArray<T>& array,
00498                                const IPosition& boxSize,
00499                                const FuncType& funcObj);
00500 
00501 // Apply for each element in the array the given ArrayMath reduction function
00502 // object to the box around that element. The full box is 2*halfBoxSize + 1.
00503 // It can be used for arrays and boxes of any dimensionality; missing
00504 // halfBoxSize values are set to 1.
00505 // <example>
00506 // Determine for each element in the array the median of a box
00507 // with size [51,51] around that element:
00508 // <srcblock>
00509 //    Array<Float> medians = slidingArrayMath(in, IPosition(2,25,25),
00510 //                                            MaskedMedianFunc<Float>());
00511 // </srcblock>
00512 // This is a potentially expensive operation. On a high-end PC it took
00513 // appr. 27 seconds to get the medians for an array of [1000,1000] using
00514 // a halfBoxSize of [50,50].
00515 // </example>
00516 // <br>The fillEdge argument determines how the edge is filled where
00517 // no full boxes can be made. True means it is set to zero; False means
00518 // that the edge is removed, thus the output array is smaller than the
00519 // input array.
00520 // <note> This brute-force method of determining the medians outperforms
00521 // all kinds of smart implementations. For a vector it is about as fast
00522 // as class <linkto class=MedianSlider>MedianSlider</linkto>, for a 2D array
00523 // it is much, much faster.
00524 // </note>
00525 template <typename T, typename FuncType>
00526 Array<T> slidingArrayMath (const MaskedArray<T>& array,
00527                            const IPosition& halfBoxSize,
00528                            const FuncType& funcObj,
00529                            Bool fillEdge=True);
00530 
00531 
00532 } //# NAMESPACE CASA - END
00533 
00534 #ifndef CASACORE_NO_AUTO_TEMPLATES
00535 #include <casa/Arrays/MaskArrMath.tcc>
00536 #endif //# CASACORE_NO_AUTO_TEMPLATES
00537 #endif