welford.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. #include "welford.h"
  2. #include <util/generic/ymath.h>
  3. void TMeanCalculator::Multiply(const double value) {
  4. SumWeights *= value;
  5. }
  6. void TMeanCalculator::Add(const double value, const double weight /*= 1.*/) {
  7. SumWeights += weight;
  8. if (SumWeights.Get()) {
  9. Mean += weight * (value - Mean) / SumWeights.Get();
  10. }
  11. }
  12. void TMeanCalculator::Remove(const double value, const double weight /*= 1.*/) {
  13. SumWeights -= weight;
  14. if (SumWeights.Get()) {
  15. Mean -= weight * (value - Mean) / SumWeights.Get();
  16. }
  17. }
  18. double TMeanCalculator::GetMean() const {
  19. return Mean;
  20. }
  21. double TMeanCalculator::GetSumWeights() const {
  22. return SumWeights.Get();
  23. }
  24. void TMeanCalculator::Reset() {
  25. *this = TMeanCalculator();
  26. }
  27. void TCovariationCalculator::Add(const double firstValue, const double secondValue, const double weight /*= 1.*/) {
  28. SumWeights += weight;
  29. if (SumWeights.Get()) {
  30. FirstValueMean += weight * (firstValue - FirstValueMean) / SumWeights.Get();
  31. Covariation += weight * (firstValue - FirstValueMean) * (secondValue - SecondValueMean);
  32. SecondValueMean += weight * (secondValue - SecondValueMean) / SumWeights.Get();
  33. }
  34. }
  35. void TCovariationCalculator::Remove(const double firstValue, const double secondValue, const double weight /*= 1.*/) {
  36. SumWeights -= weight;
  37. if (SumWeights.Get()) {
  38. FirstValueMean -= weight * (firstValue - FirstValueMean) / SumWeights.Get();
  39. Covariation -= weight * (firstValue - FirstValueMean) * (secondValue - SecondValueMean);
  40. SecondValueMean -= weight * (secondValue - SecondValueMean) / SumWeights.Get();
  41. }
  42. }
  43. double TCovariationCalculator::GetFirstValueMean() const {
  44. return FirstValueMean;
  45. }
  46. double TCovariationCalculator::GetSecondValueMean() const {
  47. return SecondValueMean;
  48. }
  49. double TCovariationCalculator::GetCovariation() const {
  50. return Covariation;
  51. }
  52. double TCovariationCalculator::GetSumWeights() const {
  53. return SumWeights.Get();
  54. }
  55. void TCovariationCalculator::Reset() {
  56. *this = TCovariationCalculator();
  57. }
  58. void TDeviationCalculator::Add(const double value, const double weight /*= 1.*/) {
  59. const double lastMean = MeanCalculator.GetMean();
  60. MeanCalculator.Add(value, weight);
  61. Deviation += weight * (value - lastMean) * (value - MeanCalculator.GetMean());
  62. }
  63. void TDeviationCalculator::Remove(const double value, const double weight /*= 1.*/) {
  64. const double lastMean = MeanCalculator.GetMean();
  65. MeanCalculator.Remove(value, weight);
  66. Deviation -= weight * (value - lastMean) * (value - MeanCalculator.GetMean());
  67. }
  68. double TDeviationCalculator::GetMean() const {
  69. return MeanCalculator.GetMean();
  70. }
  71. double TDeviationCalculator::GetDeviation() const {
  72. return Deviation;
  73. }
  74. double TDeviationCalculator::GetStdDev() const {
  75. const double sumWeights = GetSumWeights();
  76. if (!sumWeights) {
  77. return 0.;
  78. }
  79. return sqrt(GetDeviation() / sumWeights);
  80. }
  81. double TDeviationCalculator::GetSumWeights() const {
  82. return MeanCalculator.GetSumWeights();
  83. }
  84. void TDeviationCalculator::Reset() {
  85. *this = TDeviationCalculator();
  86. }