1 /*****************************************************************************
2 * rrd_hw_math.c Math functions for Holt-Winters computations
3 *****************************************************************************/
5 #include "rrd_tool.h"
6 #include "rrd_hw_math.h"
7 #ifndef WIN32
8 #include "rrd_config.h"
9 #endif
11 /*****************************************************************************
12 * RRDtool supports both the additive and multiplicative Holt-Winters methods.
13 * The additive method makes predictions by adding seasonality to the baseline,
14 * whereas the multiplicative method multiplies the seasonality coefficient by
15 * the baseline to make a prediction. This file contains all the differences
16 * between the additive and multiplicative methods, as well as a few math
17 * functions common to them both.
18 ****************************************************************************/
20 /*****************************************************************************
21 * Functions for additive Holt-Winters
22 *****************************************************************************/
24 rrd_value_t hw_additive_calculate_prediction(
25 rrd_value_t intercept,
26 rrd_value_t slope,
27 int null_count,
28 rrd_value_t seasonal_coef)
29 {
30 return intercept + slope * null_count + seasonal_coef;
31 }
33 rrd_value_t hw_additive_calculate_intercept(
34 rrd_value_t hw_alpha,
35 rrd_value_t observed,
36 rrd_value_t seasonal_coef,
37 unival *coefs)
38 {
39 return hw_alpha * (observed - seasonal_coef)
40 + (1 - hw_alpha) * (coefs[CDP_hw_intercept].u_val
41 +
42 (coefs[CDP_hw_slope].u_val) *
43 (coefs[CDP_null_count].u_cnt));
44 }
46 rrd_value_t hw_additive_calculate_seasonality(
47 rrd_value_t hw_gamma,
48 rrd_value_t observed,
49 rrd_value_t intercept,
50 rrd_value_t seasonal_coef)
51 {
52 return hw_gamma * (observed - intercept)
53 + (1 - hw_gamma) * seasonal_coef;
54 }
56 rrd_value_t hw_additive_init_seasonality(
57 rrd_value_t seasonal_coef,
58 rrd_value_t intercept)
59 {
60 return seasonal_coef - intercept;
61 }
63 /*****************************************************************************
64 * Functions for multiplicative Holt-Winters
65 *****************************************************************************/
67 rrd_value_t hw_multiplicative_calculate_prediction(
68 rrd_value_t intercept,
69 rrd_value_t slope,
70 int null_count,
71 rrd_value_t seasonal_coef)
72 {
73 return (intercept + slope * null_count) * seasonal_coef;
74 }
76 rrd_value_t hw_multiplicative_calculate_intercept(
77 rrd_value_t hw_alpha,
78 rrd_value_t observed,
79 rrd_value_t seasonal_coef,
80 unival *coefs)
81 {
82 if (seasonal_coef <= 0) {
83 return DNAN;
84 }
86 return hw_alpha * (observed / seasonal_coef)
87 + (1 - hw_alpha) * (coefs[CDP_hw_intercept].u_val
88 +
89 (coefs[CDP_hw_slope].u_val) *
90 (coefs[CDP_null_count].u_cnt));
91 }
93 rrd_value_t hw_multiplicative_calculate_seasonality(
94 rrd_value_t hw_gamma,
95 rrd_value_t observed,
96 rrd_value_t intercept,
97 rrd_value_t seasonal_coef)
98 {
99 if (intercept <= 0) {
100 return DNAN;
101 }
103 return hw_gamma * (observed / intercept)
104 + (1 - hw_gamma) * seasonal_coef;
105 }
107 rrd_value_t hw_multiplicative_init_seasonality(
108 rrd_value_t seasonal_coef,
109 rrd_value_t intercept)
110 {
111 if (intercept <= 0) {
112 return DNAN;
113 }
115 return seasonal_coef / intercept;
116 }
118 /*****************************************************************************
119 * Math functions common to additive and multiplicative Holt-Winters
120 *****************************************************************************/
122 rrd_value_t hw_calculate_slope(
123 rrd_value_t hw_beta,
124 unival *coefs)
125 {
126 return hw_beta * (coefs[CDP_hw_intercept].u_val -
127 coefs[CDP_hw_last_intercept].u_val)
128 + (1 - hw_beta) * coefs[CDP_hw_slope].u_val;
129 }
131 rrd_value_t hw_calculate_seasonal_deviation(
132 rrd_value_t hw_gamma,
133 rrd_value_t prediction,
134 rrd_value_t observed,
135 rrd_value_t last)
136 {
137 return hw_gamma * fabs(prediction - observed)
138 + (1 - hw_gamma) * last;
139 }
141 rrd_value_t hw_init_seasonal_deviation(
142 rrd_value_t prediction,
143 rrd_value_t observed)
144 {
145 return fabs(prediction - observed);
146 }