source: trunk/src/Utils/getRobustStats.cc @ 1391

Last change on this file since 1391 was 907, checked in by MatthewWhiting, 12 years ago

Ticket #134: enabling the specification of precision for decToDMS. Also setting that precision to be 1/10th of the pixel width, rounded down to the nearest multiple of 10. RA gets one additional decimal place.

File size: 25.9 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
[848]95template <class T> T findMedian(T *array, 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}
122template int findMedian<int>(int *array, bool *mask, size_t size);
123template long findMedian<long>(long *array, bool *mask, size_t size);
124template float findMedian<float>(float *array, bool *mask, size_t size);
125template double findMedian<double>(double *array, bool *mask, size_t size);
126//--------------------------------------------------------------------
127
[849]128template <class T> T findMedianDiff(T *first, T *second, bool *mask, size_t size)
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}
154template int findMedianDiff<int>(int *first, int *second, bool *mask, size_t size);
155template long findMedianDiff<long>(long *first, long *second, bool *mask, size_t size);
156template float findMedianDiff<float>(float *first, float *second, bool *mask, size_t size);
157template double findMedianDiff<double>(double *first, double *second, bool *mask, size_t size);
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
[848]227template <class T> T findMADFM(T *array, 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}
257template int findMADFM<int>(int *array, bool *mask, size_t size);
258template long findMADFM<long>(long *array, bool *mask, size_t size);
259template float findMADFM<float>(float *array, bool *mask, size_t size);
260template double findMADFM<double>(double *array, bool *mask, size_t size);
261//--------------------------------------------------------------------
262
[849]263template <class T> T findMADFMDiff(T *first, T *second, bool *mask, size_t size)
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}
293template int findMADFMDiff<int>(int *first, int *second, bool *mask, size_t size);
294template long findMADFMDiff<long>(long *first, long *second, bool *mask, size_t size);
295template float findMADFMDiff<float>(float *first, float *second, bool *mask, size_t size);
296template double findMADFMDiff<double>(double *first, double *second, bool *mask, size_t size);
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
[848]369template <class T> T findMADFM(T *array, bool *mask, size_t size, T median)
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}
400template int findMADFM<int>(int *array, bool *mask, size_t size, int median);
401template long findMADFM<long>(long *array, bool *mask, size_t size, long median);
402template float findMADFM<float>(float *array, bool *mask, size_t size, float median);
403template double findMADFM<double>(double *array, bool *mask, size_t size, double median);
404//--------------------------------------------------------------------
405
[849]406template <class T> T findMADFMDiff(T *first, T *second, bool *mask, size_t size, T median)
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}
437template int findMADFMDiff<int>(int *first, int *second, bool *mask, size_t size, int median);
438template long findMADFMDiff<long>(long *first, long *second, bool *mask, size_t size, long median);
439template float findMADFMDiff<float>(float *first, float *second, bool *mask, size_t size, float median);
440template double findMADFMDiff<double>(double *first, double *second, bool *mask, size_t size, double median);
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
[848]479template <class T> void findMedianStats(T *array, size_t size, 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}
[848]513template void findMedianStats<int>(int *array, size_t size, bool *mask,
[222]514                                      int &median, int &madfm);
[848]515template void findMedianStats<long>(long *array, size_t size, bool *mask,
[222]516                                       long &median, long &madfm);
[848]517template void findMedianStats<float>(float *array, size_t size, bool *mask,
[222]518                                        float &median, float &madfm);
[848]519template void findMedianStats<double>(double *array, size_t size, 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
[848]561template <class T> void findMedianStatsDiff(T *first, T *second, size_t size, bool *mask,
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}
[848]597template void findMedianStatsDiff<int>(int *first, int *second, size_t size, bool *mask,
598                                       int &median, int &madfm);
599template void findMedianStatsDiff<long>(long *first, long *second, size_t size, bool *mask,
600                                        long &median, long &madfm);
601template void findMedianStatsDiff<float>(float *first, float *second, size_t size, bool *mask,
602                                         float &median, float &madfm);
603template void findMedianStatsDiff<double>(double *first, double *second, size_t size, bool *mask,
604                                          double &median, double &madfm);
[275]605//--------------------------------------------------------------------
[848]606 
Note: See TracBrowser for help on using the repository browser.