source: trunk/src/Utils/Statistics.cc @ 321

Last change on this file since 321 was 301, checked in by Matthew Whiting, 17 years ago

Mostly adding the distribution text to the start of files, with a few additional comments added too.

File size: 12.1 KB
Line 
1// -----------------------------------------------------------------------
2// Statistics.cc: Member functions for the templated StatsContainer
3//                class.
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// -----------------------------------------------------------------------
29#include <iostream>
30#include <Utils/Statistics.hh>
31#include <Utils/utils.hh>
32
33namespace Statistics
34{
35
36  template <class T>
37  float madfmToSigma(T madfm){
38    return float(madfm)/correctionFactor;
39  }
40  template float madfmToSigma<int>(int madfm);
41  template float madfmToSigma<long>(long madfm);
42  template float madfmToSigma<float>(float madfm);
43  template float madfmToSigma<double>(double madfm);
44
45  //--------------------------------------------------------------------
46  template <class T>
47  float sigmaToMADFM(float sigma){
48    return float(sigma)*correctionFactor;
49  }
50  //--------------------------------------------------------------------
51  //--------------------------------------------------------------------
52
53  template <class Type>
54  StatsContainer<Type>::StatsContainer(const StatsContainer<Type>& s)
55  {
56    /**
57     *  The copy constructor for the StatsContainer class.
58     */
59
60    this->defined    = s.defined;
61    this->mean       = s.mean;
62    this->stddev     = s.stddev;
63    this->median     = s.median;
64    this->madfm      = s.madfm;
65    this->threshold  = s.threshold;
66    this->pThreshold = s.pThreshold;
67    this->useRobust  = s.useRobust;
68    this->useFDR     = s.useFDR;
69  }
70  template StatsContainer<int>::StatsContainer(const StatsContainer<int>& s);
71  template StatsContainer<long>::StatsContainer(const StatsContainer<long>& s);
72  template StatsContainer<float>::StatsContainer(const StatsContainer<float>& s);
73  template StatsContainer<double>::StatsContainer(const StatsContainer<double>& s);
74  //--------------------------------------------------------------------
75
76  template <class Type>
77  StatsContainer<Type>&
78  StatsContainer<Type>::operator= (const StatsContainer<Type>& s)
79  {
80    /**
81     *  The assignment operator for the StatsContainer class.
82     */
83
84    if(this == &s) return *this;
85    this->defined    = s.defined;
86    this->mean       = s.mean;
87    this->stddev     = s.stddev;
88    this->median     = s.median;
89    this->madfm      = s.madfm;
90    this->threshold  = s.threshold;
91    this->pThreshold = s.pThreshold;
92    this->useRobust  = s.useRobust;
93    this->useFDR     = s.useFDR;
94    return *this;
95  }
96  template StatsContainer<int>& StatsContainer<int>::operator= (const StatsContainer<int>& s);
97  template StatsContainer<long>& StatsContainer<long>::operator= (const StatsContainer<long>& s);
98  template StatsContainer<float>& StatsContainer<float>::operator= (const StatsContainer<float>& s);
99  template StatsContainer<double>& StatsContainer<double>::operator= (const StatsContainer<double>& s);
100  //--------------------------------------------------------------------
101
102  template <class Type>
103  float StatsContainer<Type>::getThresholdSNR()
104  {
105    /**
106     * The SNR is defined in terms of excess over the middle estimator
107     * in units of the spread estimator.
108    */
109    return (threshold - this->getMiddle())/this->getSpread();
110  }
111  template float StatsContainer<int>::getThresholdSNR();
112  template float StatsContainer<long>::getThresholdSNR();
113  template float StatsContainer<float>::getThresholdSNR();
114  template float StatsContainer<double>::getThresholdSNR();
115  //--------------------------------------------------------------------
116
117  template <class Type>
118  void  StatsContainer<Type>::setThresholdSNR(float snr)
119  {
120    /**
121     * The SNR is defined in terms of excess over the middle estimator
122     * in units of the spread estimator.
123     */
124    threshold=this->getMiddle() + snr*this->getSpread();
125  }
126  template void StatsContainer<int>::setThresholdSNR(float snr);
127  template void StatsContainer<long>::setThresholdSNR(float snr);
128  template void StatsContainer<float>::setThresholdSNR(float snr);
129  template void StatsContainer<double>::setThresholdSNR(float snr);
130  //--------------------------------------------------------------------
131 
132  template <class Type>
133  float StatsContainer<Type>::getSNR(float value)
134  {
135    /**
136     * The SNR is defined in terms of excess over the middle estimator
137     * in units of the spread estimator.
138     */
139    return (value - this->getMiddle())/this->getSpread();
140  }
141  template float StatsContainer<int>::getSNR(float value);
142  template float StatsContainer<long>::getSNR(float value);
143  template float StatsContainer<float>::getSNR(float value);
144  template float StatsContainer<double>::getSNR(float value);
145  //--------------------------------------------------------------------
146   
147  template <class Type>
148  float StatsContainer<Type>::getMiddle()
149  {
150    /**
151     * The middle value is determined by the StatsContainer::useRobust
152     * flag -- it will be either the median (if true), or the mean (if
153     * false).
154     */
155    if(useRobust) return float(median);
156    else return mean;
157  }
158  template float StatsContainer<int>::getMiddle();
159  template float StatsContainer<long>::getMiddle();
160  template float StatsContainer<float>::getMiddle();
161  template float StatsContainer<double>::getMiddle();
162  //--------------------------------------------------------------------
163   
164  template <class Type>
165  float StatsContainer<Type>::getSpread(){
166    /**
167     * The spread value returned is determined by the
168     * StatsContainer::useRobust flag -- it will be either the madfm
169     * (if true), or the rms (if false). If robust, the madfm will be
170     * converted to an equivalent rms under the assumption of
171     * Gaussianity, using the Statistics::madfmToSigma function.
172     */
173    if(useRobust) return madfmToSigma(madfm);
174    else return stddev;
175  }
176  template float StatsContainer<int>::getSpread();
177  template float StatsContainer<long>::getSpread();
178  template float StatsContainer<float>::getSpread();
179  template float StatsContainer<double>::getSpread();
180  //--------------------------------------------------------------------
181   
182  template <class Type>
183  void  StatsContainer<Type>::scaleNoise(float scale)
184  {
185    /**
186     *  Multiply the noise parameters (stddev & madfm) by a given
187     *  factor, and adjust the threshold.
188     */
189    float snr = (threshold - this->getMiddle())/this->getSpread();   
190    this->madfm  = Type(this->madfm*scale);
191    this->stddev *= scale;
192    this->threshold = this->getMiddle() + snr*this->getSpread();
193  }
194  template void StatsContainer<int>::scaleNoise(float scale);
195  template void StatsContainer<long>::scaleNoise(float scale);
196  template void StatsContainer<float>::scaleNoise(float scale);
197  template void StatsContainer<double>::scaleNoise(float scale);
198 //--------------------------------------------------------------------
199
200  template <class Type>
201  float StatsContainer<Type>::getPValue(float value)
202  {
203    /**
204     * Get the "probability", under the assumption of normality, of a
205     * value occuring. 
206     *
207     * It is defined by \f$0.5 \operatorname{erfc}(z/\sqrt{2})\f$, where
208     * \f$z=(x-\mu)/\sigma\f$. We need the factor of 0.5 here, as we are
209     * only considering the positive tail of the distribution -- we
210     * don't care about negative detections.
211     */
212   
213    float zStat = (value - this->getMiddle()) / this->getSpread();
214    return 0.5 * erfc( zStat / M_SQRT2 );
215  }
216  template float StatsContainer<int>::getPValue(float value);
217  template float StatsContainer<long>::getPValue(float value);
218  template float StatsContainer<float>::getPValue(float value);
219  template float StatsContainer<double>::getPValue(float value);
220  //--------------------------------------------------------------------
221   
222  template <class Type>
223  bool StatsContainer<Type>::isDetection(float value){
224    /**
225     * Compares the value given to the correct threshold, depending on
226     * the value of the StatsContainer::useFDR flag.
227     */
228    if(useFDR) return (this->getPValue(value) < this->pThreshold);
229    else       return (value > this->threshold);
230  }
231  template bool StatsContainer<int>::isDetection(float value);
232  template bool StatsContainer<long>::isDetection(float value);
233  template bool StatsContainer<float>::isDetection(float value);
234  template bool StatsContainer<double>::isDetection(float value);
235  //--------------------------------------------------------------------
236
237  template <class Type>
238  void StatsContainer<Type>::calculate(Type *array, long size)
239  {
240    /**
241     * Calculate all four statistics for all elements of a given
242     * array.
243     *
244     * \param array The input data array.
245     * \param size The length of the input array
246     */
247//     findNormalStats(array, size, this->mean, this->stddev);
248//     findMedianStats(array, size, this->median, this->madfm);
249    findAllStats(array,size,this->mean,this->stddev,this->median,this->madfm);
250    this->defined = true;
251  }
252  template void StatsContainer<int>::calculate(int *array, long size);
253  template void StatsContainer<long>::calculate(long *array, long size);
254  template void StatsContainer<float>::calculate(float *array, long size);
255  template void StatsContainer<double>::calculate(double *array, long size);
256  //--------------------------------------------------------------------
257
258  template <class Type>
259  void StatsContainer<Type>::calculate(Type *array, long size, bool *mask)
260  {
261    /**
262     * Calculate all four statistics for a subset of a given
263     * array. The subset is defined by an array of bool
264     * variables. 
265     *
266     * \param array The input data array.
267     * \param size The length of the input array
268     * \param mask An array of the same length that says whether to
269     * include each member of the array in the calculations. Use a
270     * value if mask=true.
271     */
272//     findNormalStats(array, size, mask, this->mean, this->stddev);
273//     findMedianStats(array, size, mask, this->median, this->madfm);
274    findAllStats(array, size, mask,
275                 this->mean, this->stddev, this->median, this->madfm);
276    this->defined = true;
277  }
278  template void StatsContainer<int>::calculate(int *array, long size, bool *mask);
279  template void StatsContainer<long>::calculate(long *array, long size, bool *mask);
280  template void StatsContainer<float>::calculate(float *array, long size, bool *mask);
281  template void StatsContainer<double>::calculate(double *array, long size, bool *mask);
282  //--------------------------------------------------------------------
283
284  template <class Type>
285  std::ostream& operator<< (std::ostream& theStream, StatsContainer<Type> &s)
286  {
287    /**
288     * Prints out the four key statistics to the requested stream.
289     */
290    theStream << "Mean   = "   << s.mean   << "\t"
291              << "Std.Dev. = " << s.stddev << "\n"
292              << "Median = "   << s.median << "\t"
293              << "MADFM    = " << s.madfm  << "\n";
294    return theStream;
295  }
296  template std::ostream& operator<<<int> (std::ostream& theStream, StatsContainer<int> &s);
297  template std::ostream& operator<<<long> (std::ostream& theStream, StatsContainer<long> &s);
298  template std::ostream& operator<<<float> (std::ostream& theStream, StatsContainer<float> &s);
299  template std::ostream& operator<<<double> (std::ostream& theStream, StatsContainer<double> &s);
300
301
302
303}  // matches:  namespace Statistics {
Note: See TracBrowser for help on using the repository browser.