Merge branch 'master' into ff/rrdd
[rrdtool.git] / src / rrd_hw_math.c
1 /*****************************************************************************
2  * rrd_hw_math.c  Math functions for Holt-Winters computations
3  *****************************************************************************/
4
5 #include "rrd_tool.h"
6 #include "rrd_hw_math.h"
7 #include "rrd_config.h"
8
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  ****************************************************************************/
17
18 /*****************************************************************************
19  * Functions for additive Holt-Winters
20  *****************************************************************************/
21
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 }
30
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 }
43
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 }
53
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 }
60
61 /*****************************************************************************
62  * Functions for multiplicative Holt-Winters
63  *****************************************************************************/
64
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 }
73
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     }
83
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 }
90
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     }
100
101     return hw_gamma * (observed / intercept)
102         + (1 - hw_gamma) * seasonal_coef;
103 }
104
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     }
112
113     return seasonal_coef / intercept;
114 }
115
116 /*****************************************************************************
117  * Math functions common to additive and multiplicative Holt-Winters
118  *****************************************************************************/
119
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 }
128
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 }
138
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 }