bug fix
[u/mrichter/AliRoot.git] / FMD / flow / AliFMDFlowStat.h
1 // -*- mode: C++ -*- 
2 /* Copyright (C) 2007 Christian Holm Christensen <cholm@nbi.dk>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 2.1 of
7  * the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
17  * USA
18  */
19 #ifndef ALIFMDFLOWSTAT_H
20 #define ALIFMDFLOWSTAT_H
21 // #include <cmath>
22 #include <TMath.h>
23 #include <TObject.h>
24
25 //______________________________________________________
26 /** @class AliFMDFlowStat flow/AliFMDFlowStat.h <flow/AliFMDFlowStat.h>
27     @brief Single variable statistics. 
28     @ingroup u_utils 
29
30     This class calculates the single variable statistics of a random
31     variable @f$ x@f$. 
32     
33     The average @f$\bar{x}@f$ after @f$n@f$ observations is calculated as 
34     @f[ 
35     \bar{x}^{(n)} = \left\{\begin{array}{rl} 
36     x^{(n)} & n = 1\\
37     \left(1-\frac1n\right)\bar{x}^{(n-1)} + \frac{x^{(n)}}{n} & n > 1
38     \end{array}\right. 
39     @f]
40     and the square variance @f$s^2@f$ after @f$ n@f$ observations is
41     given by  
42     @f[ 
43     {s^{2}}^{(n)} = \left\{\begin{array}{rl}
44     0 & n = 1\\ 
45     \left(1-\frac1n\right){s^{2}}^{(n-1)} + 
46     \frac{\left(x^{(n)}-\bar{x}^{(n)}\right)^2}{n-1} & n > 1
47     \end{array}\right.
48     @f] 
49 */
50 class AliFMDFlowStat : public TObject
51 {
52 public:
53   /** Constructor */
54   AliFMDFlowStat() : fAverage(0), fSqVar(0), fN(0) {}
55   /** Copy constructor 
56       @param o Object to copy from. */
57   AliFMDFlowStat(const AliFMDFlowStat& o);
58   /** Assuignement operator
59       @param o Object to assign from. 
60       @return Reference to this */
61   AliFMDFlowStat& operator=(const AliFMDFlowStat& o);
62   /** Destructor */
63   virtual ~AliFMDFlowStat() {}
64   /** Reset */
65   void Clear(Option_t* option="");
66   /** Add another data point */
67   void Add(Double_t x);
68   /** Get the average */
69   Double_t Average() const { return fAverage; }
70   /** Get the square variance */
71   Double_t SqVar() const { return fSqVar; } 
72   /** Get the number of data points */
73   ULong_t N() const { return fN; }
74   /**  Given the two partial sample of the same stocastic variable, of 
75        size @f$ n_1@f$ and @f$ n_2@f$, with averages @f$ m_1@f$ and
76        @f$ m2@f$, and square variances, @f$ s_1^2@f$ and @f$ s_2^2@f$,
77        calculate the full sample average and square variance: 
78        @f[ 
79        m = \frac{n_1 m_1 + n_2 m_2}{n_1 + n_2} 
80        @f] 
81        and 
82        @f[ 
83        s^2 = \frac{n_1 * s_1^2 + n_2 s_2^2}{n_1 + n_2} 
84              + \frac{n_1 n_2 (m_1 - m_2)^2}{(n_1 + n_2)^2}
85        @f]
86        @param o Other statistics object to add 
87        @return Reference to this */
88   AliFMDFlowStat& operator+=(const AliFMDFlowStat& o);
89 protected:
90   /** Average */
91   Double_t        fAverage; // Running 
92   /** Square variance */
93   Double_t        fSqVar; // Square variance 
94   /** Number of data points */
95   ULong_t fN; // Number of data points
96   /** Define for ROOT I/O */
97   ClassDef(AliFMDFlowStat,1);
98 };
99
100 //__________________________________________________________________
101 inline 
102 AliFMDFlowStat::AliFMDFlowStat(const AliFMDFlowStat& o)
103   : TObject(o), 
104     fAverage(o.fAverage), 
105     fSqVar(o.fSqVar), 
106     fN(o.fN)
107 {}
108 //__________________________________________________________________
109 inline AliFMDFlowStat&
110 AliFMDFlowStat::operator=(const AliFMDFlowStat& o)
111 {
112   fAverage = o.fAverage;
113   fSqVar   = o.fSqVar;
114   fN       = o.fN;
115   return *this;
116 }
117 //__________________________________________________________________
118 inline AliFMDFlowStat&
119 AliFMDFlowStat::operator+=(const AliFMDFlowStat& o)
120 {
121   if (fN + o.fN <= 0) return *this;
122   
123   Double_t m = (fN * o.fAverage + o.fN * o.fAverage)/(fN + o.fN);
124   Double_t s = ((fN * o.fSqVar + o.fN * o.fSqVar)/(fN + o.fN)
125                 + (TMath::Power(fAverage - o.fAverage, 2) * fN * o.fN) 
126                 / TMath::Power(fN + o.fN, 2));
127   fAverage = m;
128   fSqVar   = s;
129   fN       = fN + o.fN;
130   return *this;
131 }
132 //__________________________________________________________________
133 inline void 
134 AliFMDFlowStat::Clear(Option_t*) 
135
136   fAverage = fSqVar = 0; 
137   fN = 0; 
138 }
139
140 //__________________________________________________________________
141 inline void 
142 AliFMDFlowStat::Add(Double_t x) 
143
144   if (TMath::IsNaN(x) || !TMath::Finite(x)) return;
145   fN++;
146   if (fN == 1) { 
147     fAverage = x;
148     fSqVar   = 0;
149     return;
150   }
151   Double_t c = (1. - 1. / fN);
152   fAverage  *= c;
153   fAverage  += x / fN;
154   fSqVar    *= c;
155   fSqVar    += TMath::Power(x - fAverage, 2) / (fN - 1);
156 }
157
158
159 #endif
160 //
161 // EOF
162 //