diff --git a/ostap/stats/moment.py b/ostap/stats/moment.py index 6cca4ad3..171f412b 100644 --- a/ostap/stats/moment.py +++ b/ostap/stats/moment.py @@ -408,125 +408,122 @@ def _om_table ( obj , title = '' , prefix = '' , standard = False ) : IM = Ostap.Math.Moments.invalid_moment() rows = [] - item = obj - while 1 < 2 : + + order = obj.order + size = obj.size () + + s = obj.size() + if 1.e+6 < s : + field , n = pretty_float ( s * 1.0 ) + row = "#entries" , '' if not n else '[10^%+d]' % n , field + else : + row = "#entries" , '' , '%d' % s + rows.append ( row ) + + if hasattr ( obj , 'w2' ) : + + w2 = obj.w2 () + field , n = pretty_float ( w2 ) + row = "sum(w^2)" , '' if not n else '[10^%+d]' % n , field + rows.append ( row ) - order = item.order - moment = item.moment () - size = item.size () + if hasattr ( obj , 'w' ) : - if 0 == order : + w = obj.w () + field , n = pretty_float ( w ) + row = "sum(w)" , '' if not n else '[10^%+d]' % n , field + rows.append ( row ) + + if hasattr ( obj , 'nEff' ) : - if hasattr ( obj , 'w2' ) : - - w2 = obj.w2 () - field , n = pretty_float ( w2 ) - row = "sum(w^2)" , '' if not n else '[10^%+d]' % n , field - rows.append ( row ) - - if hasattr ( obj , 'w' ) : - - w = obj.w () - field , n = pretty_float ( w ) - row = "sum(w)" , '' if not n else '[10^%+d]' % n , field - rows.append ( row ) - - if hasattr ( obj , 'nEff' ) : - - neff = obj.nEff() - if neff != size and 0 < neff and isfinite ( neff ) : - field , n = pretty_float ( neff ) - row = "nEff" , '' if not n else '[10^%+d]' % n , field - rows.append ( row ) - - s = obj.size() - if 1.e+6 < s : - field , n = pretty_float ( s * 1.0 ) - row = "#entries" , '' if not n else '[10^%+d]' % n , field - else : - row = "#entries" , '' , '%d' % s - + neff = obj.nEff() + if neff != size and 0 < neff and isfinite ( neff ) : + field , n = pretty_float ( neff ) + row = "nEff" , '' if not n else '[10^%+d]' % n , field rows.append ( row ) - - elif 1 == order and 1 <= size : - v = obj.mean () - vv = float ( v ) - if IM != float ( v ) and isfinite ( vv ) : - if isinstance ( v , VE ) : field , n = pretty_ve ( v ) - else : field , n = pretty_float ( v ) - row = "mean" , '' if not n else '[10^%+d]' % n , field - rows.append ( row ) - - elif 2 == order and 2 <= size : - - v = obj.variance () - vv = float ( v ) - if isfinite ( vv ) and IM != vv and 0 <= vv : - - v = obj.rms ( ) - vv = float ( v ) - if isfinite ( vv ) and IM != vv and 0 <= vv : - if isinstance ( v , VE ) : field , n = pretty_ve ( v ) - else : field , n = pretty_float ( v ) - row = "rms" , '' if not n else '[10^%+d]' % n , field - rows.append ( row ) - - elif 3 == order and 3 <= size : - - v = obj.skewness () - vv = float ( v ) - if isfinite ( vv ) and IM != vv : - if isinstance ( v , VE ) : field , n = pretty_ve ( v ) - else : field , n = pretty_float ( v ) - row = "skewness" , '' if not n else '[10^%+d]' % n , field - rows.append ( row ) + if 1 <= order and 1 <= size and obj.ok () : - elif 4 == order and 4 <= size : + v = obj.mean () + vv = float ( v ) + if IM != float ( v ) and isfinite ( vv ) : + if isinstance ( v , VE ) : field , n = pretty_ve ( v ) + else : field , n = pretty_float ( v ) + row = "mean" , '' if not n else '[10^%+d]' % n , field + rows.append ( row ) - v = obj.kurtosis () - vv = float ( v ) - if isfinite ( vv ) and IM != float ( v ) : - if isinstance ( v , VE ) : field , n = pretty_ve ( v ) - else : field , n = pretty_float ( v ) - row = "kurtosis" , '' if not n else '[10^%+d]' % n , field - rows.append ( row ) - - elif 5 == order and 5 <= size and obj.order < 10 and hasattr ( obj , 'unbiased_5th' ) and not standard : + if 2 <= order and 2 <= size and obj.ok() : + + v = obj.rms ( ) + vv = float ( v ) + if isfinite ( vv ) and IM != vv and 0 <= vv : + if isinstance ( v , VE ) : field , n = pretty_ve ( v ) + else : field , n = pretty_float ( v ) + row = "rms" , '' if not n else '[10^%+d]' % n , field + rows.append ( row ) - v = obj.unbiased_5th () - vv = float ( v ) - if isfinite ( vv ) and IM != float ( v ) : - if isinstance ( v , VE ) : field , n = pretty_ve ( v ) - else : field , n = pretty_float ( v ) - row = "M[5](unb)" , '' if not n else '[10^%+d]' % n , field - rows.append ( row ) + v = obj.variance ( ) + vv = float ( v ) + if isfinite ( vv ) and IM != vv and 0 <= vv : + if isinstance ( v , VE ) : field , n = pretty_ve ( v ) + else : field , n = pretty_float ( v ) + row = "variance" , '' if not n else '[10^%+d]' % n , field + rows.append ( row ) + + if 3 <= order and 3 <= size and obj.ok () : + + v = obj.skewness () + vv = float ( v ) + if isfinite ( vv ) and IM != vv : + if isinstance ( v , VE ) : field , n = pretty_ve ( v ) + else : field , n = pretty_float ( v ) + row = "skewness" , '' if not n else '[10^%+d]' % n , field + rows.append ( row ) + + elif 4 <= order and 4 <= size and obj.ok () : + + v = obj.kurtosis () + vv = float ( v ) + if isfinite ( vv ) and IM != float ( v ) : + if isinstance ( v , VE ) : field , n = pretty_ve ( v ) + else : field , n = pretty_float ( v ) + row = "kurtosis" , '' if not n else '[10^%+d]' % n , field + rows.append ( row ) - elif order <= size and standard : + if 5 <= order and 5 <= size and obj.ok() and hasattr ( obj , 'unbiased_5th' ) : + + v = obj.unbiased_5th () + vv = float ( v ) + if isfinite ( vv ) and IM != float ( v ) : + if isinstance ( v , VE ) : field , n = pretty_ve ( v ) + else : field , n = pretty_float ( v ) + row = "M[5](unb)" , '' if not n else '[10^%+d]' % n , field + rows.append ( row ) - v = obj.std_moment ( order ) + for i in range ( 2 , order + 1 ) : + + if standard : + + v = obj.std_moment ( i ) vv = float ( v ) if isfinite ( vv ) and IM != float ( v ) : if isinstance ( v , VE ) : field , n = pretty_ve ( v ) else : field , n = pretty_float ( v ) - row = "std-M[%s]" % order , '' if not n else '[10^%+d]' % n , field + row = "std-M[%s]" % i , '' if not n else '[10^%+d]' % n , field rows.append ( row ) - - elif order <= size : - v = obj.cmoment ( order ) + else : + + v = obj.central_moment ( i ) vv = float ( v ) if isfinite ( vv ) and IM != float ( v ) : if isinstance ( v , VE ) : field , n = pretty_ve ( v ) else : field , n = pretty_float ( v ) - row = "M[%s]" % order , '' if not n else '[10^%+d]' % n , field + row = "M[%s]" % i , '' if not n else '[10^%+d]' % n , field rows.append ( row ) - - if hasattr ( item , 'previous' ) : item = item.previous() - else : break - + - rows = tuple ( [ ( '' , '' , 'value') ] + [ r for r in reversed ( rows ) ] ) + rows = tuple ( [ ( '' , '' , 'value') ] + rows ) import ostap.logger.table as T diff --git a/ostap/stats/tests/test_stats_moment.py b/ostap/stats/tests/test_stats_moment.py index 48b3d274..b178cb08 100755 --- a/ostap/stats/tests/test_stats_moment.py +++ b/ostap/stats/tests/test_stats_moment.py @@ -84,17 +84,17 @@ def test_moment2() : logger.info ( "%s\n%s" % ( t , i.table ( title = t , prefix = '# ' ) ) ) logger.info ( "%s\n%s" % ( t , i.table ( title = t , prefix = '# ' , standard = True ) ) ) - for i in m : - t = 'Moment counter-%2d' % i.order - logger .info (' %s : size %s ' % ( t , i.size () ) ) - logger .info (' %s : n_eff %s ' % ( t , i.nEff () ) ) - logger .info (' %s : sum(w) %s ' % ( t , i.w () ) ) - logger .info (' %s : sum(w^2) %s ' % ( t , i.w2 () ) ) - if 1 <= i.order : logger.info (' %s : mean %s ' % ( t , i.mean () ) ) - if 2 <= i.order : logger.info (' %s : rms %s ' % ( t , i.rms () ) ) - if 2 <= i.order : logger.info (' %s : variance %s ' % ( t , i.variance () ) ) - if 3 <= i.order : logger.info (' %s : skewness %s ' % ( t , i.skewness () ) ) - if 4 <= i.order : logger.info (' %s : kurtosis %s ' % ( t , i.kurtosis () ) ) + ## for i in m : + ## t = 'Moment counter-%2d' % i.order + ## logger .info (' %s : size %s ' % ( t , i.size () ) ) + ## logger .info (' %s : n_eff %s ' % ( t , i.nEff () ) ) + ## logger .info (' %s : sum(w) %s ' % ( t , i.w () ) ) + ## logger .info (' %s : sum(w^2) %s ' % ( t , i.w2 () ) ) + ## if 1 <= i.order : logger.info (' %s : mean %s ' % ( t , i.mean () ) ) + ## if 2 <= i.order : logger.info (' %s : rms %s ' % ( t , i.rms () ) ) + ## if 2 <= i.order : logger.info (' %s : variance %s ' % ( t , i.variance () ) ) + ## if 3 <= i.order : logger.info (' %s : skewness %s ' % ( t , i.skewness () ) ) + ## if 4 <= i.order : logger.info (' %s : kurtosis %s ' % ( t , i.kurtosis () ) ) # ============================================================================= def test_moment3() : @@ -162,10 +162,10 @@ def test_moment4() : # ============================================================================= if '__main__' == __name__ : - test_moment1 () + ## test_moment1 () test_moment2 () - test_moment3 () - test_moment4 () + ## test_moment3 () + ## test_moment4 () # ============================================================================= ## The END diff --git a/source/include/Ostap/Moments.h b/source/include/Ostap/Moments.h index 4814742f..66f45a20 100644 --- a/source/include/Ostap/Moments.h +++ b/source/include/Ostap/Moments.h @@ -229,6 +229,16 @@ namespace Ostap this->template moment_ () / std::pow ( this->moment_<2>() , 0.5 * K ) ; } // ======================================================================= + public: + // ====================================================================== + /// mean value + inline Ostap::Math::ValueWithError + mean () const + { + const double cov2 = ( 2 <= size() ) ? M_<2>() / ( size () * size () ) : 0.0L ; + return Ostap::Math::ValueWithError ( mu () , cov2 ) ; + } + // ======================================================================= private: // ====================================================================== /// counter of (N-1)th order @@ -557,6 +567,11 @@ namespace Ostap template ::type = 0 > inline long double std_moment_ () const { return 0 ; } // ====================================================================== + public: + // ====================================================================== + /// mean value + inline double mean () const { return mu() ; } + // ======================================================================= private : // ====================================================================== Moment_<0> m_prev { } ; @@ -804,6 +819,16 @@ namespace Ostap this->template moment_ () / std::pow ( this->moment_<2>() , 0.5 * K ) ; } // ====================================================================== + public: + // ====================================================================== + /// mean value + inline Ostap::Math::ValueWithError + mean () const + { + const double cov2 = ( ok () && 2 <= size() ) ? M_<2>() / ( w() * nEff() ) : 0.0L ; + return Ostap::Math::ValueWithError ( mu () , cov2 ) ; + } + // ======================================================================= private: // ====================================================================== /// counter of (N-1)th order @@ -1163,6 +1188,11 @@ namespace Ostap template ::type = 0 > inline long double std_moment_ () const { return 0 ; } // ====================================================================== + public: + // ====================================================================== + /// mean value + inline double mean () const { return mu() ; } + // ======================================================================= private: // ====================================================================== WMoment_<0> m_prev { } ;