casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
ArrayPartMath.h
Go to the documentation of this file.
00001 //# ArrayPartMath.h: mathematics done on an array parts.
00002 //# Copyright (C) 1993,1994,1995,1996,1998,1999,2001,2003
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: ArrayPartMath.h 21130 2011-10-18 07:39:05Z gervandiepen $
00027 
00028 #ifndef CASA_ARRAYPARTMATH_H
00029 #define CASA_ARRAYPARTMATH_H
00030 
00031 #include <casa/Arrays/ArrayMath.h>
00032 
00033 namespace casa { //# NAMESPACE CASA - BEGIN
00034 
00035 // <summary>
00036 //    Mathematical and logical operations for Array parts.
00037 // </summary>
00038 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="tArray">
00039 //
00040 // <prerequisite>
00041 //   <li> <linkto class=Array>Array</linkto>
00042 // </prerequisite>
00043 //
00044 // <etymology>
00045 // This file contains global functions which perform part by part
00046 // mathematical or logical operations on arrays.
00047 // </etymology>
00048 //
00049 // <synopsis>
00050 // These functions perform chunk by chunk mathematical operations on
00051 // arrays.
00052 // In particular boxed and sliding operations are possible. E.g. to calculate
00053 // the median in sliding windows making it possible to subtract the background
00054 // in an image.
00055 //
00056 // The operations to be performed are defined by means of functors that
00057 // reduce an array subset to a scalar. Those functors are wrappers for
00058 // ArrayMath and ArrayLogical functions like sum, median, and ntrue. 
00059 //
00060 // The <src>partialXX</src> functions are a special case of the 
00061 // <src>BoxedArrayMath</src> function.
00062 // They reduce one or more entire axes which can be done in a faster way than
00063 // the more general <src>boxedArrayMath</src> function.
00064 // </synopsis>
00065 //
00066 // <example>
00067 // <srcblock>
00068 // Array<Double> data(...);
00069 // Array<Double> means = partialMeans (data, IPosition(2,0,1));
00070 // </srcblock>
00071 // This example calculates the mean of each plane in the data array.
00072 // </example>
00073 //
00074 // <example>
00075 // <srcblock>
00076 // IPosition shp = data.shape();
00077 // Array<Double> means = boxedArrayMath (data, IPosition(2,shp[0],shp[1]),
00078 //                                       SumFunc<Double>());
00079 // </srcblock>
00080 // does the same as the first example.
00081 // Note that in this example the box is formed by the entire axes, but it
00082 // could also be a subset of it to average, say, boxes of 5*5 elements.
00083 // </example>
00084 //
00085 // <linkfrom anchor="Array mathematical operations" classes="Array Vector Matrix Cube">
00086 //    <here>Array mathematical operations</here> -- Mathematical operations for
00087 //    Arrays.
00088 // </linkfrom>
00089 //
00090 // <group name="Array partial operations">
00091 
00092 
00093 // Determine the sum, product, etc. for the given axes only.
00094 // The result is an array with a shape formed by the remaining axes.
00095 // For example, for an array with shape [3,4,5], collapsing axis 0
00096 // results in an array with shape [4,5] containing, say, the sum for
00097 // each X line.
00098 // Summing for axes 0 and 2 results in an array with shape [4] containing,
00099 // say, the sum for each XZ plane.
00100 // <note>
00101 // ArrayLogical.h contains the functions ntrue, nfalse, partialNTrue and
00102 // partialNFalse to count the number of true or false elements in an array.
00103 // </note>
00104 // <group>
00105 template<class T> Array<T> partialSums (const Array<T>& array,
00106                                         const IPosition& collapseAxes);
00107 template<class T> Array<T> partialProducts (const Array<T>& array,
00108                                             const IPosition& collapseAxes);
00109 template<class T> Array<T> partialMins (const Array<T>& array,
00110                                         const IPosition& collapseAxes);
00111 template<class T> Array<T> partialMaxs (const Array<T>& array,
00112                                         const IPosition& collapseAxes);
00113 template<class T> Array<T> partialMeans (const Array<T>& array,
00114                                          const IPosition& collapseAxes);
00115 template<class T> inline Array<T> partialVariances (const Array<T>& array,
00116                                              const IPosition& collapseAxes)
00117 {
00118     return partialVariances (array, collapseAxes,
00119                              partialMeans (array, collapseAxes));
00120 }
00121 template<class T> Array<T> partialVariances (const Array<T>& array,
00122                                              const IPosition& collapseAxes,
00123                                              const Array<T>& means);
00124 template<class T> inline Array<T> partialStddevs (const Array<T>& array,
00125                                            const IPosition& collapseAxes)
00126 {
00127     return sqrt (partialVariances (array, collapseAxes,
00128                                    partialMeans (array, collapseAxes)));
00129 }
00130 template<class T> inline Array<T> partialStddevs (const Array<T>& array,
00131                                            const IPosition& collapseAxes,
00132                                            const Array<T>& means)
00133 {
00134     return sqrt (partialVariances (array, collapseAxes, means));
00135 }
00136 template<class T> inline Array<T> partialAvdevs (const Array<T>& array,
00137                                           const IPosition& collapseAxes)
00138 {
00139     return partialAvdevs (array, collapseAxes,
00140                           partialMeans (array, collapseAxes));
00141 }
00142 template<class T> Array<T> partialAvdevs (const Array<T>& array,
00143                                           const IPosition& collapseAxes,
00144                                           const Array<T>& means);
00145 template<class T> Array<T> partialRmss (const Array<T>& array,
00146                                         const IPosition& collapseAxes);
00147 template<class T> Array<T> partialMedians (const Array<T>& array,
00148                                            const IPosition& collapseAxes,
00149                                            Bool takeEvenMean=False,
00150                                            Bool inPlace=False);
00151 template<class T> Array<T> partialFractiles (const Array<T>& array,
00152                                              const IPosition& collapseAxes,
00153                                              Float fraction,
00154                                              Bool inPlace=False);
00155 // </group>
00156 
00157 
00158 
00159 template<typename T> class SumFunc {
00160 public:
00161   T operator() (const Array<T>& arr) const { return sum(arr); }
00162 };
00163 template<typename T> class ProductFunc {
00164 public:
00165   T operator() (const Array<T>& arr) const { return product(arr); }
00166 };
00167 template<typename T> class MinFunc {
00168 public:
00169   T operator() (const Array<T>& arr) const { return min(arr); }
00170 };
00171 template<typename T> class MaxFunc {
00172 public:
00173   T operator() (const Array<T>& arr) const { return max(arr); }
00174 };
00175 template<typename T> class MeanFunc {
00176 public:
00177   T operator() (const Array<T>& arr) const { return mean(arr); }
00178 };
00179 template<typename T> class VarianceFunc {
00180 public:
00181   T operator() (const Array<T>& arr) const { return variance(arr); }
00182 };
00183 template<typename T> class StddevFunc {
00184 public:
00185   T operator() (const Array<T>& arr) const { return stddev(arr); }
00186 };
00187 template<typename T> class AvdevFunc {
00188 public:
00189   T operator() (const Array<T>& arr) const { return avdev(arr); }
00190 };
00191 template<typename T> class RmsFunc {
00192 public:
00193   T operator() (const Array<T>& arr) const { return rms(arr); }
00194 };
00195 template<typename T> class MedianFunc {
00196 public:
00197   explicit MedianFunc (Bool sorted=False, Bool takeEvenMean=True,
00198                        Bool inPlace = False)
00199     : itsSorted(sorted), itsTakeEvenMean(takeEvenMean), itsInPlace(inPlace) {}
00200   T operator() (const Array<T>& arr) const
00201     { return median(arr, itsTmp, itsSorted, itsTakeEvenMean, itsInPlace); }
00202 private:
00203   Bool     itsSorted;
00204   Bool     itsTakeEvenMean;
00205   Bool     itsInPlace;
00206   mutable Block<T> itsTmp;
00207 };
00208 template<typename T> class FractileFunc {
00209 public:
00210   explicit FractileFunc (Float fraction,
00211                          Bool sorted = False, Bool inPlace = False)
00212     : itsFraction(fraction), itsSorted(sorted), itsInPlace(inPlace) {}
00213   T operator() (const Array<T>& arr) const
00214     { return fractile(arr, itsTmp, itsFraction, itsSorted, itsInPlace); }
00215 private:
00216   float    itsFraction;
00217   Bool     itsSorted;
00218   Bool     itsInPlace;
00219   mutable Block<T> itsTmp;
00220 };
00221 
00222 // Apply the given ArrayMath reduction function objects
00223 // to each box in the array.
00224 // <example>
00225 // Downsample an array by taking the median of every [25,25] elements.
00226 // <srcblock>
00227 //    Array<Float> downArr = boxedArrayMath(in, IPosition(2,25,25),
00228 //                                          MedianFunc<Float>());
00229 // </srcblock>
00230 // </example>
00231 // The dimensionality of the array can be larger than the box; in that
00232 // case the missing axes of the box are assumed to have length 1.
00233 // A box axis length <= 0 means the full array axis.
00234 template <typename T, typename FuncType>
00235 Array<T> boxedArrayMath (const Array<T>& array,
00236                          const IPosition& boxSize,
00237                          const FuncType& funcObj);
00238 
00239 // Apply for each element in the array the given ArrayMath reduction function
00240 // object to the box around that element. The full box is 2*halfBoxSize + 1.
00241 // It can be used for arrays and boxes of any dimensionality; missing
00242 // halfBoxSize values are set to 0.
00243 // <example>
00244 // Determine for each element in the array the median of a box
00245 // with size [51,51] around that element:
00246 // <srcblock>
00247 //    Array<Float> medians = slidingArrayMath(in, IPosition(2,25,25),
00248 //                                            MedianFunc<Float>());
00249 // </srcblock>
00250 // This is a potentially expensive operation. On a high-end PC it took
00251 // appr. 27 seconds to get the medians for an array of [1000,1000] using
00252 // a halfBoxSize of [50,50].
00253 // </example>
00254 // <br>The fillEdge argument determines how the edge is filled where
00255 // no full boxes can be made. True means it is set to zero; False means
00256 // that the edge is removed, thus the output array is smaller than the
00257 // input array.
00258 // <note> This brute-force method of determining the medians outperforms
00259 // all kinds of smart implementations. For a vector it is about as fast
00260 // as class <linkto class=MedianSlider>MedianSlider</linkto>, for a 2D array
00261 // it is much, much faster.
00262 // </note>
00263 //# Do not use this template definition, as it is stricter. It precludes use
00264 //# of double accumulators on float data.
00265 //# template <typename T, template <typename T> class FuncType>
00266 //# Array<T> slidingArrayMath (const Array<T>& array,
00267 //#                        const IPosition& halfBoxSize,
00268 //#                        const FuncType<T>& funcObj,
00269 //#                        Bool fillEdge=True);
00270 template <typename T, typename FuncType>
00271 Array<T> slidingArrayMath (const Array<T>& array,
00272                            const IPosition& halfBoxSize,
00273                            const FuncType& funcObj,
00274                            Bool fillEdge=True);
00275 
00276 // </group>
00277 
00278 } //# NAMESPACE CASA - END
00279 
00280 #ifndef CASACORE_NO_AUTO_TEMPLATES
00281 #include <casa/Arrays/ArrayPartMath.tcc>
00282 #endif //# CASACORE_NO_AUTO_TEMPLATES
00283 #endif