@@ -30,36 +30,41 @@ class mean {
3030 using value_type = ValueType;
3131 using const_reference = const value_type&;
3232
33+ struct internal_data_type {
34+ value_type sum_;
35+ value_type mean_;
36+ value_type sum_of_deltas_squared_;
37+ };
38+
3339 mean () = default ;
3440
3541 // / Allow implicit conversion from mean<T>.
3642 template <class T >
37- mean (const mean<T>& o) noexcept
38- : sum_{o.sum_ }, mean_{o.mean_ }, sum_of_deltas_squared_{o.sum_of_deltas_squared_ } {}
43+ mean (const mean<T>& o) noexcept : data_{o.data_ } {}
3944
4045 // / Initialize to external count, mean, and variance.
4146 mean (const_reference n, const_reference mean, const_reference variance) noexcept
42- : sum_(n), mean_( mean), sum_of_deltas_squared_( variance * (n - 1 )) {}
47+ : data_{n, mean, variance * (n - 1 )} {}
4348
4449 // / Insert sample x.
4550 void operator ()(const_reference x) noexcept {
46- sum_ += static_cast <value_type>(1 );
47- const auto delta = x - mean_;
48- mean_ += delta / sum_;
49- sum_of_deltas_squared_ += delta * (x - mean_);
51+ data_. sum_ += static_cast <value_type>(1 );
52+ const auto delta = x - data_. mean_ ;
53+ data_. mean_ += delta / data_. sum_ ;
54+ data_. sum_of_deltas_squared_ += delta * (x - data_. mean_ );
5055 }
5156
5257 // / Insert sample x with weight w.
5358 void operator ()(const weight_type<value_type>& w, const_reference x) noexcept {
54- sum_ += w.value ;
55- const auto delta = x - mean_;
56- mean_ += w.value * delta / sum_;
57- sum_of_deltas_squared_ += w.value * delta * (x - mean_);
59+ data_. sum_ += w.value ;
60+ const auto delta = x - data_. mean_ ;
61+ data_. mean_ += w.value * delta / data_. sum_ ;
62+ data_. sum_of_deltas_squared_ += w.value * delta * (x - data_. mean_ );
5863 }
5964
6065 // / Add another mean accumulator.
6166 mean& operator +=(const mean& rhs) noexcept {
62- if (rhs.sum_ == 0 ) return *this ;
67+ if (rhs.data_ . sum_ == 0 ) return *this ;
6368
6469 /*
6570 sum_of_deltas_squared
@@ -75,20 +80,20 @@ class mean {
7580
7681 Putting it together:
7782 sum_of_deltas_squared
78- = sum_of_deltas_squared_1 + n1 (mu1 - mu ))^2
79- + sum_of_deltas_squared_2 + n2 (mu2 - mu ))^2
83+ = sum_of_deltas_squared_1 + n1 (mu - mu1 ))^2
84+ + sum_of_deltas_squared_2 + n2 (mu - mu2 ))^2
8085 */
8186
82- const auto n1 = sum_;
83- const auto mu1 = mean_;
84- const auto n2 = rhs.sum_ ;
85- const auto mu2 = rhs.mean_ ;
87+ const auto n1 = data_. sum_ ;
88+ const auto mu1 = data_. mean_ ;
89+ const auto n2 = rhs.data_ . sum_ ;
90+ const auto mu2 = rhs.data_ . mean_ ;
8691
87- sum_ += rhs.sum_ ;
88- mean_ = (n1 * mu1 + n2 * mu2) / sum_;
89- sum_of_deltas_squared_ += rhs.sum_of_deltas_squared_ ;
90- sum_of_deltas_squared_ += n1 * detail::square (mean_ - mu1);
91- sum_of_deltas_squared_ += n2 * detail::square (mean_ - mu2);
92+ data_. sum_ += rhs. data_ .sum_ ;
93+ data_. mean_ = (n1 * mu1 + n2 * mu2) / data_. sum_ ;
94+ data_. sum_of_deltas_squared_ += rhs. data_ .sum_of_deltas_squared_ ;
95+ data_. sum_of_deltas_squared_ += n1 * detail::square (data_. mean_ - mu1);
96+ data_. sum_of_deltas_squared_ += n2 * detail::square (data_. mean_ - mu2);
9297
9398 return *this ;
9499 }
@@ -98,14 +103,14 @@ class mean {
98103 This acts as if all samples were scaled by the value.
99104 */
100105 mean& operator *=(const_reference s) noexcept {
101- mean_ *= s;
102- sum_of_deltas_squared_ *= s * s;
106+ data_. mean_ *= s;
107+ data_. sum_of_deltas_squared_ *= s * s;
103108 return *this ;
104109 }
105110
106111 bool operator ==(const mean& rhs) const noexcept {
107- return sum_ == rhs.sum_ && mean_ == rhs.mean_ &&
108- sum_of_deltas_squared_ == rhs.sum_of_deltas_squared_ ;
112+ return data_. sum_ == rhs.data_ . sum_ && data_. mean_ == rhs. data_ .mean_ &&
113+ data_. sum_of_deltas_squared_ == rhs. data_ .sum_of_deltas_squared_ ;
109114 }
110115
111116 bool operator !=(const mean& rhs) const noexcept { return !operator ==(rhs); }
@@ -116,38 +121,38 @@ class mean {
116121 see documentation of value() and variance(). count() can be used to compute
117122 the variance of the mean by dividing variance() by count().
118123 */
119- const_reference count () const noexcept { return sum_; }
124+ const_reference count () const noexcept { return data_. sum_ ; }
120125
121126 /* * Return mean value of accumulated samples.
122127
123128 The result is undefined, if `count() < 1`.
124129 */
125- const_reference value () const noexcept { return mean_; }
130+ const_reference value () const noexcept { return data_. mean_ ; }
126131
127132 /* * Return variance of accumulated samples.
128133
129134 The result is undefined, if `count() < 2`.
130135 */
131- value_type variance () const noexcept { return sum_of_deltas_squared_ / (sum_ - 1 ); }
136+ value_type variance () const noexcept {
137+ return data_.sum_of_deltas_squared_ / (data_.sum_ - 1 );
138+ }
132139
133140 template <class Archive >
134141 void serialize (Archive& ar, unsigned version) {
135142 if (version == 0 ) {
136143 // read only
137144 std::size_t sum;
138145 ar& make_nvp (" sum" , sum);
139- sum_ = static_cast <value_type>(sum);
146+ data_. sum_ = static_cast <value_type>(sum);
140147 } else {
141- ar& make_nvp (" sum" , sum_);
148+ ar& make_nvp (" sum" , data_. sum_ );
142149 }
143- ar& make_nvp (" mean" , mean_);
144- ar& make_nvp (" sum_of_deltas_squared" , sum_of_deltas_squared_);
150+ ar& make_nvp (" mean" , data_. mean_ );
151+ ar& make_nvp (" sum_of_deltas_squared" , data_. sum_of_deltas_squared_ );
145152 }
146153
147154private:
148- value_type sum_{};
149- value_type mean_{};
150- value_type sum_of_deltas_squared_{};
155+ internal_data_type data_{0 , 0 , 0 };
151156};
152157
153158} // namespace accumulators
0 commit comments