feisty meow concerns codebase  2.140
averager.h
Go to the documentation of this file.
1 #ifndef AVERAGER_CLASS
2 #define AVERAGER_CLASS
3 
4 /*****************************************************************************\
5 * *
6 * Name : averager *
7 * Author : Chris Koeritz *
8 * *
9 *******************************************************************************
10 * Copyright (c) 1997-$now By Author. This program is free software; you can *
11 * redistribute it and/or modify it under the terms of the GNU General Public *
12 * License as published by the Free Software Foundation; either version 2 of *
13 * the License or (at your option) any later version. This is online at: *
14 * http://www.fsf.org/copyleft/gpl.html *
15 * Please send any updates to: fred@gruntose.com *
16 \*****************************************************************************/
17 
18 #include <basis/array.h>
19 #include <basis/functions.h>
20 
21 namespace mathematics {
22 
24 
30 template <class contents>
31 class averager
32 {
33 public:
34  averager(int entries = 100, bool compacting = true);
36 
45  void add(contents value, int count = 1);
47 
48  contents average() const { return average(0, length() - 1); }
50 
51  int samples() const;
53 
54  int length() const { return _averages.length(); }
56 
57  contents average(int start, int end) const;
59 
60  struct weighted_entry { contents value; int count; };
62 
65  weighted_entry get(int index) const { return _averages.get(index); }
67 
68  void compact();
70 
75 
79 private:
80  bool _do_compaction;
82  int _entries;
83 };
84 
86 
88 class int_averager : public averager<int>
89 {
90 public:
91  int_averager(int entries = 100, bool compacting = true)
92  : averager<int>(entries, compacting) {}
93 };
94 
96 
97 // implementations below...
98 
99 const int AVERAGER_SIZE_LIMIT = 180000; // the most items we'll try to handle.
100 
101 template <class contents>
102 averager<contents>::averager(int entries, bool compacting)
103 : _do_compaction(compacting), _averages(), _entries(entries)
104 {
105  int unit_size = sizeof(weighted_entry);
106  if (basis::negative(_entries) || !_entries)
107  _entries = int(AVERAGER_SIZE_LIMIT / unit_size);
108 }
109 
110 template <class contents>
112 {
113  if (length() < 8) return; // sorry, you're too short for this wild ride.
114  int end_whacking = _averages.length() / 4;
115  if (_do_compaction) {
116  contents whacked_average = average(0, end_whacking);
117  _averages.zap(1, end_whacking);
118  _averages[0].value = whacked_average;
119  _averages[0].count = end_whacking + 1;
120  } else _averages.zap(0, end_whacking);
121 }
122 
123 template <class contents>
125 {
126  // make sure that we don't go over our allotted space.
127  int unit_size = sizeof(weighted_entry);
128  int limit = basis::minimum(AVERAGER_SIZE_LIMIT, _entries * unit_size);
129  if (int(_averages.length() + 2) * unit_size >= limit) compact();
130 }
131 
132 template <class contents>
133 void averager<contents>::add(contents value, int count)
134 {
135  weighted_entry to_add;
136  to_add.value = value;
137  to_add.count = count;
138  check_for_compaction();
139  _averages += to_add;
140 }
141 
142 template <class contents>
143 contents averager<contents>::average(int start, int end) const
144 {
145  bounds_return(start, 0, length() - 1, 0);
146  bounds_return(end, start, length() - 1, 0);
147  bounds_return(end - start + 1, 1, length(), 0);
148 
149  contents accum = 0;
150  contents count = 0;
151  for (int i = start; i <= end; i++) {
152  accum += get(i).value * get(i).count;
153  count += get(i).count;
154  }
155  if (!count) count = 1;
156  return accum / count;
157 }
158 
159 template <class contents>
161 {
162  int to_return = 0;
163  for (int i = 0; i < length(); i++) to_return += get(i).count;
164  return to_return;
165 }
166 
167 } //namespace.
168 
169 #endif
170 
Represents a sequential, ordered, contiguous collection of objects.
Definition: array.h:54
Maintains a list of numbers and provides the average for them.
Definition: averager.h:32
void check_for_compaction()
checks whether the averager needs to be compacted yet or not.
Definition: averager.h:124
weighted_entry get(int index) const
accesses the entry stored at the "index" specified.
Definition: averager.h:65
int samples() const
returns the total number of samples recorded in the average.
Definition: averager.h:160
void add(contents value, int count=1)
adds a new "value" to the averager, with an optional "count".
Definition: averager.h:133
contents average() const
reports the overall average of the whole list.
Definition: averager.h:48
int length() const
returns the current length of the averages list.
Definition: averager.h:54
void compact()
chops off the oldest portion of the averager.
Definition: averager.h:111
averager(int entries=100, bool compacting=true)
creates an averager whose list length is restricted to "entries".
Definition: averager.h:102
contents average(int start, int end) const
reports the average over the range from "start" to "end" inclusive.
Definition: averager.h:143
keeps an average on a stream of integers.
Definition: averager.h:89
int_averager(int entries=100, bool compacting=true)
Definition: averager.h:91
#define bounds_return(value, low, high, to_return)
Verifies that "value" is between "low" and "high", inclusive.
Definition: guards.h:48
type minimum(type a, type b)
maximum returns the greater of two values.
Definition: functions.h:29
bool negative(const type &a)
negative returns true if "a" is less than zero.
Definition: functions.h:43
An extension to floating point primitives providing approximate equality.
Definition: averager.h:21
const int AVERAGER_SIZE_LIMIT
Definition: averager.h:99
structure holding a weighted chunk of the average.
Definition: averager.h:60
contents value
Definition: averager.h:60
int count
Definition: averager.h:60