1 /*++ 2 Copyright (c) 2018 Microsoft Corporation 3 4 Module Name: 5 6 ema.h 7 8 Abstract: 9 10 Exponential moving average based on CaDiCal. 11 The exponential scheme used to adjust beta to alpha is 12 described in Biere & Froelich, POS (Pragmatics of SAT) 2016. 13 14 Author: 15 16 Nikolaj Bjorner (nbjorner) 2018-05-03 17 18 Revision History: 19 20 --*/ 21 #pragma once 22 23 class ema { 24 double m_alpha, m_beta, m_value; 25 unsigned m_period, m_wait; invariant()26 bool invariant() const { return 0 <= m_alpha && m_alpha <= m_beta && m_beta <= 1; } 27 public: ema()28 ema(): m_alpha(0), m_beta(1), m_value(0), m_period(0), m_wait(0) { 29 SASSERT(invariant()); 30 } 31 ema(double alpha)32 ema(double alpha): 33 m_alpha(alpha), m_beta(1), m_value(0), 34 m_period(0), m_wait(0) { 35 SASSERT(invariant()); 36 } 37 set_alpha(double alpha)38 void set_alpha(double alpha) { 39 m_alpha = alpha; 40 SASSERT(invariant()); 41 } 42 43 operator double () const { return m_value; } 44 update(double x)45 void update(double x) { 46 SASSERT(invariant()); 47 m_value += m_beta * (x - m_value); 48 if (m_beta <= m_alpha || m_wait--) return; 49 m_wait = m_period = 2*(m_period + 1) - 1; 50 m_beta *= 0.5; 51 if (m_beta < m_alpha) m_beta = m_alpha; 52 } 53 set(double x)54 void set(double x) { 55 m_value = x; 56 } 57 }; 58 59