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
21namespace mathematics {
22
24
30template <class contents>
32{
33public:
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
79private:
80 bool _do_compaction;
82 int _entries;
83};
84
86
88class int_averager : public averager<int>
89{
90public:
91 int_averager(int entries = 100, bool compacting = true)
92 : averager<int>(entries, compacting) {}
93};
94
96
97// implementations below...
98
99const int AVERAGER_SIZE_LIMIT = 180000; // the most items we'll try to handle.
100
101template <class contents>
102averager<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
110template <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
123template <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
132template <class contents>
133void 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
142template <class contents>
143contents 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
159template <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