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

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

Only significant changes relate to altering the headers to the spectral plots. The information is now spread over four lines, so that it can all fit horizontally. This required a new Detection function, and some tweaking of Plot constants.

Otherwise, just minor tweaks of comments and formatting.

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