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// Determine the sum, product, etc. for the given axes only.
94// The result is an array with a shape formed by the remaining axes.
95// For example, for an array with shape [3,4,5], collapsing axis 0
96// results in an array with shape [4,5] containing, say, the sum for
97// each X line.
98// Summing for axes 0 and 2 results in an array with shape [4] containing,
99// say, the sum for each XZ plane.
100// <note>
101// ArrayLogical.h contains the functions ntrue, nfalse, partialNTrue and
102// partialNFalse to count the number of true or false elements in an array.
103// </note>
104// <group>
105template <typename T>
106Array<T> partialSums(const Array<T>& array, const IPosition& collapseAxes);
107template <typename T>
108Array<T> partialSumSqrs(const Array<T>& array, const IPosition& collapseAxes);
109template <typename T>
110Array<T> partialProducts(const Array<T>& array, const IPosition& collapseAxes);
111template <typename T>
112Array<T> partialMins(const Array<T>& array, const IPosition& collapseAxes);
113template <typename T>
114Array<T> partialMaxs(const Array<T>& array, const IPosition& collapseAxes);
115template <typename T>
116Array<T> partialMeans(const Array<T>& array, const IPosition& collapseAxes);
117template <typename T>
118inline Array<T> partialVariances(const Array<T>& array, const IPosition& collapseAxes,
119 size_t ddof = 1) {
120 return partialVariances(array, collapseAxes, partialMeans(array, collapseAxes), ddof);
121}
122template <typename T>
124 const Array<T>& means);
125template <typename T>
127 const Array<T>& means, size_t ddof);
128template <typename T>
130 const IPosition& collapseAxes,
131 const Array<std::complex<T>>& means, size_t ddof);
132template <typename T>
133inline Array<T> partialStddevs(const Array<T>& array, const IPosition& collapseAxes,
134 size_t ddof = 1) {
135 return sqrt(partialVariances(array, collapseAxes, partialMeans(array, collapseAxes), ddof));
136}
137template <typename T>
138inline Array<T> partialStddevs(const Array<T>& array, const IPosition& collapseAxes,
139 const Array<T>& means, size_t ddof = 1) {
140 return sqrt(partialVariances(array, collapseAxes, means, ddof));
141}
142template <typename T>
143inline Array<T> partialAvdevs(const Array<T>& array, const IPosition& collapseAxes) {
144 return partialAvdevs(array, collapseAxes, partialMeans(array, collapseAxes));
145}
146template <typename T>
147Array<T> partialAvdevs(const Array<T>& array, const IPosition& collapseAxes, const Array<T>& means);
148template <typename T>
149Array<T> partialRmss(const Array<T>& array, const IPosition& collapseAxes);
150template <typename T>
151Array<T> partialMedians(const Array<T>& array, const IPosition& collapseAxes,
152 bool takeEvenMean = false, bool inPlace = false);
153template <typename T>
154Array<T> partialMadfms(const Array<T>& array, const IPosition& collapseAxes,
155 bool takeEvenMean = false, bool inPlace = false);
156template <typename T>
157Array<T> partialFractiles(const Array<T>& array, const IPosition& collapseAxes, float fraction,
158 bool inPlace = false);
159template <typename T>
161 float fraction, bool inPlace = false);
162template <typename T>
164 bool inPlace = false) {
165 return partialInterFractileRanges(array, collapseAxes, 1. / 6., inPlace);
166}
167template <typename T>
169 bool inPlace = false) {
170 return partialInterFractileRanges(array, collapseAxes, 0.25, inPlace);
171}
172// </group>
173
174// Define functors to perform a reduction function on an Array object.
175// Use virtual functions instead of templates to avoid code bloat
176// in partialArrayMath, etc.
177template <typename T>
178class SumFunc : public ArrayFunctorBase<T> {
179 public:
180 virtual ~SumFunc() {}
181 virtual T operator()(const Array<T>& arr) const final override { return sum(arr); }
182};
183template <typename T>
184class SumSqrFunc : public ArrayFunctorBase<T> {
185 public:
186 virtual ~SumSqrFunc() {}
187 virtual T operator()(const Array<T>& arr) const final override { return sumsqr(arr); }
188};
189template <typename T>
190class ProductFunc : public ArrayFunctorBase<T> {
191 public:
192 virtual ~ProductFunc() {}
193 virtual T operator()(const Array<T>& arr) const final override { return product(arr); }
194};
195template <typename T>
196class MinFunc : public ArrayFunctorBase<T> {
197 public:
198 virtual ~MinFunc() {}
199 virtual T operator()(const Array<T>& arr) const final override { return min(arr); }
200};
201template <typename T>
202class MaxFunc : public ArrayFunctorBase<T> {
203 public:
204 virtual ~MaxFunc() {}
205 virtual T operator()(const Array<T>& arr) const final override { return max(arr); }
206};
207template <typename T>
208class MeanFunc : public ArrayFunctorBase<T> {
209 public:
210 virtual ~MeanFunc() {}
211 virtual T operator()(const Array<T>& arr) const final override { return mean(arr); }
212};
213template <typename T>
215 public:
216 explicit VarianceFunc(size_t ddof) : itsDdof(ddof) {}
217 virtual ~VarianceFunc() {}
218 virtual T operator()(const Array<T>& arr) const final override { return pvariance(arr, itsDdof); }
219
220 private:
221 size_t itsDdof;
222};
223template <typename T>
224class StddevFunc : public ArrayFunctorBase<T> {
225 public:
226 explicit StddevFunc(size_t ddof) : itsDdof(ddof) {}
227 virtual ~StddevFunc() {}
228 virtual T operator()(const Array<T>& arr) const final override { return pstddev(arr, itsDdof); }
229
230 private:
231 size_t itsDdof;
232};
233template <typename T>
234class AvdevFunc : public ArrayFunctorBase<T> {
235 public:
236 virtual ~AvdevFunc() {}
237 virtual T operator()(const Array<T>& arr) const final override { return avdev(arr); }
238};
239template <typename T>
240class RmsFunc : public ArrayFunctorBase<T> {
241 public:
242 virtual ~RmsFunc() {}
243 virtual T operator()(const Array<T>& arr) const final override { return rms(arr); }
244};
245template <typename T>
246class MedianFunc : public ArrayFunctorBase<T> {
247 public:
248 explicit MedianFunc(bool sorted = false, bool takeEvenMean = true, bool inPlace = false)
249 : itsSorted(sorted), itsTakeEvenMean(takeEvenMean), itsInPlace(inPlace) {}
250 virtual ~MedianFunc() {}
251 virtual T operator()(const Array<T>& arr) const final override {
253 }
254
255 private:
259 mutable std::vector<T> itsTmp;
260};
261template <typename T>
262class MadfmFunc : public ArrayFunctorBase<T> {
263 public:
264 explicit MadfmFunc(bool sorted = false, bool takeEvenMean = true, 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 }
270
271 private:
275 mutable std::vector<T> itsTmp;
276};
277template <typename T>
279 public:
280 explicit FractileFunc(float fraction, bool sorted = false, bool inPlace = false)
281 : itsFraction(fraction), itsSorted(sorted), itsInPlace(inPlace) {}
282 virtual ~FractileFunc() {}
283 virtual T operator()(const Array<T>& arr) const final override {
285 }
286
287 private:
291 mutable std::vector<T> itsTmp;
292};
293template <typename T>
295 public:
296 explicit InterFractileRangeFunc(float fraction, bool sorted = false, bool inPlace = false)
297 : itsFraction(fraction), itsSorted(sorted), itsInPlace(inPlace) {}
299 virtual T operator()(const Array<T>& arr) const final override {
300 return interFractileRange(arr, itsTmp, itsFraction, itsSorted, itsInPlace);
301 }
302
303 private:
307 mutable std::vector<T> itsTmp;
308};
309template <typename T>
311 public:
312 explicit InterHexileRangeFunc(bool sorted = false, bool inPlace = false)
313 : InterFractileRangeFunc<T>(1. / 6., sorted, inPlace) {}
315};
316template <typename T>
318 public:
319 explicit InterQuartileRangeFunc(bool sorted = false, bool inPlace = false)
320 : InterFractileRangeFunc<T>(0.25, sorted, inPlace) {}
322};
323
324// Do partial reduction of an Array object. I.e., perform the operation
325// on a subset of the array axes (the collapse axes).
326template <typename T>
327inline Array<T> partialArrayMath(const Array<T>& a, const IPosition& collapseAxes,
328 const ArrayFunctorBase<T>& funcObj) {
329 Array<T> res;
330 partialArrayMath(res, a, collapseAxes, funcObj);
331 return res;
332}
333template <typename T, typename RES>
334void partialArrayMath(Array<RES>& res, const Array<T>& a, const IPosition& collapseAxes,
335 const ArrayFunctorBase<T, RES>& funcObj);
336
337// Apply the given ArrayMath reduction function objects
338// to each box in the array.
339// <example>
340// Downsample an array by taking the median of every [25,25] elements.
341// <srcblock>
342// Array<float> downArr = boxedArrayMath(in, IPosition(2,25,25),
343// MedianFunc<float>());
344// </srcblock>
345// </example>
346// The dimensionality of the array can be larger than the box; in that
347// case the missing axes of the box are assumed to have length 1.
348// A box axis length <= 0 means the full array axis.
349template <typename T>
350inline Array<T> boxedArrayMath(const Array<T>& a, const IPosition& boxSize,
351 const ArrayFunctorBase<T>& funcObj) {
352 Array<T> res;
353 boxedArrayMath(res, a, boxSize, funcObj);
354 return res;
355}
356template <typename T, typename RES>
357void boxedArrayMath(Array<RES>&, const Array<T>& array, const IPosition& boxSize,
358 const ArrayFunctorBase<T, RES>& funcObj);
359
360// Apply for each element in the array the given ArrayMath reduction function
361// object to the box around that element. The full box is 2*halfBoxSize + 1.
362// It can be used for arrays and boxes of any dimensionality; missing
363// halfBoxSize values are set to 0.
364// <example>
365// Determine for each element in the array the median of a box
366// with size [51,51] around that element:
367// <srcblock>
368// Array<float> medians = slidingArrayMath(in, IPosition(2,25,25),
369// MedianFunc<float>());
370// </srcblock>
371// This is a potentially expensive operation. On a high-end PC it took
372// appr. 27 seconds to get the medians for an array of [1000,1000] using
373// a halfBoxSize of [50,50].
374// </example>
375// <br>The fillEdge argument determines how the edge is filled where
376// no full boxes can be made. true means it is set to zero; false means
377// that the edge is removed, thus the output array is smaller than the
378// input array.
379// <note> This brute-force method of determining the medians outperforms
380// all kinds of smart implementations. For a vector it is about as fast
381// as casacore class MedianSlider, for a 2D array
382// it is much, much faster.
383// </note>
384template <typename T>
385inline Array<T> slidingArrayMath(const Array<T>& a, const IPosition& halfBoxSize,
386 const ArrayFunctorBase<T>& funcObj, bool fillEdge = true) {
387 Array<T> res;
388 slidingArrayMath(res, a, halfBoxSize, funcObj, fillEdge);
389 return res;
390}
391template <typename T, typename RES>
392void slidingArrayMath(Array<RES>& res, const Array<T>& array, const IPosition& halfBoxSize,
393 const ArrayFunctorBase<T, RES>& funcObj, bool fillEdge = true);
394
395// </group>
396
397// <group>
398// Helper functions for boxed and sliding functions.
399// Determine full box shape and shape of result for a boxed operation.
400void fillBoxedShape(const IPosition& shape, const IPosition& boxShape, IPosition& fullBoxShape,
401 IPosition& resultShape);
402// Determine the box end and shape of result for a sliding operation.
403// It returns false if the result is empty.
404bool fillSlidingShape(const IPosition& shape, const IPosition& halfBoxSize, IPosition& boxEnd,
405 IPosition& resultShape);
406// </group>
407
408} // namespace casacore
409
410#include "ArrayPartMath.tcc"
411
412#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
For temporary backward namespace compatibility, use casa as alias for casacore.
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:1466
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)
T * array
The actual storage.
Definition Block.h:689
LatticeExprNode min(const LatticeExprNode &left, const LatticeExprNode &right)
LatticeExprNode sqrt(const LatticeExprNode &expr)
IPosition shape(const RecordFieldId &) const
Get the actual shape of this field.
T product(const TableVector< T > &tv)
Definition TabVecMath.h:380
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:1430
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)