00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef CASA_MARRAYMATH_H
00029 #define CASA_MARRAYMATH_H
00030
00031
00032 #include <casacore/casa/aips.h>
00033 #include <casacore/tables/TaQL/MArray.h>
00034 #include <casacore/tables/TaQL/MArrayMathBase.h>
00035 #include <casacore/casa/Arrays/ArrayPartMath.h>
00036 #include <casacore/casa/Arrays/ArrayIter.h>
00037
00038 namespace casacore {
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 template<typename T> class MSumFunc : public MArrayFunctorBase<T> {
00096 public:
00097 virtual ~MSumFunc() {}
00098 T operator() (const MArray<T>& arr) const { return sum(arr); }
00099 };
00100 template<typename T> class MSumSqrFunc : public MArrayFunctorBase<T> {
00101 public:
00102 virtual ~MSumSqrFunc() {}
00103 T operator() (const MArray<T>& arr) const { return sumsqr(arr); }
00104 };
00105 template<typename T> class MProductFunc : public MArrayFunctorBase<T> {
00106 public:
00107 virtual ~MProductFunc() {}
00108 T operator() (const MArray<T>& arr) const { return product(arr); }
00109 };
00110 template<typename T> class MMinFunc : public MArrayFunctorBase<T> {
00111 public:
00112 virtual ~MMinFunc() {}
00113 T operator() (const MArray<T>& arr) const { return min(arr); }
00114 };
00115 template<typename T> class MMaxFunc : public MArrayFunctorBase<T> {
00116 public:
00117 virtual ~MMaxFunc() {}
00118 T operator() (const MArray<T>& arr) const { return max(arr); }
00119 };
00120 template<typename T> class MMeanFunc : public MArrayFunctorBase<T> {
00121 public:
00122 virtual ~MMeanFunc() {}
00123 T operator() (const MArray<T>& arr) const { return mean(arr); }
00124 };
00125 template<typename T> class MVarianceFunc : public MArrayFunctorBase<T> {
00126 public:
00127 virtual ~MVarianceFunc() {}
00128 T operator() (const MArray<T>& arr) const { return variance(arr); }
00129 };
00130 template<typename T> class MStddevFunc : public MArrayFunctorBase<T> {
00131 public:
00132 virtual ~MStddevFunc() {}
00133 T operator() (const MArray<T>& arr) const { return stddev(arr); }
00134 };
00135 template<typename T> class MAvdevFunc : public MArrayFunctorBase<T> {
00136 public:
00137 virtual ~MAvdevFunc() {}
00138 T operator() (const MArray<T>& arr) const { return avdev(arr); }
00139 };
00140 template<typename T> class MRmsFunc : public MArrayFunctorBase<T> {
00141 public:
00142 virtual ~MRmsFunc() {}
00143 T operator() (const MArray<T>& arr) const { return rms(arr); }
00144 };
00145 template<typename T> class MMedianFunc : public MArrayFunctorBase<T> {
00146 public:
00147 explicit MMedianFunc (Bool sorted=False, Bool takeEvenMean=True,
00148 Bool inPlace = False)
00149 : itsSorted(sorted), itsTakeEvenMean(takeEvenMean), itsInPlace(inPlace) {}
00150 virtual ~MMedianFunc() {}
00151 T operator() (const MArray<T>& arr) const
00152 { return median(arr, itsSorted, itsTakeEvenMean, itsInPlace); }
00153 private:
00154 Bool itsSorted;
00155 Bool itsTakeEvenMean;
00156 Bool itsInPlace;
00157 };
00158 template<typename T> class MFractileFunc : public MArrayFunctorBase<T> {
00159 public:
00160 explicit MFractileFunc (Float fraction,
00161 Bool sorted = False, Bool inPlace = False)
00162 : itsFraction(fraction), itsSorted(sorted), itsInPlace(inPlace) {}
00163 virtual ~MFractileFunc() {}
00164 T operator() (const MArray<T>& arr) const
00165 { return fractile(arr, itsFraction, itsSorted, itsInPlace); }
00166 private:
00167 float itsFraction;
00168 Bool itsSorted;
00169 Bool itsInPlace;
00170 };
00171
00172
00173
00174
00175 template<typename T>
00176 inline MArray<T> partialArrayMath (const MArray<T>& a,
00177 const IPosition& collapseAxes,
00178 const MArrayFunctorBase<T>& funcObj)
00179 {
00180 MArray<T> res;
00181 partialArrayMath (res, a, collapseAxes, funcObj);
00182 return res;
00183 }
00184 template<typename T, typename RES>
00185 void partialArrayMath (MArray<RES>& res,
00186 const MArray<T>& a,
00187 const IPosition& collapseAxes,
00188 const MArrayFunctorBase<T,RES>& funcObj)
00189 {
00190 AlwaysAssert (a.hasMask(), AipsError);
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202 ReadOnlyArrayIterator<T> aiter(a.array(), collapseAxes);
00203 ReadOnlyArrayIterator<Bool> miter(a.mask(), collapseAxes);
00204 IPosition shape(a.array().shape().removeAxes (collapseAxes));
00205
00206
00207
00208
00209
00211
00212
00213
00214
00215
00216
00218 res.resize (shape, False);
00219 Array<Bool> resMask(shape);
00220 RES* data = res.array().data();
00221 Bool* mask = resMask.data();
00222 while (!aiter.pastEnd()) {
00223 if (allTrue(miter.array())) {
00224 *mask++ = True;
00225 *data++ = RES();
00226 } else {
00227 *mask++ = False;
00228 *data++ = funcObj(MArray<T> (aiter.array(), miter.array()));
00229 }
00230 aiter.next();
00231 miter.next();
00232 }
00233 res.setMask (resMask);
00234 }
00235
00236
00237
00238 template<typename T>
00239 inline MArray<T> boxedArrayMath (const MArray<T>& a,
00240 const IPosition& boxShape,
00241 const MArrayFunctorBase<T>& funcObj)
00242 {
00243 MArray<T> res;
00244 boxedArrayMath (res, a, boxShape, funcObj);
00245 return res;
00246 }
00247 template<typename T, typename RES>
00248 void boxedArrayMath (MArray<RES>& res,
00249 const MArray<T>& array,
00250 const IPosition& boxShape,
00251 const MArrayFunctorBase<T,RES>& funcObj)
00252 {
00253 AlwaysAssert (array.hasMask(), AipsError);
00254 const IPosition& shape = array.shape();
00255 uInt ndim = shape.size();
00256 IPosition fullBoxShape, resShape;
00257 fillBoxedShape (shape, boxShape, fullBoxShape, resShape);
00258 res.resize (resShape, False);
00259 Array<Bool> resMask(resShape);
00260 RES* data = res.array().data();
00261 Bool* mask = resMask.data();
00262
00263 IPosition blc(ndim, 0);
00264 IPosition trc(fullBoxShape-1);
00265 while (True) {
00266 Array<Bool> subMask (array.mask()(blc,trc));
00267 if (allTrue(subMask)) {
00268 *data++ = RES();
00269 *mask++ = True;
00270 } else {
00271 *data++ = funcObj (MArray<T>(array.array()(blc,trc), subMask));
00272 *mask++ = False;
00273 }
00274 uInt ax;
00275 for (ax=0; ax<ndim; ++ax) {
00276 blc[ax] += fullBoxShape[ax];
00277 if (blc[ax] < shape[ax]) {
00278 trc[ax] += fullBoxShape[ax];
00279 if (trc[ax] >= shape[ax]) {
00280 trc[ax] = shape[ax]-1;
00281 }
00282 break;
00283 }
00284 blc[ax] = 0;
00285 trc[ax] = fullBoxShape[ax]-1;
00286 }
00287 if (ax == ndim) {
00288 break;
00289 }
00290 }
00291 res.setMask (resMask);
00292 }
00293
00294 template <typename T>
00295 inline MArray<T> slidingArrayMath (const MArray<T>& array,
00296 const IPosition& halfBoxShape,
00297 const MArrayFunctorBase<T>& funcObj,
00298 Bool fillEdge=True)
00299 {
00300 MArray<T> res;
00301 slidingArrayMath (res, array, halfBoxShape, funcObj, fillEdge);
00302 return res;
00303 }
00304 template <typename T, typename RES>
00305 void slidingArrayMath (MArray<RES>& res,
00306 const MArray<T>& array,
00307 const IPosition& halfBoxShape,
00308 const MArrayFunctorBase<T,RES>& funcObj,
00309 Bool fillEdge=True)
00310 {
00311 AlwaysAssert (array.hasMask(), AipsError);
00312 const IPosition& shape = array.shape();
00313 uInt ndim = shape.size();
00314 IPosition boxEnd, resShape;
00315 Bool empty = fillSlidingShape (shape, halfBoxShape, boxEnd, resShape);
00316 if (fillEdge) {
00317 res.resize (shape, False);
00318 res.array() = RES();
00319 Array<Bool> mask(shape, True);
00320 res.setMask (mask);
00321 } else {
00322 res.resize (resShape, True);
00323 }
00324 if (!empty) {
00325 Array<RES> resa (res.array());
00326 Array<Bool> resm (res.mask());
00327 if (fillEdge) {
00328 IPosition boxEnd2 (boxEnd/2);
00329 resa.reference (resa(boxEnd2, resShape+boxEnd2-1));
00330 resm.reference (resm(boxEnd2, resShape+boxEnd2-1));
00331 }
00332 typename Array<RES>::iterator iterarr(resa.begin());
00333 typename Array<Bool>::iterator itermask(resm.begin());
00334
00335 IPosition blc(ndim, 0);
00336 IPosition trc(boxEnd);
00337 IPosition pos(ndim, 0);
00338 while (True) {
00339 Array<Bool> subMask (array.mask()(blc,trc));
00340 if (allTrue(subMask)) {
00341 *iterarr = RES();
00342 *itermask = True;
00343 } else {
00344 *iterarr = funcObj (MArray<T>(array.array()(blc,trc), subMask));
00345 *itermask = False;
00346 }
00347 ++iterarr;
00348 ++itermask;
00349 uInt ax;
00350 for (ax=0; ax<ndim; ++ax) {
00351 if (++pos[ax] < resShape[ax]) {
00352 blc[ax]++;
00353 trc[ax]++;
00354 break;
00355 }
00356 pos(ax) = 0;
00357 blc[ax] = 0;
00358 trc[ax] = boxEnd[ax];
00359 }
00360 if (ax == ndim) {
00361 break;
00362 }
00363 }
00364 }
00365 }
00366
00367
00368
00369
00370 template<typename T>
00371 MArray<T> operator+ (const MArray<T>& left, const MArray<T>& right)
00372 { return (left.isNull() || right.isNull() ? MArray<T>() :
00373 MArray<T> (left.array() + right.array(),
00374 left.combineMask(right))); }
00375
00376 template<typename T>
00377 MArray<T> operator- (const MArray<T>& left, const MArray<T>& right)
00378 { return (left.isNull() || right.isNull() ? MArray<T>() :
00379 MArray<T> (left.array() - right.array(),
00380 left.combineMask(right))); }
00381
00382 template<typename T>
00383 MArray<T> operator* (const MArray<T>& left, const MArray<T>& right)
00384 { return (left.isNull() || right.isNull() ? MArray<T>() :
00385 MArray<T> (left.array() * right.array(),
00386 left.combineMask(right))); }
00387
00388 template<typename T>
00389 MArray<T> operator/ (const MArray<T>& left, const MArray<T>& right)
00390 { return (left.isNull() || right.isNull() ? MArray<T>() :
00391 MArray<T> (left.array() / right.array(),
00392 left.combineMask(right))); }
00393
00394 template<typename T>
00395 MArray<T> operator% (const MArray<T>& left, const MArray<T>& right)
00396 { return (left.isNull() || right.isNull() ? MArray<T>() :
00397 MArray<T> (left.array() % right.array(),
00398 left.combineMask(right))); }
00399
00400 template<typename T>
00401 MArray<T> operator& (const MArray<T>& left, const MArray<T>& right)
00402 { return (left.isNull() || right.isNull() ? MArray<T>() :
00403 MArray<T> (left.array() & right.array(),
00404 left.combineMask(right))); }
00405
00406 template<typename T>
00407 MArray<T> operator| (const MArray<T>& left, const MArray<T>& right)
00408 { return (left.isNull() || right.isNull() ? MArray<T>() :
00409 MArray<T> (left.array() | right.array(),
00410 left.combineMask(right))); }
00411
00412 template<typename T>
00413 MArray<T> operator^ (const MArray<T>& left, const MArray<T>& right)
00414 { return (left.isNull() || right.isNull() ? MArray<T>() :
00415 MArray<T> (left.array() ^ right.array(),
00416 left.combineMask(right))); }
00417
00418 template<typename T>
00419 MArray<T> operator+ (const MArray<T>& left, const T& right)
00420 { return MArray<T> (left.array() + right, left); }
00421
00422 template<typename T>
00423 MArray<T> operator- (const MArray<T>& left, const T& right)
00424 { return MArray<T> (left.array() - right, left); }
00425
00426 template<typename T>
00427 MArray<T> operator* (const MArray<T>& left, const T& right)
00428 { return MArray<T> (left.array() * right, left); }
00429
00430 template<typename T>
00431 MArray<T> operator/ (const MArray<T>& left, const T& right)
00432 { return MArray<T> (left.array() / right, left); }
00433
00434 template<typename T>
00435 MArray<T> operator% (const MArray<T>& left, const T& right)
00436 { return MArray<T> (left.array() % right, left); }
00437
00438 template<typename T>
00439 MArray<T> operator& (const MArray<T>& left, const T& right)
00440 { return MArray<T> (left.array() & right, left); }
00441
00442 template<typename T>
00443 MArray<T> operator| (const MArray<T>& left, const T& right)
00444 { return MArray<T> (left.array() | right, left); }
00445
00446 template<typename T>
00447 MArray<T> operator^ (const MArray<T>& left, const T& right)
00448 { return MArray<T> (left.array() ^ right, left); }
00449
00450 template<typename T>
00451 MArray<T> operator+ (const T& left, const MArray<T>& right)
00452 { return MArray<T> (left + right.array(), right); }
00453
00454 template<typename T>
00455 MArray<T> operator- (const T& left, const MArray<T>& right)
00456 { return MArray<T> (left - right.array(), right); }
00457
00458 template<typename T>
00459 MArray<T> operator* (const T& left, const MArray<T>& right)
00460 { return MArray<T> (left * right.array(), right); }
00461
00462 template<typename T>
00463 MArray<T> operator/ (const T& left, const MArray<T>& right)
00464 { return MArray<T> (left / right.array(), right); }
00465
00466 template<typename T>
00467 MArray<T> operator% (const T& left, const MArray<T>& right)
00468 { return MArray<T> (left % right.array(), right); }
00469
00470 template<typename T>
00471 MArray<T> operator& (const T& left, const MArray<T>& right)
00472 { return MArray<T> (left & right.array(), right); }
00473
00474 template<typename T>
00475 MArray<T> operator| (const T& left, const MArray<T>& right)
00476 { return MArray<T> (left | right.array(), right); }
00477
00478 template<typename T>
00479 MArray<T> operator^ (const T& left, const MArray<T>& right)
00480 { return MArray<T> (left ^ right.array(), right); }
00481
00482
00483
00484 template<typename T>
00485 MArray<T> operator- (const MArray<T>& a)
00486 { return MArray<T> (-a.array(), a); }
00487
00488
00489 template<typename T>
00490 MArray<T> operator~ (const MArray<T>& a)
00491 { return MArray<T> (~a.array(), a); }
00492
00493
00494
00495 template<typename T>
00496 MArray<T> sin(const MArray<T>& a)
00497 { return MArray<T> (sin(a.array()), a); }
00498
00499 template<typename T>
00500 MArray<T> cos(const MArray<T>& a)
00501 { return MArray<T> (cos(a.array()), a); }
00502
00503 template<typename T>
00504 MArray<T> tan(const MArray<T>& a)
00505 { return MArray<T> (tan(a.array()), a); }
00506
00507 template<typename T>
00508 MArray<T> sinh(const MArray<T>& a)
00509 { return MArray<T> (sinh(a.array()), a); }
00510
00511 template<typename T>
00512 MArray<T> cosh(const MArray<T>& a)
00513 { return MArray<T> (cosh(a.array()), a); }
00514
00515 template<typename T>
00516 MArray<T> tanh(const MArray<T>& a)
00517 { return MArray<T> (tanh(a.array()), a); }
00518
00519 template<typename T>
00520 MArray<T> asin(const MArray<T>& a)
00521 { return MArray<T> (asin(a.array()), a); }
00522
00523 template<typename T>
00524 MArray<T> acos(const MArray<T>& a)
00525 { return MArray<T> (acos(a.array()), a); }
00526
00527 template<typename T>
00528 MArray<T> atan(const MArray<T>& a)
00529 { return MArray<T> (atan(a.array()), a); }
00530
00531 template<typename T>
00532 MArray<T> atan2(const MArray<T>& left, const MArray<T>& right)
00533 { return (left.isNull() || right.isNull() ? MArray<T>() :
00534 MArray<T> (atan2(left.array(), right.array()),
00535 left.combineMask(right))); }
00536
00537 template<typename T>
00538 MArray<T> atan2(const MArray<T>& left, const T& right)
00539 { return MArray<T> (atan2(left.array(), right), left); }
00540
00541 template<typename T>
00542 MArray<T> atan2(const T& left, const MArray<T>& right)
00543 { return MArray<T> (atan2(left, right.array()), right); }
00544
00545 template<typename T>
00546 MArray<T> exp(const MArray<T>& a)
00547 { return MArray<T> (exp(a.array()), a); }
00548
00549 template<typename T>
00550 MArray<T> log(const MArray<T>& a)
00551 { return MArray<T> (log(a.array()), a); }
00552
00553 template<typename T>
00554 MArray<T> log10(const MArray<T>& a)
00555 { return MArray<T> (log10(a.array()), a); }
00556
00557 template<typename T>
00558 MArray<T> sqrt(const MArray<T>& a)
00559 { return MArray<T> (sqrt(a.array()), a); }
00560
00561 template<typename T>
00562 MArray<T> square(const MArray<T>& a)
00563 { return MArray<T> (square(a.array()), a); }
00564
00565 template<typename T>
00566 MArray<T> cube(const MArray<T>& a)
00567 { return MArray<T> (cube(a.array()), a); }
00568
00569 template<typename T>
00570 MArray<T> pow(const MArray<T>& a, const MArray<T>& exp)
00571 { return (a.isNull() || exp.isNull() ? MArray<T>() :
00572 MArray<T> (pow(a.array(), exp.array()),
00573 a.combineMask(exp))); }
00574
00575 template<typename T>
00576 MArray<T> pow(const T& a, const MArray<T>& exp)
00577 { return MArray<T> (pow(a, exp.array()), exp); }
00578
00579 template<typename T>
00580 MArray<T> pow(const MArray<T>& a, const Double& exp)
00581 { return MArray<T> (pow(a.array(), exp), a); }
00582
00583 template<typename T>
00584 MArray<T> min(const MArray<T>& left, const MArray<T>& right)
00585 { return (left.isNull() || right.isNull() ? MArray<T>() :
00586 MArray<T> (min(left.array(), right.array()),
00587 left.combineMask(right))); }
00588
00589 template<typename T>
00590 MArray<T> min(const MArray<T>& left, const T& right)
00591 { return MArray<T> (min(left.array(), right), left); }
00592
00593 template<typename T>
00594 MArray<T> min(const T& left, const MArray<T>& right)
00595 { return MArray<T> (min(left, right.array()), right); }
00596
00597 template<typename T>
00598 MArray<T> max(const MArray<T>& left, const MArray<T>& right)
00599 { return (left.isNull() || right.isNull() ? MArray<T>() :
00600 MArray<T> (max(left.array(), right.array()),
00601 left.combineMask(right))); }
00602
00603 template<typename T>
00604 MArray<T> max(const MArray<T>& left, const T& right)
00605 { return MArray<T> (max(left.array(), right), left); }
00606
00607 template<typename T>
00608 MArray<T> max(const T& left, const MArray<T>& right)
00609 { return MArray<T> (max(left, right.array()), right); }
00610
00611 template<typename T>
00612 MArray<T> ceil(const MArray<T>& a)
00613 { return MArray<T> (ceil(a.array()), a); }
00614
00615 template<typename T>
00616 MArray<T> floor(const MArray<T>& a)
00617 { return MArray<T> (floor(a.array()), a); }
00618
00619 template<typename T>
00620 MArray<T> round(const MArray<T>& a)
00621 { return MArray<T> (round(a.array()), a); }
00622
00623 template<typename T>
00624 MArray<T> sign(const MArray<T>& a)
00625 { return MArray<T> (sign(a.array()), a); }
00626
00627 template<typename T>
00628 MArray<T> abs(const MArray<T>& a)
00629 { return MArray<T> (abs(a.array()), a); }
00630
00631 template<typename T>
00632 MArray<T> fabs(const MArray<T>& a)
00633 { return MArray<T> (fabs(a.array()), a); }
00634
00635 template<typename T>
00636 MArray<T> fmod(const MArray<T>& left, const MArray<T>& right)
00637 { return (left.isNull() || right.isNull() ? MArray<T>() :
00638 MArray<T> (fmod(left.array(), right.array()),
00639 left.combineMask(right))); }
00640
00641 template<typename T>
00642 MArray<T> fmod(const MArray<T>& left, const T& right)
00643 { return MArray<T> (fmod(left.array(), right), left); }
00644
00645 template<typename T>
00646 MArray<T> fmod(const T& left, const MArray<T>& right)
00647 { return MArray<T> (fmod(left, right.array()), right); }
00648
00649 template<typename T>
00650 MArray<T> floormod(const MArray<T>& left, const MArray<T>& right)
00651 { return (left.isNull() || right.isNull() ? MArray<T>() :
00652 MArray<T> (floormod(left.array(), right.array()),
00653 left.combineMask(right))); }
00654
00655 template<typename T>
00656 MArray<T> floormod(const MArray<T>& left, const T& right)
00657 { return MArray<T> (floormod(left.array(), right), left); }
00658
00659 template<typename T>
00660 MArray<T> floormod(const T& left, const MArray<T>& right)
00661 { return MArray<T> (floormod(left, right.array()), right); }
00662
00663 template<typename T>
00664 MArray<T> conj(const MArray<T>& arr)
00665 { return MArray<T> (conj(arr.array()), arr); }
00666
00667 inline MArray<Float> real(const MArray<Complex> &arr)
00668 { return MArray<Float> (real(arr.array()), arr); }
00669
00670 inline MArray<Float> imag(const MArray<Complex> &arr)
00671 { return MArray<Float> (imag(arr.array()), arr); }
00672
00673 inline MArray<Float> amplitude(const MArray<Complex> &arr)
00674 { return MArray<Float> (amplitude(arr.array()), arr); }
00675
00676 inline MArray<Float> phase(const MArray<Complex> &arr)
00677 { return MArray<Float> (phase(arr.array()), arr); }
00678
00679 inline MArray<Double> real(const MArray<DComplex> &arr)
00680 { return MArray<Double> (real(arr.array()), arr); }
00681
00682 inline MArray<Double> imag(const MArray<DComplex> &arr)
00683 { return MArray<Double> (imag(arr.array()), arr); }
00684
00685 inline MArray<Double> amplitude(const MArray<DComplex> &arr)
00686 { return MArray<Double> (amplitude(arr.array()), arr); }
00687
00688 inline MArray<Double> phase(const MArray<DComplex> &arr)
00689 { return MArray<Double> (phase(arr.array()), arr); }
00690
00691
00692
00693
00694
00695
00696 template<typename T>
00697 T sum(const MArray<T>& a)
00698 {
00699 if (a.hasMask()) {
00700 return a.array().contiguousStorage() && a.mask().contiguousStorage() ?
00701 accumulateMasked<T>(a.array().cbegin(), a.array().cend(),
00702 a.mask().cbegin(), T(), std::plus<T>()) :
00703 accumulateMasked<T>(a.array().begin(), a.array().end(),
00704 a.mask().begin(), T(), std::plus<T>());
00705 }
00706 return sum(a.array());
00707 }
00708
00709 template<typename T>
00710 T sumsqr(const MArray<T>& a)
00711 {
00712 if (a.hasMask()) {
00713 return a.array().contiguousStorage() && a.mask().contiguousStorage() ?
00714 accumulateMasked<T>(a.array().cbegin(), a.array().cend(),
00715 a.mask().cbegin(), T(), SumSqr<T>()) :
00716 accumulateMasked<T>(a.array().begin(), a.array().end(),
00717 a.mask().begin(), T(), SumSqr<T>());
00718 }
00719 return sumsqr(a.array());
00720 }
00721
00722 template<typename T>
00723 T product(const MArray<T>& a)
00724 {
00725 if (a.hasMask()) {
00726 return a.array().contiguousStorage() && a.mask().contiguousStorage() ?
00727 accumulateMasked<T>(a.array().cbegin(), a.array().cend(),
00728 a.mask().cbegin(), std::multiplies<T>()) :
00729 accumulateMasked<T>(a.array().begin(), a.array().end(),
00730 a.mask().begin(), std::multiplies<T>());
00731 }
00732 return product(a.array());
00733 }
00734
00735 template<typename T>
00736 T min(const MArray<T>& a)
00737 {
00738 if (a.hasMask()) {
00739 return a.array().contiguousStorage() && a.mask().contiguousStorage() ?
00740 accumulateMasked<T>(a.array().cbegin(), a.array().cend(),
00741 a.mask().cbegin(), Min<T>()) :
00742 accumulateMasked<T>(a.array().begin(), a.array().end(),
00743 a.mask().begin(), Min<T>());
00744 }
00745 return min(a.array());
00746 }
00747
00748 template<typename T>
00749 T max(const MArray<T>& a)
00750 {
00751 if (a.hasMask()) {
00752 return a.array().contiguousStorage() && a.mask().contiguousStorage() ?
00753 accumulateMasked<T>(a.array().cbegin(), a.array().cend(),
00754 a.mask().cbegin(), Max<T>()) :
00755 accumulateMasked<T>(a.array().begin(), a.array().end(),
00756 a.mask().begin(), Max<T>());
00757 }
00758 return max(a.array());
00759 }
00760
00761 template<typename T>
00762 T mean(const MArray<T>& a)
00763 {
00764 Int64 nv = a.nvalid();
00765 if (nv == 0) return T();
00766 if (! a.hasMask()) return mean(a.array());
00767 return T(sum(a) / (1.0*nv));
00768 }
00769
00770 template<typename T>
00771 T variance(const MArray<T>& a, T mean)
00772 {
00773 Int64 nv = a.nvalid();
00774 if (nv < 2) return T();
00775 if (! a.hasMask()) return variance(a.array(), mean);
00776 T sum = a.array().contiguousStorage() && a.mask().contiguousStorage() ?
00777 accumulateMasked<T>(a.array().cbegin(), a.array().cend(),
00778 a.mask().cbegin(), T(), SumSqrDiff<T>(mean)) :
00779 accumulateMasked<T>(a.array().begin(), a.array().end(),
00780 a.mask().begin(), T(), SumSqrDiff<T>(mean));
00781 return T(sum / (1.0*nv - 1));
00782 }
00783
00784 template<typename T>
00785 T variance(const MArray<T>& a)
00786 {
00787 return variance(a, mean(a));
00788 }
00789
00790 template<typename T>
00791 T stddev(const MArray<T>& a)
00792 {
00793 return sqrt(variance(a));
00794 }
00795
00796 template<typename T>
00797 T stddev(const MArray<T>& a, T mean)
00798 {
00799 return sqrt(variance(a, mean));
00800 }
00801
00802 template<typename T>
00803 T avdev(const MArray<T>& a, T mean)
00804 {
00805 Int64 nv = a.nvalid();
00806 if (nv == 0) return T();
00807 if (! a.hasMask()) return avdev(a.array(), mean);
00808 T sum = a.array().contiguousStorage() && a.mask().contiguousStorage() ?
00809 accumulateMasked<T>(a.array().cbegin(), a.array().cend(),
00810 a.mask().cbegin(), T(), SumAbsDiff<T>(mean)) :
00811 accumulateMasked<T>(a.array().begin(), a.array().end(),
00812 a.mask().begin(), T(), SumAbsDiff<T>(mean));
00813 return T(sum / (1.0*nv));
00814 }
00815
00816 template<typename T>
00817 T avdev(const MArray<T>& a)
00818 {
00819 return avdev(a, mean(a));
00820 }
00821
00822 template<typename T>
00823 T rms(const MArray<T>& a)
00824 {
00825 Int64 nv = a.nvalid();
00826 if (nv == 0) return T();
00827 if (! a.hasMask()) return rms(a.array());
00828 T sum = a.array().contiguousStorage() && a.mask().contiguousStorage() ?
00829 accumulateMasked<T>(a.array().cbegin(), a.array().cend(),
00830 a.mask().cbegin(), T(), SumSqr<T>()) :
00831 accumulateMasked<T>(a.array().begin(), a.array().end(),
00832 a.mask().begin(), T(), SumSqr<T>());
00833 return T(sqrt(sum / (1.0*nv)));
00834 }
00835
00836 template<typename T>
00837 T median(const MArray<T> &a, Bool sorted, Bool takeEvenMean,
00838 Bool inPlace=False)
00839 {
00840
00841 if (a.empty()) return T();
00842 if (! a.hasMask()) return median(a.array(), sorted, takeEvenMean, inPlace);
00843 Block<T> buf(a.size());
00844 Int64 nv = a.flatten (buf.storage(), buf.size());
00845 if (nv == 0) return T();
00846 Array<T> arr(IPosition(1, nv), buf.storage(), SHARE);
00847
00848 return median (arr, sorted, takeEvenMean, True);
00849 }
00850 template<typename T>
00851 inline T median(const MArray<T> &a)
00852 { return median (a, False, (a.size() <= 100), False); }
00853 template<typename T>
00854 inline T median(const MArray<T> &a, Bool sorted)
00855 { return median (a, sorted, (a.nelements() <= 100), False); }
00856 template<typename T>
00857 inline T medianInPlace(const MArray<T> &a, Bool sorted = False)
00858 { return median (a, sorted, (a.nelements() <= 100), True); }
00859
00860
00861
00862
00863
00864
00865 template<typename T>
00866 T fractile(const MArray<T> &a, Float fraction, Bool sorted=False,
00867 Bool inPlace=False)
00868 {
00869
00870 if (a.empty()) return T();
00871 if (! a.hasMask()) return fractile(a.array(), fraction, sorted, inPlace);
00872 Block<T> buf(a.size());
00873 Int64 nv = a.flatten (buf.storage(), a.size());
00874 if (nv == 0) return T();
00875 Array<T> arr(IPosition(1, nv), buf.storage(), SHARE);
00876 return fractile (arr, fraction, sorted, True);
00877 }
00878
00879
00880
00881
00882 template<typename T>
00883 MArray<T> partialSums (const MArray<T>& a,
00884 const IPosition& collapseAxes)
00885 {
00886 if (a.isNull()) {
00887 return MArray<T>();
00888 } else if (! a.hasMask()) {
00889 return MArray<T>(partialSums (a.array(), collapseAxes));
00890 }
00891 return partialArrayMath (a, collapseAxes, MSumFunc<T>());
00892 }
00893 template<typename T>
00894 MArray<T> partialSumSqrs (const MArray<T>& a,
00895 const IPosition& collapseAxes)
00896 {
00897 if (a.isNull()) {
00898 return MArray<T>();
00899 } else if (! a.hasMask()) {
00900 return MArray<T>(partialArrayMath (a.array(), collapseAxes,
00901 SumSqrFunc<T>()));
00902 }
00903 return partialArrayMath (a, collapseAxes, MSumSqrFunc<T>());
00904 }
00905 template<typename T>
00906 MArray<T> partialProducts (const MArray<T>& a,
00907 const IPosition& collapseAxes)
00908 {
00909 if (a.isNull()) {
00910 return MArray<T>();
00911 } else if (! a.hasMask()) {
00912 return MArray<T>(partialProducts (a.array(), collapseAxes));
00913 }
00914 return partialArrayMath (a, collapseAxes, MProductFunc<T>());
00915 }
00916 template<typename T>
00917 MArray<T> partialMins (const MArray<T>& a,
00918 const IPosition& collapseAxes)
00919 {
00920 if (a.isNull()) {
00921 return MArray<T>();
00922 } else if (! a.hasMask()) {
00923 return MArray<T>(partialMins (a.array(), collapseAxes));
00924 }
00925 return partialArrayMath (a, collapseAxes, MMinFunc<T>());
00926 }
00927 template<typename T>
00928 MArray<T> partialMaxs (const MArray<T>& a,
00929 const IPosition& collapseAxes)
00930 {
00931 if (a.isNull()) {
00932 return MArray<T>();
00933 } else if (! a.hasMask()) {
00934 return MArray<T>(partialMaxs (a.array(), collapseAxes));
00935 }
00936 return partialArrayMath (a, collapseAxes, MMaxFunc<T>());
00937 }
00938 template<typename T>
00939 MArray<T> partialMeans (const MArray<T>& a,
00940 const IPosition& collapseAxes)
00941 {
00942 if (a.isNull()) {
00943 return MArray<T>();
00944 } else if (! a.hasMask()) {
00945 return MArray<T>(partialMeans (a.array(), collapseAxes));
00946 }
00947 return partialArrayMath (a, collapseAxes, MMeanFunc<T>());
00948 }
00949 template<typename T>
00950 MArray<T> partialVariances (const MArray<T>& a,
00951 const IPosition& collapseAxes)
00952 {
00953 if (a.isNull()) {
00954 return MArray<T>();
00955 } else if (! a.hasMask()) {
00956 return MArray<T>(partialVariances (a.array(), collapseAxes));
00957 }
00958 return partialArrayMath (a, collapseAxes, MVarianceFunc<T>());
00959 }
00960 template<typename T>
00961 MArray<T> partialStddevs (const MArray<T>& a,
00962 const IPosition& collapseAxes)
00963 {
00964 if (a.isNull()) {
00965 return MArray<T>();
00966 } else if (! a.hasMask()) {
00967 return MArray<T>(partialStddevs (a.array(), collapseAxes));
00968 }
00969 return partialArrayMath (a, collapseAxes, MStddevFunc<T>());
00970 }
00971 template<typename T>
00972 MArray<T> partialAvdevs (const MArray<T>& a,
00973 const IPosition& collapseAxes)
00974 {
00975 if (a.isNull()) {
00976 return MArray<T>();
00977 } else if (! a.hasMask()) {
00978 return MArray<T>(partialAvdevs (a.array(), collapseAxes));
00979 }
00980 return partialArrayMath (a, collapseAxes, MAvdevFunc<T>());
00981 }
00982 template<typename T>
00983 MArray<T> partialRmss (const MArray<T>& a,
00984 const IPosition& collapseAxes)
00985 {
00986 if (a.isNull()) {
00987 return MArray<T>();
00988 } else if (! a.hasMask()) {
00989 return MArray<T>(partialRmss (a.array(), collapseAxes));
00990 }
00991 return partialArrayMath (a, collapseAxes, MRmsFunc<T>());
00992 }
00993 template<typename T>
00994 MArray<T> partialMedians (const MArray<T>& a,
00995 const IPosition& collapseAxes,
00996 Bool takeEvenMean=False,
00997 Bool inPlace=False)
00998 {
00999 if (a.isNull()) {
01000 return MArray<T>();
01001 } else if (! a.hasMask()) {
01002 return MArray<T>(partialMedians (a.array(), collapseAxes,
01003 takeEvenMean, inPlace));
01004 }
01005 return partialArrayMath (a, collapseAxes,
01006 MMedianFunc<T>(False, takeEvenMean, inPlace));
01007 }
01008 template<typename T>
01009 MArray<T> partialFractiles (const MArray<T>& a,
01010 const IPosition& collapseAxes,
01011 Float fraction,
01012 Bool inPlace=False)
01013 {
01014 if (a.isNull()) {
01015 return MArray<T>();
01016 } else if (! a.hasMask()) {
01017 return MArray<T>(partialFractiles (a.array(), collapseAxes,
01018 fraction, inPlace));
01019 }
01020 return partialArrayMath (a, collapseAxes,
01021 MFractileFunc<T>(fraction, False, inPlace));
01022 }
01023
01024
01025
01026
01027 template<typename T>
01028 MArray<T> slidingSums (const MArray<T>& a,
01029 const IPosition& halfBoxSize, Bool fillEdge=True)
01030 {
01031 if (a.isNull()) {
01032 return MArray<T>();
01033 } else if (! a.hasMask()) {
01034 return MArray<T>(slidingArrayMath (a.array(), halfBoxSize,
01035 SumFunc<T>(), fillEdge));
01036 }
01037 return slidingArrayMath (a, halfBoxSize, MSumFunc<T>(), fillEdge);
01038 }
01039 template<typename T>
01040 MArray<T> slidingSumSqrs (const MArray<T>& a,
01041 const IPosition& halfBoxSize, Bool fillEdge=True)
01042 {
01043 if (a.isNull()) {
01044 return MArray<T>();
01045 } else if (! a.hasMask()) {
01046 return MArray<T>(slidingArrayMath (a.array(), halfBoxSize,
01047 SumSqrFunc<T>(), fillEdge));
01048 }
01049 return slidingArrayMath (a, halfBoxSize, MSumSqrFunc<T>(), fillEdge);
01050 }
01051 template<typename T>
01052 MArray<T> slidingProducts (const MArray<T>& a,
01053 const IPosition& halfBoxSize, Bool fillEdge=True)
01054 {
01055 if (a.isNull()) {
01056 return MArray<T>();
01057 } else if (! a.hasMask()) {
01058 return MArray<T>(slidingArrayMath (a.array(), halfBoxSize,
01059 ProductFunc<T>(), fillEdge));
01060 }
01061 return slidingArrayMath (a, halfBoxSize, MProductFunc<T>(), fillEdge);
01062 }
01063 template<typename T>
01064 MArray<T> slidingMins (const MArray<T>& a,
01065 const IPosition& halfBoxSize, Bool fillEdge=True)
01066 {
01067 if (a.isNull()) {
01068 return MArray<T>();
01069 } else if (! a.hasMask()) {
01070 return MArray<T>(slidingArrayMath (a.array(), halfBoxSize,
01071 MinFunc<T>(), fillEdge));
01072 }
01073 return slidingArrayMath (a, halfBoxSize, MMinFunc<T>(), fillEdge);
01074 }
01075 template<typename T>
01076 MArray<T> slidingMaxs (const MArray<T>& a,
01077 const IPosition& halfBoxSize, Bool fillEdge=True)
01078 {
01079 if (a.isNull()) {
01080 return MArray<T>();
01081 } else if (! a.hasMask()) {
01082 return MArray<T>(slidingArrayMath (a.array(), halfBoxSize,
01083 MaxFunc<T>(), fillEdge));
01084 }
01085 return slidingArrayMath (a, halfBoxSize, MMaxFunc<T>(), fillEdge);
01086 }
01087 template<typename T>
01088 MArray<T> slidingMeans (const MArray<T>& a,
01089 const IPosition& halfBoxSize, Bool fillEdge=True)
01090 {
01091 if (a.isNull()) {
01092 return MArray<T>();
01093 } else if (! a.hasMask()) {
01094 return MArray<T>(slidingArrayMath (a.array(), halfBoxSize,
01095 MeanFunc<T>(), fillEdge));
01096 }
01097 return slidingArrayMath (a, halfBoxSize, MMeanFunc<T>(), fillEdge);
01098 }
01099 template<typename T>
01100 MArray<T> slidingVariances (const MArray<T>& a,
01101 const IPosition& halfBoxSize, Bool fillEdge=True)
01102 {
01103 if (a.isNull()) {
01104 return MArray<T>();
01105 } else if (! a.hasMask()) {
01106 return MArray<T>(slidingArrayMath (a.array(), halfBoxSize,
01107 VarianceFunc<T>(), fillEdge));
01108 }
01109 return slidingArrayMath (a, halfBoxSize, MVarianceFunc<T>(), fillEdge);
01110 }
01111 template<typename T>
01112 MArray<T> slidingStddevs (const MArray<T>& a,
01113 const IPosition& halfBoxSize, Bool fillEdge=True)
01114 {
01115 if (a.isNull()) {
01116 return MArray<T>();
01117 } else if (! a.hasMask()) {
01118 return MArray<T>(slidingArrayMath (a.array(), halfBoxSize,
01119 StddevFunc<T>(), fillEdge));
01120 }
01121 return slidingArrayMath (a, halfBoxSize, MStddevFunc<T>(), fillEdge);
01122 }
01123 template<typename T>
01124 MArray<T> slidingAvdevs (const MArray<T>& a,
01125 const IPosition& halfBoxSize, Bool fillEdge=True)
01126 {
01127 if (a.isNull()) {
01128 return MArray<T>();
01129 } else if (! a.hasMask()) {
01130 return MArray<T>(slidingArrayMath (a.array(), halfBoxSize,
01131 AvdevFunc<T>(), fillEdge));
01132 }
01133 return slidingArrayMath (a, halfBoxSize, MAvdevFunc<T>(), fillEdge);
01134 }
01135 template<typename T>
01136 MArray<T> slidingRmss (const MArray<T>& a,
01137 const IPosition& halfBoxSize, Bool fillEdge=True)
01138 {
01139 if (a.isNull()) {
01140 return MArray<T>();
01141 } else if (! a.hasMask()) {
01142 return MArray<T>(slidingArrayMath (a.array(), halfBoxSize,
01143 RmsFunc<T>(), fillEdge));
01144 }
01145 return slidingArrayMath (a, halfBoxSize, MRmsFunc<T>(), fillEdge);
01146 }
01147 template<typename T>
01148 MArray<T> slidingMedians (const MArray<T>& a,
01149 const IPosition& halfBoxSize,
01150 Bool takeEvenMean=False,
01151 Bool inPlace=False,
01152 Bool fillEdge=True)
01153 {
01154 if (a.isNull()) {
01155 return MArray<T>();
01156 } else if (! a.hasMask()) {
01157 return MArray<T>(slidingArrayMath (a.array(), halfBoxSize,
01158 MedianFunc<T>(False, takeEvenMean,
01159 inPlace),
01160 fillEdge));
01161 }
01162 return slidingArrayMath (a, halfBoxSize,
01163 MMedianFunc<T>(False, takeEvenMean, inPlace),
01164 fillEdge);
01165 }
01166 template<typename T>
01167 MArray<T> slidingFractiles (const MArray<T>& a,
01168 const IPosition& halfBoxSize,
01169 Float fraction,
01170 Bool inPlace=False,
01171 Bool fillEdge=True)
01172 {
01173 if (a.isNull()) {
01174 return MArray<T>();
01175 } else if (! a.hasMask()) {
01176 return MArray<T>(slidingArrayMath (a.array(), halfBoxSize,
01177 FractileFunc<T>(fraction, False,
01178 inPlace),
01179 fillEdge));
01180 }
01181 return slidingArrayMath (a, halfBoxSize,
01182 MFractileFunc<T>(fraction, False, inPlace),
01183 fillEdge);
01184 }
01185
01186
01187
01188
01189 template<typename T>
01190 MArray<T> boxedSums (const MArray<T>& a,
01191 const IPosition& boxSize)
01192 {
01193 if (a.isNull()) {
01194 return MArray<T>();
01195 } else if (! a.hasMask()) {
01196 return MArray<T>(boxedArrayMath (a.array(), boxSize, SumFunc<T>()));
01197 }
01198 return boxedArrayMath (a, boxSize, MSumFunc<T>());
01199 }
01200 template<typename T>
01201 MArray<T> boxedSumSqrs (const MArray<T>& a,
01202 const IPosition& boxSize)
01203 {
01204 if (a.isNull()) {
01205 return MArray<T>();
01206 } else if (! a.hasMask()) {
01207 return MArray<T>(boxedArrayMath (a.array(), boxSize, SumSqrFunc<T>()));
01208 }
01209 return boxedArrayMath (a, boxSize, MSumSqrFunc<T>());
01210 }
01211 template<typename T>
01212 MArray<T> boxedProducts (const MArray<T>& a,
01213 const IPosition& boxSize)
01214 {
01215 if (a.isNull()) {
01216 return MArray<T>();
01217 } else if (! a.hasMask()) {
01218 return MArray<T>(boxedArrayMath (a.array(), boxSize, ProductFunc<T>()));
01219 }
01220 return boxedArrayMath (a, boxSize, MProductFunc<T>());
01221 }
01222 template<typename T>
01223 MArray<T> boxedMins (const MArray<T>& a,
01224 const IPosition& boxSize)
01225 {
01226 if (a.isNull()) {
01227 return MArray<T>();
01228 } else if (! a.hasMask()) {
01229 return MArray<T>(boxedArrayMath (a.array(), boxSize, MinFunc<T>()));
01230 }
01231 return boxedArrayMath (a, boxSize, MMinFunc<T>());
01232 }
01233 template<typename T>
01234 MArray<T> boxedMaxs (const MArray<T>& a,
01235 const IPosition& boxSize)
01236 {
01237 if (a.isNull()) {
01238 return MArray<T>();
01239 } else if (! a.hasMask()) {
01240 return MArray<T>(boxedArrayMath (a.array(), boxSize, MaxFunc<T>()));
01241 }
01242 return boxedArrayMath (a, boxSize, MMaxFunc<T>());
01243 }
01244 template<typename T>
01245 MArray<T> boxedMeans (const MArray<T>& a,
01246 const IPosition& boxSize)
01247 {
01248 if (a.isNull()) {
01249 return MArray<T>();
01250 } else if (! a.hasMask()) {
01251 return MArray<T>(boxedArrayMath (a.array(), boxSize, MeanFunc<T>()));
01252 }
01253 return boxedArrayMath (a, boxSize, MMeanFunc<T>());
01254 }
01255 template<typename T>
01256 MArray<T> boxedVariances (const MArray<T>& a,
01257 const IPosition& boxSize)
01258 {
01259 if (a.isNull()) {
01260 return MArray<T>();
01261 } else if (! a.hasMask()) {
01262 return MArray<T>(boxedArrayMath (a.array(), boxSize, VarianceFunc<T>()));
01263 }
01264 return boxedArrayMath (a, boxSize, MVarianceFunc<T>());
01265 }
01266 template<typename T>
01267 MArray<T> boxedStddevs (const MArray<T>& a,
01268 const IPosition& boxSize)
01269 {
01270 if (a.isNull()) {
01271 return MArray<T>();
01272 } else if (! a.hasMask()) {
01273 return MArray<T>(boxedArrayMath (a.array(), boxSize, StddevFunc<T>()));
01274 }
01275 return boxedArrayMath (a, boxSize, MStddevFunc<T>());
01276 }
01277 template<typename T>
01278 MArray<T> boxedAvdevs (const MArray<T>& a,
01279 const IPosition& boxSize)
01280 {
01281 if (a.isNull()) {
01282 return MArray<T>();
01283 } else if (! a.hasMask()) {
01284 return MArray<T>(boxedArrayMath (a.array(), boxSize, AvdevFunc<T>()));
01285 }
01286 return boxedArrayMath (a, boxSize, MAvdevFunc<T>());
01287 }
01288 template<typename T>
01289 MArray<T> boxedRmss (const MArray<T>& a,
01290 const IPosition& boxSize)
01291 {
01292 if (a.isNull()) {
01293 return MArray<T>();
01294 } else if (! a.hasMask()) {
01295 return MArray<T>(boxedArrayMath (a.array(), boxSize, RmsFunc<T>()));
01296 }
01297 return boxedArrayMath (a, boxSize, MRmsFunc<T>());
01298 }
01299 template<typename T>
01300 MArray<T> boxedMedians (const MArray<T>& a,
01301 const IPosition& boxSize,
01302 Bool takeEvenMean=False,
01303 Bool inPlace=False)
01304 {
01305 if (a.isNull()) {
01306 return MArray<T>();
01307 } else if (! a.hasMask()) {
01308 return MArray<T>(boxedArrayMath (a.array(), boxSize,
01309 MedianFunc<T>(False, takeEvenMean,
01310 inPlace)));
01311 }
01312 return boxedArrayMath (a, boxSize,
01313 MMedianFunc<T>(False, takeEvenMean, inPlace));
01314 }
01315 template<typename T>
01316 MArray<T> boxedFractiles (const MArray<T>& a,
01317 const IPosition& boxSize,
01318 Float fraction,
01319 Bool inPlace=False)
01320 {
01321 if (a.isNull()) {
01322 return MArray<T>();
01323 } else if (! a.hasMask()) {
01324 return MArray<T>(boxedArrayMath (a.array(), boxSize,
01325 FractileFunc<T>(fraction, False,
01326 inPlace)));
01327 }
01328 return boxedArrayMath (a, boxSize,
01329 MFractileFunc<T>(fraction, False, inPlace));
01330 }
01331
01332
01333
01334
01335 }
01336
01337 #endif