diff --git a/source/include/Ostap/ValueWithError.h b/source/include/Ostap/ValueWithError.h index 6f0647c6..5efca8bc 100644 --- a/source/include/Ostap/ValueWithError.h +++ b/source/include/Ostap/ValueWithError.h @@ -1517,11 +1517,37 @@ namespace Ostap ( ValueWithError& left , ValueWithError& right ) { left.swap ( right ) ; } // ======================================================================== - // converison to string + // conversion to string inline std::string to_string ( const ValueWithError& v ) { return v.toString() ; } // ======================================================================== + /** Calculate mean andRMS for two samples + * @param a mean and rms for the 1st sample + * @param na size of the first sample + * @param b mean and rms for the 2nd sample + * @param nb size of the second sample + * @return mean and rmd for the combined sample + */ + ValueWithError two_samples + ( const ValueWithError& a , + const unsigned long na , + const ValueWithError& b , + const unsigned long nb ) ; + // ======================================================================== + /** Calculate mean andRMS for two samples + * @param a mean and rms for the 1st sample + * @param na size of the first sample + * @param b mean and rms for the 2nd sample + * @param nb size of the second sample + * @return mean and rmd for the combined sample + */ + ValueWithError two_samples + ( const ValueWithError& a , + const double na , + const ValueWithError& b , + const double nb ) ; + // ======================================================================== } // The end of namespace Ostap::Math // ========================================================================== } // The end of namespace Ostap diff --git a/source/src/ValueWithError.cpp b/source/src/ValueWithError.cpp index beb224c9..ff18f7f5 100644 --- a/source/src/ValueWithError.cpp +++ b/source/src/ValueWithError.cpp @@ -3280,6 +3280,93 @@ Ostap::Math::agm // return agm ( x , y , 0.0 ) ; } +// ============================================================================= +namespace +{ + // =========================================================================== + inline + Ostap::Math::ValueWithError + _two_samples_ + ( const Ostap::Math::ValueWithError& a , + const Ostap::Math::ValueWithError& b , + const long double alpha ) + { + const double beta = 1.0L - alpha ; + // + const double am = a.value() ; + const double bm = b.value() ; + const double ac2 = std::max ( a.cov2() , 0.0 ) ; + const double bc2 = std::max ( b.cov2() , 0.0 ) ; + // + const double m = alpha * am + beta * bm ; + const double dm = am - bm ; + const double c2 = alpha * ac2 + beta * bc2 + alpha * beta * dm * dm ; + // + return Ostap::Math::ValueWithError ( m , c2 ) ; + } + // =========================================================================== +} +// ============================================================================= +/* Calculate mean and RMS for two samples + * @param a mean and rms for the 1st sample + * @param na size of the first sample + * @param b mean and rms for the 2nd sample + * @param nb size of the second sample + * @return mean and rmd for the combined sample + */ +// ============================================================================= +Ostap::Math::ValueWithError +Ostap::Math::two_samples +( const Ostap::Math::ValueWithError& a , + const unsigned long na , + const Ostap::Math::ValueWithError& b , + const unsigned long nb ) +{ + const unsigned long nt = na + nb ; + // + static const std::string s_m1 { "Invalid sample size" } ; + static const std::string s_m2 { "Ostap::Math::two_samples" } ; + // + Ostap::Assert ( 0 < nt , s_m1 , s_m2 ) ; + // + if ( !na ) { return b ; } + else if ( !nb ) { return a ; } + // + const long double la = na ; + // + return _two_samples_ ( a , b , la / nt ) ; +} +// ============================================================================= +/* Calculate mean and RMS for two samples + * @param a mean and rms for the 1st sample + * @param na size of the first sample + * @param b mean and rms for the 2nd sample + * @param nb size of the second sample + * @return mean and rmd for the combined sample + */ +// ============================================================================= +Ostap::Math::ValueWithError +Ostap::Math::two_samples +( const Ostap::Math::ValueWithError& a , + const double na , + const Ostap::Math::ValueWithError& b , + const double nb ) +{ + const double nt = na + nb ; + // + static const std::string s_m1 { "Invalid sample size" } ; + static const std::string s_m2 { "Ostap::Math::two_samples" } ; + // + Ostap::Assert ( 0 < nt , s_m1 , s_m2 ) ; + // + if ( !na ) { return b ; } + else if ( !nb ) { return a ; } + // + const long double la = na ; + // + return _two_samples_ ( a , b , la / nt ) ; +} +// =============================================================================