casacore
Loading...
Searching...
No Matches
ArrayPartMath.h
Go to the documentation of this file.
1//# ArrayPartMath.h: mathematics done on an array parts.
2//# Copyright (C) 1993,1994,1995,1996,1998,1999,2001,2003
3//# Associated Universities, Inc. Washington DC, USA.
4//#
5//# This library is free software; you can redistribute it and/or modify it
6//# under the terms of the GNU Library General Public License as published by
7//# the Free Software Foundation; either version 2 of the License, or (at your
8//# option) any later version.
9//#
10//# This library is distributed in the hope that it will be useful, but WITHOUT
11//# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12//# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13//# License for more details.
14//#
15//# You should have received a copy of the GNU Library General Public License
16//# along with this library; if not, write to the Free Software Foundation,
17//# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18//#
19//# Correspondence concerning AIPS++ should be addressed as follows:
20//# Internet email: casa-feedback@nrao.edu.
21//# Postal address: AIPS++ Project Office
22//# National Radio Astronomy Observatory
23//# 520 Edgemont Road
24//# Charlottesville, VA 22903-2475 USA
25
26#ifndef CASA_ARRAYPARTMATH_2_H
27#define CASA_ARRAYPARTMATH_2_H
28
29#include "ArrayMath.h"
30#include "ArrayMathBase.h"
31
32#include <vector>
33
34namespace casacore { //# NAMESPACE CASACORE - BEGIN
35
36// <summary>
37// Mathematical and logical operations for Array parts.
38// </summary>
39// <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="tArray">
40//
41// <prerequisite>
42// <li> <linkto class=Array>Array</linkto>
43// </prerequisite>
44//
45// <etymology>
46// This file contains global functions which perform part by part
47// mathematical or logical operations on arrays.
48// </etymology>
49//
50// <synopsis>
51// These functions perform chunk by chunk mathematical operations on
52// arrays.
53// In particular boxed and sliding operations are possible. E.g. to calculate
54// the median in sliding windows making it possible to subtract the background
55// in an image.
56//
57// The operations to be performed are defined by means of functors that
58// reduce an array subset to a scalar. Those functors are wrappers for
59// ArrayMath and ArrayLogical functions like sum, median, and ntrue.
60//
61// The <src>partialXX</src> functions are a special case of the
62// <src>BoxedArrayMath</src> function.
63// They reduce one or more entire axes which can be done in a faster way than
64// the more general <src>boxedArrayMath</src> function.
65// </synopsis>
66//
67// <example>
68// <srcblock>
69// Array<double> data(...);
70// Array<double> means = partialMeans (data, IPosition(2,0,1));
71// </srcblock>
72// This example calculates the mean of each plane in the data array.
73// </example>
74//
75// <example>
76// <srcblock>
77// IPosition shp = data.shape();
78// Array<double> means = boxedArrayMath (data, IPosition(2,shp[0],shp[1]),
79// SumFunc<double>());
80// </srcblock>
81// does the same as the first example.
82// Note that in this example the box is formed by the entire axes, but it
83// could also be a subset of it to average, say, boxes of 5*5 elements.
84// </example>
85//
86// <linkfrom anchor="Array mathematical operations" classes="Array Vector Matrix Cube">
87// <here>Array mathematical operations</here> -- Mathematical operations for
88// Arrays.
89// </linkfrom>
90//
91// <group name="Array partial operations">
93
94// Determine the sum, product, etc. for the given axes only.
95// The result is an array with a shape formed by the remaining axes.
96// For example, for an array with shape [3,4,5], collapsing axis 0
97// results in an array with shape [4,5] containing, say, the sum for
98// each X line.
99// Summing for axes 0 and 2 results in an array with shape [4] containing,
100// say, the sum for each XZ plane.
101// <note>
102// ArrayLogical.h contains the functions ntrue, nfalse, partialNTrue and
103// partialNFalse to count the number of true or false elements in an array.
104// </note>
105// <group>
106template<typename T> Array<T> partialSums (const Array<T>& array,
107 const IPosition& collapseAxes);
108template<typename T> Array<T> partialSumSqrs (const Array<T>& array,
109 const IPosition& collapseAxes);
110template<typename T> Array<T> partialProducts (const Array<T>& array,
111 const IPosition& collapseAxes);
112template<typename T> Array<T> partialMins (const Array<T>& array,
113 const IPosition& collapseAxes);
114template<typename T> Array<T> partialMaxs (const Array<T>& array,
115 const IPosition& collapseAxes);
116template<typename T> Array<T> partialMeans (const Array<T>& array,
117 const IPosition& collapseAxes);
118template<typename T>
120 const IPosition& collapseAxes, size_t ddof=1)
121{
122 return partialVariances (array, collapseAxes,
123 partialMeans (array, collapseAxes), ddof);
124}
125template<typename T> Array<T> partialVariances (const Array<T>& array,
126 const IPosition& collapseAxes, const Array<T>& means);
127template<typename T> Array<T> partialVariances (const Array<T>& array,
128 const IPosition& collapseAxes, const Array<T>& means, size_t ddof);
129template<typename T> Array<std::complex<T>> partialVariances (const Array<std::complex<T>>& array,
130 const IPosition& collapseAxes,
131 const Array<std::complex<T>>& means,
132 size_t ddof);
133template<typename T> inline Array<T> partialStddevs (const Array<T>& array,
134 const IPosition& collapseAxes,
135 size_t ddof=1)
136{
137 return sqrt (partialVariances (array, collapseAxes,
138 partialMeans (array, collapseAxes), ddof));
139}
140template<typename T> inline Array<T> partialStddevs (const Array<T>& array,
141 const IPosition& collapseAxes,
142 const Array<T>& means,
143 size_t ddof=1)
144{
145 return sqrt (partialVariances (array, collapseAxes, means, ddof));
146}
147template<typename T> inline Array<T> partialAvdevs (const Array<T>& array,
148 const IPosition& collapseAxes)
149{
150 return partialAvdevs (array, collapseAxes,
151 partialMeans (array, collapseAxes));
152}
153template<typename T> Array<T> partialAvdevs (const Array<T>& array,
154 const IPosition& collapseAxes,
155 const Array<T>& means);
156template<typename T> Array<T> partialRmss (const Array<T>& array,
157 const IPosition& collapseAxes);
158template<typename T> Array<T> partialMedians (const Array<T>& array,
159 const IPosition& collapseAxes,
160 bool takeEvenMean=false,
161 bool inPlace=false);
162template<typename T> Array<T> partialMadfms (const Array<T>& array,
163 const IPosition& collapseAxes,
164 bool takeEvenMean=false,
165 bool inPlace=false);
166template<typename T> Array<T> partialFractiles (const Array<T>& array,
167 const IPosition& collapseAxes,
168 float fraction,
169 bool inPlace=false);
171 const IPosition& collapseAxes,
172 float fraction,
173 bool inPlace=false);
174template<typename T> Array<T> partialInterHexileRanges (const Array<T>& array,
175 const IPosition& collapseAxes,
176 bool inPlace=false)
177 { return partialInterFractileRanges (array, collapseAxes, 1./6., inPlace); }
179 const IPosition& collapseAxes,
180 bool inPlace=false)
181 { return partialInterFractileRanges (array, collapseAxes, 0.25, inPlace); }
182// </group>
183
184
185
186 // Define functors to perform a reduction function on an Array object.
187 // Use virtual functions instead of templates to avoid code bloat
188 // in partialArrayMath, etc.
189 template<typename T> class SumFunc : public ArrayFunctorBase<T> {
190 public:
191 virtual ~SumFunc() {}
192 virtual T operator() (const Array<T>& arr) const final override { return sum(arr); }
193 };
194 template<typename T> class SumSqrFunc : public ArrayFunctorBase<T> {
195 public:
196 virtual ~SumSqrFunc() {}
197 virtual T operator() (const Array<T>& arr) const final override { return sumsqr(arr); }
198 };
199 template<typename T> class ProductFunc : public ArrayFunctorBase<T> {
200 public:
201 virtual ~ProductFunc() {}
202 virtual T operator() (const Array<T>& arr) const final override { return product(arr); }
203 };
204 template<typename T> class MinFunc : public ArrayFunctorBase<T> {
205 public:
206 virtual ~MinFunc() {}
207 virtual T operator() (const Array<T>& arr) const final override { return min(arr); }
208 };
209 template<typename T> class MaxFunc : public ArrayFunctorBase<T> {
210 public:
211 virtual ~MaxFunc() {}
212 virtual T operator() (const Array<T>& arr) const final override { return max(arr); }
213 };
214 template<typename T> class MeanFunc : public ArrayFunctorBase<T> {
215 public:
216 virtual ~MeanFunc() {}
217 virtual T operator() (const Array<T>& arr) const final override { return mean(arr); }
218 };
219 template<typename T> class VarianceFunc : public ArrayFunctorBase<T> {
220 public:
221 explicit VarianceFunc (size_t ddof)
222 : itsDdof(ddof) {}
223 virtual ~VarianceFunc() {}
224 virtual T operator() (const Array<T>& arr) const final override { return pvariance(arr, itsDdof); }
225 private:
226 size_t itsDdof;
227 };
228 template<typename T> class StddevFunc : public ArrayFunctorBase<T> {
229 public:
230 explicit StddevFunc (size_t ddof)
231 : itsDdof(ddof) {}
232 virtual ~StddevFunc() {}
233 virtual T operator() (const Array<T>& arr) const final override { return pstddev(arr, itsDdof); }
234 private:
235 size_t itsDdof;
236 };
237 template<typename T> class AvdevFunc : public ArrayFunctorBase<T> {
238 public:
239 virtual ~AvdevFunc() {}
240 virtual T operator() (const Array<T>& arr) const final override { return avdev(arr); }
241 };
242 template<typename T> class RmsFunc : public ArrayFunctorBase<T> {
243 public:
244 virtual ~RmsFunc() {}
245 virtual T operator() (const Array<T>& arr) const final override { return rms(arr); }
246 };
247 template<typename T> class MedianFunc : public ArrayFunctorBase<T> {
248 public:
249 explicit MedianFunc (bool sorted=false, bool takeEvenMean=true,
250 bool inPlace = false)
251 : itsSorted(sorted), itsTakeEvenMean(takeEvenMean), itsInPlace(inPlace) {}
252 virtual ~MedianFunc() {}
253 virtual T operator() (const Array<T>& arr) const final override
254 { return median(arr, itsTmp, itsSorted, itsTakeEvenMean, itsInPlace); }
255 private:
259 mutable std::vector<T> itsTmp;
260 };
261 template<typename T> class MadfmFunc : public ArrayFunctorBase<T> {
262 public:
263 explicit MadfmFunc(bool sorted = false, bool takeEvenMean = true,
264 bool inPlace = false)
265 : itsSorted(sorted), itsTakeEvenMean(takeEvenMean), itsInPlace(inPlace) {}
266 virtual ~MadfmFunc() {}
267 virtual T operator()(const Array<T>& arr) const final override
268 { return madfm(arr, itsTmp, itsSorted, itsTakeEvenMean, itsInPlace); }
269 private:
273 mutable std::vector<T> itsTmp;
274 };
275 template<typename T> class FractileFunc : public ArrayFunctorBase<T> {
276 public:
277 explicit FractileFunc (float fraction,
278 bool sorted = false, bool inPlace = false)
279 : itsFraction(fraction), itsSorted(sorted), itsInPlace(inPlace) {}
280 virtual ~FractileFunc() {}
281 virtual T operator() (const Array<T>& arr) const final override
282 { return fractile(arr, itsTmp, itsFraction, itsSorted, itsInPlace); }
283 private:
287 mutable std::vector<T> itsTmp;
288 };
289 template<typename T> class InterFractileRangeFunc {
290 public:
291 explicit InterFractileRangeFunc(float fraction,
292 bool sorted = false, bool inPlace = false)
293 : itsFraction(fraction), itsSorted(sorted), itsInPlace(inPlace) {}
295 virtual T operator()(const Array<T>& arr) const final override
296 { return interFractileRange(arr, itsTmp, itsFraction,
297 itsSorted, itsInPlace); }
298 private:
302 mutable std::vector<T> itsTmp;
303 };
304 template<typename T> class InterHexileRangeFunc: public InterFractileRangeFunc<T> {
305 public:
306 explicit InterHexileRangeFunc(bool sorted = false, bool inPlace = false)
307 : InterFractileRangeFunc<T> (1./6., sorted, inPlace)
308 {}
310 };
311 template<typename T> class InterQuartileRangeFunc: public InterFractileRangeFunc<T> {
312 public:
313 explicit InterQuartileRangeFunc(bool sorted = false, bool inPlace = false)
314 : InterFractileRangeFunc<T> (0.25, sorted, inPlace)
315 {}
317 };
318
319
320
321 // Do partial reduction of an Array object. I.e., perform the operation
322 // on a subset of the array axes (the collapse axes).
323 template<typename T>
325 const IPosition& collapseAxes,
326 const ArrayFunctorBase<T>& funcObj)
327 {
328 Array<T> res;
329 partialArrayMath (res, a, collapseAxes, funcObj);
330 return res;
331 }
332 template<typename T, typename RES>
334 const Array<T>& a,
335 const IPosition& collapseAxes,
336 const ArrayFunctorBase<T,RES>& funcObj);
337
338
339// Apply the given ArrayMath reduction function objects
340// to each box in the array.
341// <example>
342// Downsample an array by taking the median of every [25,25] elements.
343// <srcblock>
344// Array<float> downArr = boxedArrayMath(in, IPosition(2,25,25),
345// MedianFunc<float>());
346// </srcblock>
347// </example>
348// The dimensionality of the array can be larger than the box; in that
349// case the missing axes of the box are assumed to have length 1.
350// A box axis length <= 0 means the full array axis.
351 template<typename T>
353 const IPosition& boxSize,
354 const ArrayFunctorBase<T>& funcObj)
355 {
356 Array<T> res;
357 boxedArrayMath (res, a, boxSize, funcObj);
358 return res;
359 }
360 template<typename T, typename RES>
362 const Array<T>& array,
363 const IPosition& boxSize,
364 const ArrayFunctorBase<T,RES>& funcObj);
365
366// Apply for each element in the array the given ArrayMath reduction function
367// object to the box around that element. The full box is 2*halfBoxSize + 1.
368// It can be used for arrays and boxes of any dimensionality; missing
369// halfBoxSize values are set to 0.
370// <example>
371// Determine for each element in the array the median of a box
372// with size [51,51] around that element:
373// <srcblock>
374// Array<float> medians = slidingArrayMath(in, IPosition(2,25,25),
375// MedianFunc<float>());
376// </srcblock>
377// This is a potentially expensive operation. On a high-end PC it took
378// appr. 27 seconds to get the medians for an array of [1000,1000] using
379// a halfBoxSize of [50,50].
380// </example>
381// <br>The fillEdge argument determines how the edge is filled where
382// no full boxes can be made. true means it is set to zero; false means
383// that the edge is removed, thus the output array is smaller than the
384// input array.
385// <note> This brute-force method of determining the medians outperforms
386// all kinds of smart implementations. For a vector it is about as fast
387// as casacore class MedianSlider, for a 2D array
388// it is much, much faster.
389// </note>
390 template<typename T>
392 const IPosition& halfBoxSize,
393 const ArrayFunctorBase<T>& funcObj,
394 bool fillEdge=true)
395 {
396 Array<T> res;
397 slidingArrayMath (res, a, halfBoxSize, funcObj, fillEdge);
398 return res;
399 }
400 template<typename T, typename RES>
402 const Array<T>& array,
403 const IPosition& halfBoxSize,
404 const ArrayFunctorBase<T,RES>& funcObj,
405 bool fillEdge=true);
406
407// </group>
408
409// <group>
410// Helper functions for boxed and sliding functions.
411// Determine full box shape and shape of result for a boxed operation.
412void fillBoxedShape (const IPosition& shape, const IPosition& boxShape,
413 IPosition& fullBoxShape, IPosition& resultShape);
414// Determine the box end and shape of result for a sliding operation.
415// It returns false if the result is empty.
416bool fillSlidingShape (const IPosition& shape, const IPosition& halfBoxSize,
417 IPosition& boxEnd, IPosition& resultShape);
418// </group>
419
420} //# NAMESPACE CASACORE - END
421
422#include "ArrayPartMath.tcc"
423
424#endif
virtual T operator()(const Array< T > &arr) const final override
virtual T operator()(const Array< T > &arr) const final override
FractileFunc(float fraction, bool sorted=false, bool inPlace=false)
InterFractileRangeFunc(float fraction, bool sorted=false, bool inPlace=false)
MadfmFunc(bool sorted=false, bool takeEvenMean=true, bool inPlace=false)
virtual T operator()(const Array< T > &arr) const final override
virtual T operator()(const Array< T > &arr) const final override
virtual T operator()(const Array< T > &arr) const final override
MedianFunc(bool sorted=false, bool takeEvenMean=true, bool inPlace=false)
virtual T operator()(const Array< T > &arr) const final override
virtual T operator()(const Array< T > &arr) const final override
virtual T operator()(const Array< T > &arr) const final override
virtual T operator()(const Array< T > &arr) const final override
virtual T operator()(const Array< T > &arr) const final override
Define functors to perform a reduction function on an Array object.
virtual T operator()(const Array< T > &arr) const final override
virtual T operator()(const Array< T > &arr) const final override
virtual T operator()(const Array< T > &arr) const final override
this file contains all the compiler specific defines
Definition mainpage.dox:28
LatticeExprNode fractile(const LatticeExprNode &expr, const LatticeExprNode &fraction)
Determine the value of the element at the part fraction from the beginning of the given lattice.
TableExprNode means(const TableExprNode &array, const TableExprNodeSet &collapseAxes)
Definition ExprNode.h:1746
LatticeExprNode mean(const LatticeExprNode &expr)
MaskedArray< T > boxedArrayMath(const MaskedArray< T > &array, const IPosition &boxSize, const FuncType &funcObj)
Apply the given ArrayMath reduction function objects to each box in the array.
LatticeExprNode max(const LatticeExprNode &left, const LatticeExprNode &right)
LatticeExprNode sum(const LatticeExprNode &expr)
LatticeExprNode min(const LatticeExprNode &left, const LatticeExprNode &right)
TableExprNode shape(const TableExprNode &array)
Function operating on any scalar or array resulting in a Double array containing the shape.
Definition ExprNode.h:1991
TableExprNode array(const TableExprNode &values, const TableExprNodeSet &shape)
Create an array of the given shape and fill it with the values.
Definition ExprNode.h:1933
LatticeExprNode sqrt(const LatticeExprNode &expr)
T product(const TableVector< T > &tv)
Definition TabVecMath.h:383
LatticeExprNode avdev(const LatticeExprNode &expr)
bool fillSlidingShape(const IPosition &shape, const IPosition &halfBoxSize, IPosition &boxEnd, IPosition &resultShape)
Determine the box end and shape of result for a sliding operation.
LatticeExprNode median(const LatticeExprNode &expr)
Array< T > slidingArrayMath(const MaskedArray< T > &array, const IPosition &halfBoxSize, const FuncType &funcObj, bool fillEdge=true)
Apply for each element in the array the given ArrayMath reduction function object to the box around t...
void fillBoxedShape(const IPosition &shape, const IPosition &boxShape, IPosition &fullBoxShape, IPosition &resultShape)
Helper functions for boxed and sliding functions.
TableExprNode rms(const TableExprNode &array)
Definition ExprNode.h:1684
Array< T > partialAvdevs(const Array< T > &array, const IPosition &collapseAxes, const Array< T > &means)
Array< T > partialMedians(const Array< T > &array, const IPosition &collapseAxes, bool takeEvenMean=false, bool inPlace=false)
Array< T > partialRmss(const Array< T > &array, const IPosition &collapseAxes)
Array< T > partialStddevs(const Array< T > &array, const IPosition &collapseAxes, const Array< T > &means, size_t ddof=1)
Array< T > partialVariances(const Array< T > &array, const IPosition &collapseAxes, const Array< T > &means, size_t ddof)
Array< T > partialProducts(const Array< T > &array, const IPosition &collapseAxes)
Array< T > slidingArrayMath(const Array< T > &a, const IPosition &halfBoxSize, const ArrayFunctorBase< T > &funcObj, bool fillEdge=true)
Apply for each element in the array the given ArrayMath reduction function object to the box around t...
Array< T > partialVariances(const Array< T > &array, const IPosition &collapseAxes, const Array< T > &means)
Array< T > partialInterQuartileRanges(const Array< T > &array, const IPosition &collapseAxes, bool inPlace=false)
Array< T > partialMins(const Array< T > &array, const IPosition &collapseAxes)
Array< T > partialStddevs(const Array< T > &array, const IPosition &collapseAxes, size_t ddof=1)
Array< T > partialAvdevs(const Array< T > &array, const IPosition &collapseAxes)
Array< T > partialInterHexileRanges(const Array< T > &array, const IPosition &collapseAxes, bool inPlace=false)
Array< T > partialInterFractileRanges(const Array< T > &array, const IPosition &collapseAxes, float fraction, bool inPlace=false)
Array< T > boxedArrayMath(const Array< T > &a, const IPosition &boxSize, const ArrayFunctorBase< T > &funcObj)
Apply the given ArrayMath reduction function objects to each box in the array.
Array< T > partialFractiles(const Array< T > &array, const IPosition &collapseAxes, float fraction, bool inPlace=false)
Array< T > partialArrayMath(const Array< T > &a, const IPosition &collapseAxes, const ArrayFunctorBase< T > &funcObj)
Do partial reduction of an Array object.
void boxedArrayMath(Array< RES > &, const Array< T > &array, const IPosition &boxSize, const ArrayFunctorBase< T, RES > &funcObj)
Array< T > partialVariances(const Array< T > &array, const IPosition &collapseAxes, size_t ddof=1)
Array< std::complex< T > > partialVariances(const Array< std::complex< T > > &array, const IPosition &collapseAxes, const Array< std::complex< T > > &means, size_t ddof)
Array< T > partialMeans(const Array< T > &array, const IPosition &collapseAxes)
Array< T > partialMaxs(const Array< T > &array, const IPosition &collapseAxes)
void partialArrayMath(Array< RES > &res, const Array< T > &a, const IPosition &collapseAxes, const ArrayFunctorBase< T, RES > &funcObj)
void slidingArrayMath(Array< RES > &res, const Array< T > &array, const IPosition &halfBoxSize, const ArrayFunctorBase< T, RES > &funcObj, bool fillEdge=true)
Array< T > partialMadfms(const Array< T > &array, const IPosition &collapseAxes, bool takeEvenMean=false, bool inPlace=false)
Array< T > partialSums(const Array< T > &array, const IPosition &collapseAxes)
Determine the sum, product, etc.
Array< T > partialSumSqrs(const Array< T > &array, const IPosition &collapseAxes)