@@ -158,6 +158,70 @@ public:
158158 // / \return the standard deviation of unbinned values
159159 double ComputeStdDev (std::size_t dim = 0 ) const { return std::sqrt (ComputeVariance (dim)); }
160160
161+ // clang-format off
162+ // / Compute the skewness of unbinned values.
163+ // /
164+ // / The skewness is the third standardized moment:
165+ // / \f[
166+ // / E\left[\left(\frac{X - \mu}{\sigma}\right)^3\right]
167+ // / \f]
168+ // / With support for weighted filling and after some rewriting, it is computed as:
169+ // / \f[
170+ // / \frac{\frac{\sum w_i \cdot x_i^3}{\sum w_i} - 3 \cdot \frac{\sum w_i \cdot x_i^2}{\sum w_i} \cdot \mu + 2 \cdot \mu^3}{\sigma^3}
171+ // / \f]
172+ // /
173+ // / \param[in] dim the dimension index, starting at 0
174+ // / \return the skewness of unbinned values
175+ // clang-format on
176+ double ComputeSkewness (std::size_t dim = 0 ) const
177+ {
178+ // First get the statistics, which includes checking the argument.
179+ auto &stats = fDimensionStats .at (dim);
180+ if (fSumW == 0 ) {
181+ return 0 ;
182+ }
183+ double mean = ComputeMean (dim);
184+ double var = ComputeVariance (dim);
185+ double EWX3 = stats.fSumWX3 / fSumW ;
186+ double EWX2 = stats.fSumWX2 / fSumW ;
187+ return (EWX3 - 3 * EWX2 * mean + 2 * mean * mean * mean) / std::pow (var, 1.5 );
188+ }
189+
190+ // clang-format off
191+ // / Compute the (excess) kurtosis of unbinned values.
192+ // /
193+ // / The kurtosis is based on the fourth standardized moment:
194+ // / \f[
195+ // / E\left[\left(\frac{X - \mu}{\sigma}\right)^4\right]
196+ // / \f]
197+ // / The excess kurtosis subtracts 3 from the standardized moment to have a value of 0 for a normal distribution:
198+ // / \f[
199+ // / E\left[\left(\frac{X - \mu}{\sigma}\right)^4\right] - 3
200+ // / \f]
201+ // /
202+ // / With support for weighted filling and after some rewriting, the (excess kurtosis) is computed as:
203+ // / \f[
204+ // / \frac{\frac{\sum w_i \cdot x_i^4}{\sum w_i} - 4 \cdot \frac{\sum w_i \cdot x_i^3}{\sum w_i} \cdot \mu + 6 \cdot \frac{\sum w_i \cdot x_i^2}{\sum w_i} \cdot \mu^2 - 3 \cdot \mu^4}{\sigma^4} - 3
205+ // / \f]
206+ // /
207+ // / \param[in] dim the dimension index, starting at 0
208+ // / \return the (excess) kurtosis of unbinned values
209+ // clang-format on
210+ double ComputeKurtosis (std::size_t dim = 0 ) const
211+ {
212+ // First get the statistics, which includes checking the argument.
213+ auto &stats = fDimensionStats .at (dim);
214+ if (fSumW == 0 ) {
215+ return 0 ;
216+ }
217+ double mean = ComputeMean (dim);
218+ double var = ComputeVariance (dim);
219+ double EWX4 = stats.fSumWX4 / fSumW ;
220+ double EWX3 = stats.fSumWX3 / fSumW ;
221+ double EWX2 = stats.fSumWX2 / fSumW ;
222+ return (EWX4 - 4 * EWX3 * mean + 6 * EWX2 * mean * mean - 3 * mean * mean * mean * mean) / (var * var) - 3 ;
223+ }
224+
161225private:
162226 template <std::size_t I, typename ... A>
163227 void FillImpl (const std::tuple<A...> &args)
0 commit comments