#include <Stats.h>
Collaboration diagram for ACE_Stats:

Public Methods | |
| ACE_Stats (void) | |
| Default constructor. More... | |
| int | sample (const ACE_INT32 value) |
| Provide a new sample. Returns 0 on success, -1 if it fails due to running out of memory, or to rolling over of the sample count. More... | |
| ACE_UINT32 | samples (void) const |
| Access the number of samples provided so far. More... | |
| ACE_INT32 | min_value (void) const |
| Value of the minimum sample provided so far. More... | |
| ACE_INT32 | max_value (void) const |
| Value of the maximum sample provided so far. More... | |
| void | mean (ACE_Stats_Value &mean, const ACE_UINT32 scale_factor=1) |
| int | std_dev (ACE_Stats_Value &std_dev, const ACE_UINT32 scale_factor=1) |
| Access the standard deviation, whole and fractional parts. See description of <mean> method for argument descriptions. More... | |
| int | print_summary (const u_int precision, const ACE_UINT32 scale_factor=1, FILE *=stdout) const |
| void | reset (void) |
| Initialize internal state. More... | |
| void | dump (void) const |
| Print summary statistics to stdout. More... | |
Static Public Methods | |
| void | quotient (const ACE_UINT64 dividend, const ACE_UINT32 divisor, ACE_Stats_Value "ient) |
| Utility division function, for ACE_UINT64 dividend. More... | |
| void | quotient (const ACE_Stats_Value ÷nd, const ACE_UINT32 divisor, ACE_Stats_Value "ient) |
| Utility division function, for ACE_Stats_Value dividend. More... | |
| void | square_root (const ACE_UINT64 n, ACE_Stats_Value &square_root) |
Private Attributes | |
| u_int | overflow_ |
| Internal indication of whether there has been overflow. Contains the errno corresponding to the cause of overflow. More... | |
| ACE_UINT32 | number_of_samples_ |
| Number of samples. More... | |
| ACE_INT32 | min_ |
| Minimum sample value. More... | |
| ACE_INT32 | max_ |
| Maximum sample value. More... | |
| ACE_Unbounded_Queue< ACE_INT32 > | samples_ |
| The samples. More... | |
Simple statistical analysis package. Prominent features are:
* ACE_Stats stats;
* for (u_int i = 0; i < n; ++i)
* {
* const ACE_UINT32 sample = ...;
* stats.sample (sample);
* }
* stats.print_summary (3);
*
Definition at line 125 of file Stats.h.
|
|
Default constructor.
Definition at line 64 of file Stats.i. References reset.
00065 {
00066 reset ();
00067 }
|
|
|
Print summary statistics to stdout.
Definition at line 92 of file Stats.i. References print_summary.
00093 {
00094 print_summary (3u);
00095 }
|
|
|
Value of the maximum sample provided so far.
Definition at line 85 of file Stats.i. References max_.
00086 {
00087 return max_;
00088 }
|
|
||||||||||||
|
Access the mean of all samples provided so far. The fractional part is to the specified number of digits. E.g., 3 fractional digits specifies that the fractional part is in thousandths. Definition at line 63 of file Stats.cpp. References ACE_UINT64, ACE_UINT64_LITERAL, ACE_Unbounded_Queue_Iterator::advance, ACE_Unbounded_Queue_Iterator::done, ACE_Stats_Value::fractional, ACE_Unbounded_Queue_Iterator::next, number_of_samples_, quotient, sample, samples_, and ACE_Stats_Value::whole. Referenced by ACE_High_Res_Timer::calibrate, and std_dev.
00065 {
00066 if (number_of_samples_ > 0)
00067 {
00068 #if defined ACE_LACKS_LONGLONG_T
00069 // If ACE_LACKS_LONGLONG_T, then ACE_UINT64 is a user-defined class.
00070 // To prevent having to construct a static of that class, declare it
00071 // on the stack, and construct it, in each function that needs it.
00072 const ACE_U_LongLong ACE_STATS_INTERNAL_OFFSET (0, 8);
00073 #else /* ! ACE_LACKS_LONGLONG_T */
00074 const ACE_UINT64 ACE_STATS_INTERNAL_OFFSET =
00075 ACE_UINT64_LITERAL (0x100000000);
00076 #endif /* ! ACE_LACKS_LONGLONG_T */
00077
00078 ACE_UINT64 sum = ACE_STATS_INTERNAL_OFFSET;
00079 ACE_Unbounded_Queue_Iterator<ACE_INT32> i (samples_);
00080 while (! i.done ())
00081 {
00082 ACE_INT32 *sample;
00083 if (i.next (sample))
00084 {
00085 sum += *sample;
00086 i.advance ();
00087 }
00088 }
00089
00090 // sum_ was initialized with ACE_STATS_INTERNAL_OFFSET, so
00091 // subtract that off here.
00092 quotient (sum - ACE_STATS_INTERNAL_OFFSET,
00093 number_of_samples_ * scale_factor,
00094 m);
00095 }
00096 else
00097 {
00098 m.whole (0);
00099 m.fractional (0);
00100 }
00101 }
|
|
|
Value of the minimum sample provided so far.
Definition at line 78 of file Stats.i. References min_.
00079 {
00080 return min_;
00081 }
|
|
||||||||||||||||
|
Print summary statistics. If scale_factor is not 1, then the results are divided by it, i.e., each of the samples is scaled down by it. If internal overflow is reached with the specified scale factor, it successively tries to reduce it. Returns -1 if there is overflow even with a 0 scale factor. Definition at line 209 of file Stats.cpp. References ACE_LIB_TEXT, ACE_TCHAR, ACE_UINT64, ACE_OS::fprintf, ACE_Stats_Value::fractional, max_, min_, overflow_, quotient, samples, ACE_OS::sprintf, strerror, and ACE_Stats_Value::whole. Referenced by dump.
00212 {
00213 ACE_TCHAR mean_string [128];
00214 ACE_TCHAR std_dev_string [128];
00215 ACE_TCHAR min_string [128];
00216 ACE_TCHAR max_string [128];
00217 int success = 0;
00218
00219 for (int tmp_precision = precision;
00220 ! overflow_ && ! success && tmp_precision >= 0;
00221 --tmp_precision)
00222 {
00223 // Build a format string, in case the C library doesn't support %*u.
00224 ACE_TCHAR format[32];
00225 if (tmp_precision == 0)
00226 ACE_OS::sprintf (format, ACE_LIB_TEXT ("%%%d"), tmp_precision);
00227 else
00228 ACE_OS::sprintf (format, ACE_LIB_TEXT ("%%d.%%0%du"), tmp_precision);
00229
00230 ACE_Stats_Value u (tmp_precision);
00231 ((ACE_Stats *) this)->mean (u, scale_factor);
00232 ACE_OS::sprintf (mean_string, format, u.whole (), u.fractional ());
00233
00234 ACE_Stats_Value sd (tmp_precision);
00235 if (((ACE_Stats *) this)->std_dev (sd, scale_factor))
00236 {
00237 success = 0;
00238 continue;
00239 }
00240 else
00241 {
00242 success = 1;
00243 }
00244 ACE_OS::sprintf (std_dev_string, format, sd.whole (), sd.fractional ());
00245
00246 ACE_Stats_Value minimum (tmp_precision), maximum (tmp_precision);
00247 if (min_ != 0)
00248 {
00249 const ACE_UINT64 m (min_);
00250 quotient (m, scale_factor, minimum);
00251 }
00252 if (max_ != 0)
00253 {
00254 const ACE_UINT64 m (max_);
00255 quotient (m, scale_factor, maximum);
00256 }
00257 ACE_OS::sprintf (min_string, format,
00258 minimum.whole (), minimum.fractional ());
00259 ACE_OS::sprintf (max_string, format,
00260 maximum.whole (), maximum.fractional ());
00261 }
00262
00263 if (success == 1)
00264 {
00265 ACE_OS::fprintf (file, ACE_LIB_TEXT ("samples: %u (%s - %s); mean: ")
00266 ACE_LIB_TEXT ("%s; std dev: %s\n"),
00267 samples (), min_string, max_string,
00268 mean_string, std_dev_string);
00269 return 0;
00270 }
00271 else
00272 {
00273 #if !defined (ACE_HAS_WINCE)
00274 ACE_OS::fprintf (file,
00275 ACE_LIB_TEXT ("ACE_Stats::print_summary: OVERFLOW: %s\n"),
00276 strerror (overflow_));
00277 #else
00278 // WinCE doesn't have strerror ;(
00279 ACE_OS::fprintf (file,
00280 ACE_LIB_TEXT ("ACE_Stats::print_summary: OVERFLOW\n"));
00281 #endif /* ACE_HAS_WINCE */
00282 return -1;
00283 }
00284 }
|
|
||||||||||||||||
|
Utility division function, for ACE_Stats_Value dividend.
Definition at line 318 of file Stats.cpp. References ACE_Stats_Value::fractional, ACE_Stats_Value::fractional_field, ACE_Stats_Value::precision, and ACE_Stats_Value::whole.
00321 {
00322 // The whole part of the division comes from simple integer division.
00323 quotient.whole (divisor == 0 ? 0 : dividend.whole () / divisor);
00324
00325 if (quotient.precision () > 0 || divisor == 0)
00326 {
00327 const ACE_UINT32 field = quotient.fractional_field ();
00328
00329 // Fractional = (dividend % divisor) * 10^precision / divisor.
00330 quotient.fractional (dividend.whole () % divisor * field / divisor +
00331 dividend.fractional () / divisor);
00332 }
00333 else
00334 {
00335 // No fractional portion is requested, so don't bother
00336 // calculating it.
00337 quotient.fractional (0);
00338 }
00339 }
|
|
||||||||||||||||
|
Utility division function, for ACE_UINT64 dividend.
Definition at line 287 of file Stats.cpp. References ACE_UINT64, ACE_Stats_Value::fractional, ACE_Stats_Value::fractional_field, ACE_Stats_Value::precision, and ACE_Stats_Value::whole. Referenced by mean, print_summary, and std_dev.
00290 {
00291 // The whole part of the division comes from simple integer division.
00292 quotient.whole (ACE_static_cast (ACE_UINT32,
00293 divisor == 0 ? 0 : dividend / divisor));
00294
00295 if (quotient.precision () > 0 || divisor == 0)
00296 {
00297 const ACE_UINT32 field = quotient.fractional_field ();
00298
00299 // Fractional = (dividend % divisor) * 10^precision / divisor
00300
00301 // It would be nice to add round-up term:
00302 // Fractional = (dividend % divisor) * 10^precision / divisor +
00303 // 10^precision/2 / 10^precision
00304 // = ((dividend % divisor) * 10^precision + divisor) /
00305 // divisor
00306 quotient.fractional (ACE_static_cast (ACE_UINT32,
00307 dividend % divisor * field / divisor));
00308 }
00309 else
00310 {
00311 // No fractional portion is requested, so don't bother
00312 // calculating it.
00313 quotient.fractional (0);
00314 }
00315 }
|
|
|
Initialize internal state.
Definition at line 199 of file Stats.cpp. References max_, min_, number_of_samples_, overflow_, ACE_Unbounded_Queue< ACE_INT32 >::reset, and samples_. Referenced by ACE_Stats.
|
|
|
Provide a new sample. Returns 0 on success, -1 if it fails due to running out of memory, or to rolling over of the sample count.
Definition at line 33 of file Stats.cpp. References ACE_Unbounded_Queue< ACE_INT32 >::enqueue_tail, max_, min_, number_of_samples_, overflow_, and samples_. Referenced by ACE_High_Res_Timer::calibrate, mean, and std_dev.
00034 {
00035 if (samples_.enqueue_tail (value) == 0)
00036 {
00037 ++number_of_samples_;
00038 if (number_of_samples_ == 0)
00039 {
00040 // That's a lot of samples :-)
00041 overflow_ = EFAULT;
00042 return -1;
00043 }
00044
00045 if (value < min_)
00046 min_ = value;
00047
00048 if (value > max_)
00049 max_ = value;
00050
00051 return 0;
00052 }
00053 else
00054 {
00055 // Probably failed due to running out of memory when trying to
00056 // enqueue the new value.
00057 overflow_ = errno;
00058 return -1;
00059 }
00060 }
|
|
|
Access the number of samples provided so far.
Definition at line 71 of file Stats.i. References number_of_samples_. Referenced by print_summary.
00072 {
00073 return number_of_samples_;
00074 }
|
|
||||||||||||
|
Sqrt function, which uses an oversimplified version of Newton's method. It's not fast, but it doesn't require floating point support. Definition at line 342 of file Stats.cpp. References ACE_UINT64, ACE_Stats_Value::fractional, ACE_Stats_Value::fractional_field, ACE_Stats_Value::precision, and ACE_Stats_Value::whole. Referenced by std_dev.
00344 {
00345 ACE_UINT32 floor = 0;
00346 ACE_UINT32 ceiling = 0xFFFFFFFFu;
00347 ACE_UINT32 mid = 0;
00348 u_int i;
00349
00350 // The maximum number of iterations is log_2 (2^64) == 64.
00351 for (i = 0; i < 64; ++i)
00352 {
00353 mid = (ceiling - floor) / 2 + floor;
00354 if (floor == mid)
00355 // Can't divide the interval any further.
00356 break;
00357 else
00358 {
00359 // Multiply carefully to avoid overflow.
00360 ACE_UINT64 mid_squared = mid; mid_squared *= mid;
00361 if (mid_squared == n)
00362 break;
00363 else if (mid_squared < n)
00364 floor = mid;
00365 else
00366 ceiling = mid;
00367 }
00368 }
00369
00370 square_root.whole (mid);
00371 ACE_UINT64 mid_squared = mid; mid_squared *= mid;
00372
00373 if (square_root.precision () && mid_squared < n)
00374 {
00375 // (mid * 10^precision + fractional)^2 ==
00376 // n^2 * 10^(precision * 2)
00377
00378 const ACE_UINT32 field = square_root.fractional_field ();
00379
00380 floor = 0;
00381 ceiling = field;
00382 mid = 0;
00383
00384 // Do the 64-bit arithmetic carefully to avoid overflow.
00385 ACE_UINT64 target = n;
00386 target *= field;
00387 target *= field;
00388
00389 ACE_UINT64 difference = 0;
00390
00391 for (i = 0; i < square_root.precision (); ++i)
00392 {
00393 mid = (ceiling - floor) / 2 + floor;
00394
00395 ACE_UINT64 current = square_root.whole () * field + mid;
00396 current *= square_root.whole () * field + mid;
00397
00398 if (floor == mid)
00399 {
00400 difference = target - current;
00401 break;
00402 }
00403 else if (current <= target)
00404 floor = mid;
00405 else
00406 ceiling = mid;
00407 }
00408
00409 // Check to see if the fractional part should be one greater.
00410 ACE_UINT64 next = square_root.whole () * field + mid + 1;
00411 next *= square_root.whole () * field + mid + 1;
00412
00413 square_root.fractional (next - target < difference ? mid + 1 : mid);
00414 }
00415 else
00416 {
00417 // No fractional portion is requested, so don't bother
00418 // calculating it.
00419 square_root.fractional (0);
00420 }
00421 }
|
|
||||||||||||
|
Access the standard deviation, whole and fractional parts. See description of <mean> method for argument descriptions.
Definition at line 104 of file Stats.cpp. References ACE_U64_TO_U32, ACE_UINT64, ACE_Unbounded_Queue_Iterator::advance, ACE_Unbounded_Queue_Iterator::done, ACE_Stats_Value::fractional, ACE_Stats_Value::fractional_field, mean, ACE_Unbounded_Queue_Iterator::next, number_of_samples_, overflow_, ACE_Stats_Value::precision, quotient, sample, samples_, ACE_Stats_Value::scaled_value, square_root, and ACE_Stats_Value::whole.
00106 {
00107 if (number_of_samples_ <= 1)
00108 {
00109 std_dev.whole (0);
00110 std_dev.fractional (0);
00111 }
00112 else
00113 {
00114 const ACE_UINT32 field = std_dev.fractional_field ();
00115
00116 // The sample standard deviation is:
00117 //
00118 // sqrt (sum (sample_i - mean)^2 / (number_of_samples_ - 1))
00119
00120 ACE_UINT64 mean_scaled;
00121 // Calculate the mean, scaled, so that we don't lose its
00122 // precision.
00123 ACE_Stats_Value avg (std_dev.precision ());
00124 mean (avg, 1u);
00125 avg.scaled_value (mean_scaled);
00126
00127 // Calculate the summation term, of squared differences from the
00128 // mean.
00129 ACE_UINT64 sum_of_squares = 0;
00130 ACE_Unbounded_Queue_Iterator<ACE_INT32> i (samples_);
00131 while (! i.done ())
00132 {
00133 ACE_INT32 *sample;
00134 if (i.next (sample))
00135 {
00136 const ACE_UINT64 original_sum_of_squares = sum_of_squares;
00137
00138 // Scale up by field width so that we don't lose the
00139 // precision of the mean. Carefully . . .
00140 const ACE_UINT64 product (*sample * field);
00141
00142 ACE_UINT64 difference;
00143 // NOTE: please do not reformat this code! It //
00144 // works with the Diab compiler the way it is! //
00145 if (product >= mean_scaled) //
00146 { //
00147 difference = product - mean_scaled; //
00148 } //
00149 else //
00150 { //
00151 difference = mean_scaled - product; //
00152 } //
00153 // NOTE: please do not reformat this code! It //
00154 // works with the Diab compiler the way it is! //
00155
00156 // Square using 64-bit arithmetic.
00157 sum_of_squares += difference * ACE_U64_TO_U32 (difference);
00158 i.advance ();
00159
00160 if (sum_of_squares < original_sum_of_squares)
00161 {
00162 overflow_ = ENOSPC;
00163 return -1;
00164 }
00165 }
00166 }
00167
00168 // Divide the summation by (number_of_samples_ - 1), to get the
00169 // variance. In addition, scale the variance down to undo the
00170 // mean scaling above. Otherwise, it can get too big.
00171 ACE_Stats_Value variance (std_dev.precision ());
00172 quotient (sum_of_squares,
00173 (number_of_samples_ - 1) * field * field,
00174 variance);
00175
00176 // Take the square root of the variance to get the standard
00177 // deviation. First, scale up . . .
00178 ACE_UINT64 scaled_variance;
00179 variance.scaled_value (scaled_variance);
00180
00181 // And scale up, once more, because we'll be taking the square
00182 // root.
00183 scaled_variance *= field;
00184 ACE_Stats_Value unscaled_standard_deviation (std_dev.precision ());
00185 square_root (scaled_variance,
00186 unscaled_standard_deviation);
00187
00188 // Unscale.
00189 quotient (unscaled_standard_deviation,
00190 scale_factor * field,
00191 std_dev);
00192 }
00193
00194 return 0;
00195 }
|
|
|
Maximum sample value.
Definition at line 204 of file Stats.h. Referenced by max_value, print_summary, reset, and sample. |
|
|
Minimum sample value.
Definition at line 201 of file Stats.h. Referenced by min_value, print_summary, reset, and sample. |
|
|
Number of samples.
|
|
|
Internal indication of whether there has been overflow. Contains the errno corresponding to the cause of overflow.
Definition at line 195 of file Stats.h. Referenced by print_summary, reset, sample, and std_dev. |
|
|
The samples.
|
1.2.14 written by Dimitri van Heesch,
© 1997-2002