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