source: trunk/src/Utils/getRobustStats.cc

Last change on this file was 1393, checked in by MatthewWhiting, 10 years ago

A large changeset that moves all use of bool arrays (ie. bool *) to std::vector<bool>. This will be a bit safer, plus potentially cheaper in memory usage. Interfaces to all stats functions with masks have changed accordingly, as well as the Gaussian smoothing functions and some spectral utility functions.

File size: 26.4 KB
RevLine 
[301]1// -----------------------------------------------------------------------
2// getStats.cc: Basic functions to calculate statistical parameters
3//              such as mean, median, rms, madfm, min, max.
4// -----------------------------------------------------------------------
5// Copyright (C) 2006, Matthew Whiting, ATNF
6//
7// This program is free software; you can redistribute it and/or modify it
8// under the terms of the GNU General Public License as published by the
9// Free Software Foundation; either version 2 of the License, or (at your
10// option) any later version.
11//
12// Duchamp is distributed in the hope that it will be useful, but WITHOUT
13// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15// for more details.
16//
17// You should have received a copy of the GNU General Public License
18// along with Duchamp; if not, write to the Free Software Foundation,
19// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
20//
21// Correspondence concerning Duchamp may be directed to:
22//    Internet email: Matthew.Whiting [at] atnf.csiro.au
23//    Postal address: Dr. Matthew Whiting
24//                    Australia Telescope National Facility, CSIRO
25//                    PO Box 76
26//                    Epping NSW 1710
27//                    AUSTRALIA
28// -----------------------------------------------------------------------
[3]29#include <iostream>
[204]30#include <algorithm>
[3]31#include <math.h>
[393]32#include <duchamp/Utils/utils.hh>
[3]33
[848]34template <class T> T findMedian(T *array, size_t size, bool changeArray)
[70]35{
[528]36  /// @details
37  /// Find the median value of an array of numbers. Type independent.
38  /// \param array The array of numbers.
39  /// \param size The length of the array.
[646]40  /// \param changeArray [false] Whether to use the provided array in calculations. If true, the input array will be altered (ie. the order of elements will be changed).
[528]41  /// \return The median value of the array, returned as the same type as the array.
[646]42  T *newarray;
43  if(changeArray) newarray = array;
44  else{
45    newarray = new T[size];
[848]46    for(size_t i=0;i<size;i++) newarray[i] = array[i];
[646]47  }
[190]48  T median;
[843]49  bool isEven = ((size%2)==0);
[646]50  std::nth_element(newarray,newarray+size/2,newarray+size);
51  median = newarray[size/2];
[657]52  if(isEven){
[646]53    std::nth_element(newarray,newarray+size/2-1,newarray+size);
54    median += newarray[size/2-1];
[699]55    median /= T(2);
[646]56  }
57  if(!changeArray) delete [] newarray;
[53]58  return median;
59}
[848]60template int findMedian<int>(int *array, size_t size, bool changeArray);
61template long findMedian<long>(long *array, size_t size, bool changeArray);
62template float findMedian<float>(float *array, size_t size, bool changeArray);
63template double findMedian<double>(double *array, size_t size, bool changeArray);
[190]64//--------------------------------------------------------------------
[53]65
[849]66template <class T> T findMedianDiff(T *first, T *second, size_t size)
67{
68  /// @details
69  /// Find the median value of an array of numbers. Type independent.
70  /// \param array The array of numbers.
71  /// \param size The length of the array.
72  /// \param changeArray [false] Whether to use the provided array in calculations. If true, the input array will be altered (ie. the order of elements will be changed).
73  /// \return The median value of the array, returned as the same type as the array.
74  T *newarray = new T[size];
75  for(size_t i=0;i<size;i++) newarray[i] = first[i]-second[i];
76 
77  T median;
78  bool isEven = ((size%2)==0);
79  std::nth_element(newarray,newarray+size/2,newarray+size);
80  median = newarray[size/2];
81  if(isEven){
82    std::nth_element(newarray,newarray+size/2-1,newarray+size);
83    median += newarray[size/2-1];
84    median /= T(2);
85  }
86  delete [] newarray;
87  return median;
88}
89template int findMedianDiff<int>(int *first, int *second, size_t size);
90template long findMedianDiff<long>(long *first, long *second, size_t size);
91template float findMedianDiff<float>(float *first, float *second, size_t size);
92template double findMedianDiff<double>(double *first, double *second, size_t size);
93//--------------------------------------------------------------------
94
[1393]95template <class T> T findMedian(T *array, std::vector<bool> mask, size_t size)
[53]96{
[528]97  /// @details
[907]98  /// Find the median value of an array of numbers. Type independent. This will create a new array that gets partially sorted.
[848]99  /// \param array The array of numbers.
[907]100  /// \param mask Whether a given array value should be included in calculations. NB: mask=true implies use this array value.
[848]101  /// \param size The length of the array.
102  /// \return The median value of the array, returned as the same type as the array.
103
104  int goodSize=0,ct=0;
105  for(size_t i=0;i<size;i++) if(mask[i]) goodSize++;
106  T *newarray = new T[goodSize];
107  for(size_t i=0;i<size;i++) {
108    if(mask[i]) newarray[ct++] = array[i];
109  }
110  T median;
111  bool isEven = ((goodSize%2)==0);
112  std::nth_element(newarray,newarray+goodSize/2,newarray+goodSize);
113  median = newarray[goodSize/2];
114  if(isEven){
115    std::nth_element(newarray,newarray+goodSize/2-1,newarray+goodSize);
116    median += newarray[goodSize/2-1];
117    median /= T(2);
118  }
119  delete [] newarray;
120  return median;
121}
[1393]122template int findMedian<int>(int *array, std::vector<bool> mask, size_t size);
123template long findMedian<long>(long *array, std::vector<bool> mask, size_t size);
124template float findMedian<float>(float *array, std::vector<bool> mask, size_t size);
125template double findMedian<double>(double *array, std::vector<bool> mask, size_t size);
[848]126//--------------------------------------------------------------------
127
[1393]128template <class T> T findMedianDiff(T *first, T *second, std::vector<bool> mask, size_t size)
[849]129{
130  /// @details
131  /// Find the median value of an array of numbers. Type independent.
132  /// \param array The array of numbers.
133  /// \param size The length of the array.
134  /// \param changeArray [false] Whether to use the provided array in calculations. If true, the input array will be altered (ie. the order of elements will be changed).
135  /// \return The median value of the array, returned as the same type as the array.
136  int goodSize=0,ct=0;
137  for(size_t i=0;i<size;i++) if(mask[i]) goodSize++;
138  T *newarray = new T[goodSize];
139  for(size_t i=0;i<size;i++)
140    if(mask[i]) newarray[ct++] = first[i]-second[i];
141 
142  T median=0;
143  bool isEven = ((goodSize%2)==0);
144  std::nth_element(newarray,newarray+goodSize/2,newarray+goodSize);
145  median = newarray[goodSize/2];
146  if(isEven){
147    std::nth_element(newarray,newarray+goodSize/2-1,newarray+goodSize);
148    median += newarray[goodSize/2-1];
149    median /= T(2);
150  }
151  delete [] newarray;
152  return median;
153}
[1393]154template int findMedianDiff<int>(int *first, int *second, std::vector<bool> mask, size_t size);
155template long findMedianDiff<long>(long *first, long *second, std::vector<bool> mask, size_t size);
156template float findMedianDiff<float>(float *first, float *second, std::vector<bool> mask, size_t size);
157template double findMedianDiff<double>(double *first, double *second, std::vector<bool> mask, size_t size);
[849]158//--------------------------------------------------------------------
159
[848]160template <class T> T findMADFM(T *array, size_t size, bool changeArray)
161{
162  /// @details
[528]163  /// Find the median absolute deviation from the median value of an
164  /// array of numbers. Type independent.
165  ///
166  /// \param array The array of numbers.
167  /// \param size The length of the array.
[646]168  /// \param changeArray [false] Whether to use the provided array in calculations. If true, the input array will be altered - both the order and values of the elements will be changed.
[528]169  /// \return The median absolute deviation from the median value of
170  /// the array, returned as the same type as the array.
[646]171  T *newarray;
172  if(changeArray) newarray = array;
173  else newarray = new T[size];
174
175  T median = findMedian<T>(array,size,changeArray);
[190]176  T madfm;
[843]177  bool isEven = ((size%2)==0);
[848]178  for(size_t i=0;i<size;i++) newarray[i] = absval(array[i]-median);
[646]179  std::nth_element(newarray,newarray+size/2,newarray+size);
180  madfm = newarray[size/2];
[657]181  if(isEven){
[646]182    std::nth_element(newarray,newarray+size/2-1,newarray+size);
183    madfm += newarray[size/2-1];
[699]184    madfm /= T(2);
[646]185  }
186  if(!changeArray) delete [] newarray;
[53]187  return madfm;
188}
[848]189template int findMADFM<int>(int *array, size_t size, bool changeArray);
190template long findMADFM<long>(long *array, size_t size, bool changeArray);
191template float findMADFM<float>(float *array, size_t size, bool changeArray);
192template double findMADFM<double>(double *array, size_t size, bool changeArray);
[190]193//--------------------------------------------------------------------
194
[849]195template <class T> T findMADFMDiff(T *first, T *second, size_t size)
196{
197  /// @details
198  /// Find the median absolute deviation from the median value of an
199  /// array of numbers. Type independent.
200  ///
201  /// \param array The array of numbers.
202  /// \param size The length of the array.
203  /// \param changeArray [false] Whether to use the provided array in calculations. If true, the input array will be altered - both the order and values of the elements will be changed.
204  /// \return The median absolute deviation from the median value of
205  /// the array, returned as the same type as the array.
206  T *newarray = new T[size];
207  T median = findMedianDiff<T>(first,second,size);
208  T madfm;
209  bool isEven = ((size%2)==0);
210  for(size_t i=0;i<size;i++) newarray[i] = absval(first[i]-second[i]-median);
211  std::nth_element(newarray,newarray+size/2,newarray+size);
212  madfm = newarray[size/2];
213  if(isEven){
214    std::nth_element(newarray,newarray+size/2-1,newarray+size);
215    madfm += newarray[size/2-1];
216    madfm /= T(2);
217  }
218  delete [] newarray;
219  return madfm;
220}
221template int findMADFMDiff<int>(int *first, int *second, size_t size);
222template long findMADFMDiff<long>(long *first, long *second, size_t size);
223template float findMADFMDiff<float>(float *first, float *second, size_t size);
224template double findMADFMDiff<double>(double *first, double *second, size_t size);
225//--------------------------------------------------------------------
226
[1393]227template <class T> T findMADFM(T *array, std::vector<bool> mask, size_t size)
[756]228{
229  /// @details
230  /// Find the median absolute deviation from the median value of an
[848]231  /// array of numbers. Type independent.
232  ///
233  /// \param array The array of numbers.
234  /// \param size The length of the array.
235  /// \param changeArray [false] Whether to use the provided array in calculations. If true, the input array will be altered - both the order and values of the elements will be changed.
236  /// \return The median absolute deviation from the median value of
237  /// the array, returned as the same type as the array.
238  T median = findMedian<T>(array,mask,size);
239  int goodSize=0,ct=0;
240  for(size_t i=0;i<size;i++) if(mask[i]) goodSize++;
241  T *newarray = new T[goodSize];
242  for(size_t i=0;i<size;i++)
243    if(mask[i]) newarray[ct++] = absval(array[i]-median);
244
245  T madfm;
246  bool isEven = ((goodSize%2)==0);
247  std::nth_element(newarray,newarray+goodSize/2,newarray+goodSize);
248  madfm = newarray[goodSize/2];
249  if(isEven){
250    std::nth_element(newarray,newarray+goodSize/2-1,newarray+goodSize);
251    madfm += newarray[goodSize/2-1];
252    madfm /= T(2);
253  }
254  delete [] newarray;
255  return madfm;
256}
[1393]257template int findMADFM<int>(int *array, std::vector<bool> mask, size_t size);
258template long findMADFM<long>(long *array, std::vector<bool> mask, size_t size);
259template float findMADFM<float>(float *array, std::vector<bool> mask, size_t size);
260template double findMADFM<double>(double *array, std::vector<bool> mask, size_t size);
[848]261//--------------------------------------------------------------------
262
[1393]263template <class T> T findMADFMDiff(T *first, T *second, std::vector<bool> mask, size_t size)
[849]264{
265  /// @details
266  /// Find the median absolute deviation from the median value of an
267  /// array of numbers. Type independent.
268  ///
269  /// \param array The array of numbers.
270  /// \param size The length of the array.
271  /// \param changeArray [false] Whether to use the provided array in calculations. If true, the input array will be altered - both the order and values of the elements will be changed.
272  /// \return The median absolute deviation from the median value of
273  /// the array, returned as the same type as the array.
274  T median = findMedianDiff<T>(first,second,mask,size);
275  int goodSize=0,ct=0;
276  for(size_t i=0;i<size;i++) if(mask[i]) goodSize++;
277  T *newarray = new T[goodSize];
278  for(size_t i=0;i<size;i++)
279    if(mask[i]) newarray[ct++] = absval(first[i]-second[i]-median);
280
281  T madfm;
282  bool isEven = ((goodSize%2)==0);
283  std::nth_element(newarray,newarray+goodSize/2,newarray+goodSize);
284  madfm = newarray[goodSize/2];
285  if(isEven){
286    std::nth_element(newarray,newarray+goodSize/2-1,newarray+goodSize);
287    madfm += newarray[goodSize/2-1];
288    madfm /= T(2);
289  }
290  delete [] newarray;
291  return madfm;
292}
[1393]293template int findMADFMDiff<int>(int *first, int *second, std::vector<bool> mask, size_t size);
294template long findMADFMDiff<long>(long *first, long *second, std::vector<bool> mask, size_t size);
295template float findMADFMDiff<float>(float *first, float *second, std::vector<bool> mask, size_t size);
296template double findMADFMDiff<double>(double *first, double *second, std::vector<bool> mask, size_t size);
[849]297//--------------------------------------------------------------------
298
[848]299template <class T> T findMADFM(T *array, size_t size, T median, bool changeArray)
300{
301  /// @details
302  /// Find the median absolute deviation from the median value of an
[756]303  /// array of numbers. Type independent. This version accepts a previously-
304  /// calculated median value.
305  ///
306  /// \param array The array of numbers.
307  /// \param size The length of the array.
308  /// \param median The median of the array.
309  /// \param changeArray [false] Whether to use the provided array in calculations. If true, the input array will be altered - both the order and values of the elements will be changed.
310  /// \return The median absolute deviation from the median value of
311  /// the array, returned as the same type as the array.
312  T *newarray;
313  if(changeArray) newarray = array;
314  else newarray = new T[size];
315
316  T madfm;
[843]317  bool isEven = ((size%2)==0);
[848]318  for(size_t i=0;i<size;i++) newarray[i] = absval(array[i]-median);
[756]319  std::nth_element(newarray,newarray+size/2,newarray+size);
320  madfm = newarray[size/2];
321  if(isEven){
322    std::nth_element(newarray,newarray+size/2-1,newarray+size);
323    madfm += newarray[size/2-1];
324    madfm /= T(2);
325  }
326  if(!changeArray) delete [] newarray;
327  return madfm;
328}
[848]329template int findMADFM<int>(int *array, size_t size, int median, bool changeArray);
330template long findMADFM<long>(long *array, size_t size, long median, bool changeArray);
331template float findMADFM<float>(float *array, size_t size, float median, bool changeArray);
332template double findMADFM<double>(double *array, size_t size, double median, bool changeArray);
[756]333//--------------------------------------------------------------------
334
[849]335template <class T> T findMADFMDiff(T *first, T *second, size_t size, T median)
336{
337  /// @details
338  /// Find the median absolute deviation from the median value of an
339  /// array of numbers. Type independent. This version accepts a previously-
340  /// calculated median value.
341  ///
342  /// \param array The array of numbers.
343  /// \param size The length of the array.
344  /// \param median The median of the array.
345  /// \param changeArray [false] Whether to use the provided array in calculations. If true, the input array will be altered - both the order and values of the elements will be changed.
346  /// \return The median absolute deviation from the median value of
347  /// the array, returned as the same type as the array.
348  T *newarray = new T[size];
349
350  T madfm;
351  bool isEven = ((size%2)==0);
352  for(size_t i=0;i<size;i++) newarray[i] = absval(first[i]-second[i]-median);
353  std::nth_element(newarray,newarray+size/2,newarray+size);
354  madfm = newarray[size/2];
355  if(isEven){
356    std::nth_element(newarray,newarray+size/2-1,newarray+size);
357    madfm += newarray[size/2-1];
358    madfm /= T(2);
359  }
360  delete [] newarray;
361  return madfm;
362}
363template int findMADFMDiff<int>(int *first, int *second, size_t size, int median);
364template long findMADFMDiff<long>(long *first, long *second, size_t size, long median);
365template float findMADFMDiff<float>(float *first, float *second, size_t size, float median);
366template double findMADFMDiff<double>(double *first, double *second, size_t size, double median);
367//--------------------------------------------------------------------
368
[1393]369template <class T> T findMADFM(T *array, std::vector<bool> mask, size_t size, T median)
[848]370{
371  /// @details
372  /// Find the median absolute deviation from the median value of an
373  /// array of numbers. Type independent. This version accepts a previously-
374  /// calculated median value.
375  ///
376  /// \param array The array of numbers.
377  /// \param size The length of the array.
378  /// \param median The median of the array.
379  /// \param changeArray [false] Whether to use the provided array in calculations. If true, the input array will be altered - both the order and values of the elements will be changed.
380  /// \return The median absolute deviation from the median value of
381  /// the array, returned as the same type as the array.
382  int goodSize=0,ct=0;
383  for(size_t i=0;i<size;i++) if(mask[i]) goodSize++;
384  T *newarray = new T[goodSize];
385  for(size_t i=0;i<size;i++){
386    if(mask[i]) newarray[ct++] = absval(array[i]-median);
387  }
388  T madfm;
389  bool isEven = ((goodSize%2)==0);
390  std::nth_element(newarray,newarray+goodSize/2,newarray+goodSize);
391  madfm = newarray[goodSize/2];
392  if(isEven){
393    std::nth_element(newarray,newarray+goodSize/2-1,newarray+goodSize);
394    madfm += newarray[goodSize/2-1];
395    madfm /= T(2);
396  }
397  delete [] newarray;
398  return madfm;
399}
[1393]400template int findMADFM<int>(int *array, std::vector<bool> mask, size_t size, int median);
401template long findMADFM<long>(long *array, std::vector<bool> mask, size_t size, long median);
402template float findMADFM<float>(float *array, std::vector<bool> mask, size_t size, float median);
403template double findMADFM<double>(double *array, std::vector<bool> mask, size_t size, double median);
[848]404//--------------------------------------------------------------------
405
[1393]406template <class T> T findMADFMDiff(T *first, T *second, std::vector<bool> mask, size_t size, T median)
[849]407{
408  /// @details
409  /// Find the median absolute deviation from the median value of an
410  /// array of numbers. Type independent. This version accepts a previously-
411  /// calculated median value.
412  ///
413  /// \param array The array of numbers.
414  /// \param size The length of the array.
415  /// \param median The median of the array.
416  /// \param changeArray [false] Whether to use the provided array in calculations. If true, the input array will be altered - both the order and values of the elements will be changed.
417  /// \return The median absolute deviation from the median value of
418  /// the array, returned as the same type as the array.
419  int goodSize=0,ct=0;
420  for(size_t i=0;i<size;i++) if(mask[i]) goodSize++;
421  T *newarray = new T[goodSize];
422  for(size_t i=0;i<size;i++){
423    if(mask[i]) newarray[ct++] = absval(first[i]-second[i]-median);
424  }
425  T madfm;
426  bool isEven = ((goodSize%2)==0);
427  std::nth_element(newarray,newarray+goodSize/2,newarray+goodSize);
428  madfm = newarray[goodSize/2];
429  if(isEven){
430    std::nth_element(newarray,newarray+goodSize/2-1,newarray+goodSize);
431    madfm += newarray[goodSize/2-1];
432    madfm /= T(2);
433  }
434  delete [] newarray;
435  return madfm;
436}
[1393]437template int findMADFMDiff<int>(int *first, int *second, std::vector<bool> mask, size_t size, int median);
438template long findMADFMDiff<long>(long *first, long *second, std::vector<bool> mask, size_t size, long median);
439template float findMADFMDiff<float>(float *first, float *second, std::vector<bool> mask, size_t size, float median);
440template double findMADFMDiff<double>(double *first, double *second, std::vector<bool> mask, size_t size, double median);
[849]441//--------------------------------------------------------------------
442
[848]443template <class T> void findMedianStats(T *array, size_t size,
[190]444                                        T &median, T &madfm)
[3]445{
[528]446  /// @details
447  /// Find the median and the median absolute deviation from the median
448  /// value of an array of numbers. Type independent.
449  ///
450  /// \param array The array of numbers.
451  /// \param size The length of the array.
452  /// \param median The median value of the array, returned as the same
453  /// type as the array.
454  /// \param madfm The median absolute deviation from the median value
455  /// of the array, returned as the same type as the array.
[190]456  if(size==0){
457    std::cerr << "Error in findMedianStats: zero sized array!\n";
458    return;
459  }
460  T *newarray = new T[size];
[848]461   for(size_t i=0;i<size;i++) newarray[i] = array[i];
[3]462
[889]463   median = findMedian<T>(newarray,size,true);
464   //   madfm = findMADFM<T>(newarray,size,true);
465   madfm = findMADFM<T>(newarray,size,median,true);
[3]466
467  delete [] newarray;
468}
[848]469template void findMedianStats<int>(int *array, size_t size,
[222]470                                      int &median, int &madfm);
[848]471template void findMedianStats<long>(long *array, size_t size,
[222]472                                       long &median, long &madfm);
[848]473template void findMedianStats<float>(float *array, size_t size,
[222]474                                        float &median, float &madfm);
[848]475template void findMedianStats<double>(double *array, size_t size,
[222]476                                         double &median, double &madfm);
[190]477//--------------------------------------------------------------------
478
[1393]479template <class T> void findMedianStats(T *array, size_t size, std::vector<bool> mask,
[190]480                                        T &median, T &madfm)
[3]481{
[528]482  /// @details
483  /// Find the median and the median absolute deviation from the median
484  /// value of a subset of an array of numbers. The subset is defined
485  /// by an array of bool variables. Type independent.
486  ///
487  /// \param array The array of numbers.
488  /// \param size The length of the array.
489  /// \param mask An array of the same length that says whether to
490  /// include each member of the array in the calculations. Only use
491  /// values where mask=true.
492  /// \param median The median value of the array, returned as the same
493  /// type as the array.
494  /// \param madfm The median absolute deviation from the median value
495  /// of the array, returned as the same type as the array.
496
[190]497  int goodSize=0;
[848]498  for(size_t i=0;i<size;i++) if(mask[i]) goodSize++;
[190]499  if(goodSize==0){
500    std::cerr << "Error in findMedianStats: no good values!\n";
501    return;
502  }
503  T *newarray = new T[goodSize];
[646]504
[648]505  goodSize=0;
[848]506  for(size_t i=0;i<size;i++) if(mask[i]) newarray[goodSize++] = array[i];
[889]507  median = findMedian<T>(newarray,goodSize,true);
508  //  madfm = findMADFM<T>(newarray,goodSize,true);
509  madfm = findMADFM<T>(newarray,goodSize,median,true);
[3]510
511  delete [] newarray;
512}
[1393]513template void findMedianStats<int>(int *array, size_t size, std::vector<bool> mask,
[222]514                                      int &median, int &madfm);
[1393]515template void findMedianStats<long>(long *array, size_t size, std::vector<bool> mask,
[222]516                                       long &median, long &madfm);
[1393]517template void findMedianStats<float>(float *array, size_t size, std::vector<bool> mask,
[222]518                                        float &median, float &madfm);
[1393]519template void findMedianStats<double>(double *array, size_t size, std::vector<bool> mask,
[222]520                                         double &median, double &madfm);
[190]521//--------------------------------------------------------------------
[3]522
[848]523template <class T> void findMedianStatsDiff(T *first, T *second, size_t size,
524                                            T &median, T &madfm)
[3]525{
[848]526  /// @details Find the median and the median absolute deviation from
527  /// the median value of the difference between two arrays of
528  /// numbers. Type independent. The difference is defined as first -
529  /// second.
[528]530  ///
[848]531  /// \param first The first array
532  /// \param second The second array
[528]533  /// \param size The length of the array.
534  /// \param median The median value of the array, returned as the same
535  /// type as the array.
536  /// \param madfm The median absolute deviation from the median value
537  /// of the array, returned as the same type as the array.
[275]538  if(size==0){
[848]539    std::cerr << "Error in findMedianStats: zero sized array!\n";
[275]540    return;
541  }
542  T *newarray = new T[size];
[848]543   for(size_t i=0;i<size;i++) newarray[i] = first[i]-second[i];
[275]544
[889]545   median = findMedian<T>(newarray,size,true);
546   //   madfm = findMADFM<T>(newarray,size,true);
547   madfm = findMADFM<T>(newarray,size,median,true);
[285]548
[275]549  delete [] newarray;
550}
[848]551template void findMedianStatsDiff<int>(int *first, int *second, size_t size,
552                                       int &median, int &madfm);
553template void findMedianStatsDiff<long>(long *first, long *second, size_t size,
554                                        long &median, long &madfm);
555template void findMedianStatsDiff<float>(float *first, float *second, size_t size,
556                                         float &median, float &madfm);
557template void findMedianStatsDiff<double>(double *first, double *second, size_t size,
558                                          double &median, double &madfm);
[275]559//--------------------------------------------------------------------
560
[1393]561template <class T> void findMedianStatsDiff(T *first, T *second, size_t size, std::vector<bool> mask,
[848]562                                            T &median, T &madfm)
[275]563{
[848]564  /// @details Find the median and the median absolute deviation from
565  /// the median value of the difference between two arrays of
566  /// numbers, where some elements are masked out. The mask is defined
567  /// by an array of bool variables. Type independent. The difference
568  /// is defined as first - second.
[528]569  ///
[848]570  /// \param first The first array
571  /// \param second The second array
[528]572  /// \param size The length of the array.
573  /// \param mask An array of the same length that says whether to
[848]574  /// include each member of the array in the calculations. Only use
575  /// values where mask=true.
[528]576  /// \param median The median value of the array, returned as the same
577  /// type as the array.
578  /// \param madfm The median absolute deviation from the median value
579  /// of the array, returned as the same type as the array.
580
[275]581  int goodSize=0;
[848]582  for(size_t i=0;i<size;i++) if(mask[i]) goodSize++;
[275]583  if(goodSize==0){
[848]584    std::cerr << "Error in findMedianStats: no good values!\n";
[275]585    return;
586  }
[848]587  T *newarray = new T[goodSize];
[275]588
589  goodSize=0;
[848]590  for(size_t i=0;i<size;i++) if(mask[i]) newarray[goodSize++] = first[i]-second[i];
[889]591  median = findMedian<T>(newarray,goodSize,true);
592  //  madfm = findMADFM<T>(newarray,goodSize,true);
593  madfm = findMADFM<T>(newarray,goodSize,median,true);
[275]594
[282]595  delete [] newarray;
[275]596}
[1393]597template void findMedianStatsDiff<int>(int *first, int *second, size_t size, std::vector<bool> mask,
[848]598                                       int &median, int &madfm);
[1393]599template void findMedianStatsDiff<long>(long *first, long *second, size_t size, std::vector<bool> mask,
[848]600                                        long &median, long &madfm);
[1393]601template void findMedianStatsDiff<float>(float *first, float *second, size_t size, std::vector<bool> mask,
[848]602                                         float &median, float &madfm);
[1393]603template void findMedianStatsDiff<double>(double *first, double *second, size_t size, std::vector<bool> mask,
[848]604                                          double &median, double &madfm);
[275]605//--------------------------------------------------------------------
[848]606 
Note: See TracBrowser for help on using the repository browser.