1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#ifndef _ema_hpp_INCLUDED
#define _ema_hpp_INCLUDED
#include <cstdint>
namespace CaDiCaL {
struct Internal;
// This is a more complex generic exponential moving average class to
// support more robust initialization (see comments in the 'update'
// implementation).
struct EMA {
#ifdef LOGGING
uint64_t updated;
#endif
double value; // unbiased (corrected) moving average
double biased; // biased initialized moving average
double alpha; // input scaling with 'alpha = 1 - beta'
double beta; // decay of 'biased' with 'beta = 1 - alpha'
double exp; // 'exp = pow (beta, updated)'
EMA ()
:
#ifdef LOGGING
updated (0),
#endif
value (0), biased (0), alpha (0), beta (0), exp (0) {
}
EMA (double a)
:
#ifdef LOGGING
updated (0),
#endif
value (0), biased (0), alpha (a), beta (1 - a), exp (!!beta) {
assert (beta >= 0);
}
operator double () const { return value; }
void update (Internal *, double y, const char *name);
};
} // namespace CaDiCaL
/*------------------------------------------------------------------------*/
// Compact average update and initialization macros for better logging.
#define UPDATE_AVERAGE(A, Y) \
do { \
A.update (internal, (Y), #A); \
} while (0)
#define INIT_EMA(E, WINDOW) \
do { \
assert ((WINDOW) >= 1); \
double ALPHA = 1.0 / (double) (WINDOW); \
E = EMA (ALPHA); \
LOG ("init " #E " EMA target alpha %g window %d", ALPHA, \
(int) WINDOW); \
} while (0)
/*------------------------------------------------------------------------*/
#endif