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