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 #include "rrd_config.h"
9 /*****************************************************************************
10 * RRDtool supports both the additive and multiplicative Holt-Winters methods.
11 * The additive method makes predictions by adding seasonality to the baseline,
12 * whereas the multiplicative method multiplies the seasonality coefficient by
13 * the baseline to make a prediction. This file contains all the differences
14 * between the additive and multiplicative methods, as well as a few math
15 * functions common to them both.
16 ****************************************************************************/
18 /*****************************************************************************
19 * Functions for additive Holt-Winters
20 *****************************************************************************/
22 rrd_value_t hw_additive_calculate_prediction(
23 rrd_value_t intercept,
24 rrd_value_t slope,
25 int null_count,
26 rrd_value_t seasonal_coef)
27 {
28 return intercept + slope * null_count + seasonal_coef;
29 }
31 rrd_value_t hw_additive_calculate_intercept(
32 rrd_value_t hw_alpha,
33 rrd_value_t observed,
34 rrd_value_t seasonal_coef,
35 unival *coefs)
36 {
37 return hw_alpha * (observed - seasonal_coef)
38 + (1 - hw_alpha) * (coefs[CDP_hw_intercept].u_val
39 +
40 (coefs[CDP_hw_slope].u_val) *
41 (coefs[CDP_null_count].u_cnt));
42 }
44 rrd_value_t hw_additive_calculate_seasonality(
45 rrd_value_t hw_gamma,
46 rrd_value_t observed,
47 rrd_value_t intercept,
48 rrd_value_t seasonal_coef)
49 {
50 return hw_gamma * (observed - intercept)
51 + (1 - hw_gamma) * seasonal_coef;
52 }
54 rrd_value_t hw_additive_init_seasonality(
55 rrd_value_t seasonal_coef,
56 rrd_value_t intercept)
57 {
58 return seasonal_coef - intercept;
59 }
61 /*****************************************************************************
62 * Functions for multiplicative Holt-Winters
63 *****************************************************************************/
65 rrd_value_t hw_multiplicative_calculate_prediction(
66 rrd_value_t intercept,
67 rrd_value_t slope,
68 int null_count,
69 rrd_value_t seasonal_coef)
70 {
71 return (intercept + slope * null_count) * seasonal_coef;
72 }
74 rrd_value_t hw_multiplicative_calculate_intercept(
75 rrd_value_t hw_alpha,
76 rrd_value_t observed,
77 rrd_value_t seasonal_coef,
78 unival *coefs)
79 {
80 if (seasonal_coef <= 0) {
81 return DNAN;
82 }
84 return hw_alpha * (observed / seasonal_coef)
85 + (1 - hw_alpha) * (coefs[CDP_hw_intercept].u_val
86 +
87 (coefs[CDP_hw_slope].u_val) *
88 (coefs[CDP_null_count].u_cnt));
89 }
91 rrd_value_t hw_multiplicative_calculate_seasonality(
92 rrd_value_t hw_gamma,
93 rrd_value_t observed,
94 rrd_value_t intercept,
95 rrd_value_t seasonal_coef)
96 {
97 if (intercept <= 0) {
98 return DNAN;
99 }
101 return hw_gamma * (observed / intercept)
102 + (1 - hw_gamma) * seasonal_coef;
103 }
105 rrd_value_t hw_multiplicative_init_seasonality(
106 rrd_value_t seasonal_coef,
107 rrd_value_t intercept)
108 {
109 if (intercept <= 0) {
110 return DNAN;
111 }
113 return seasonal_coef / intercept;
114 }
116 /*****************************************************************************
117 * Math functions common to additive and multiplicative Holt-Winters
118 *****************************************************************************/
120 rrd_value_t hw_calculate_slope(
121 rrd_value_t hw_beta,
122 unival *coefs)
123 {
124 return hw_beta * (coefs[CDP_hw_intercept].u_val -
125 coefs[CDP_hw_last_intercept].u_val)
126 + (1 - hw_beta) * coefs[CDP_hw_slope].u_val;
127 }
129 rrd_value_t hw_calculate_seasonal_deviation(
130 rrd_value_t hw_gamma,
131 rrd_value_t prediction,
132 rrd_value_t observed,
133 rrd_value_t last)
134 {
135 return hw_gamma * fabs(prediction - observed)
136 + (1 - hw_gamma) * last;
137 }
139 rrd_value_t hw_init_seasonal_deviation(
140 rrd_value_t prediction,
141 rrd_value_t observed)
142 {
143 return fabs(prediction - observed);
144 }