Initial commit
[talweg.git] / R / getForecast.R
1 #' @title get Forecast
2 #'
3 #' @description Predict time-series curves for the selected days indices (lines in data).
4 #' Run the forecasting task described by \code{delta_forecaster_name} and
5 #' \code{shape_forecaster_name} on data obtained with \code{getData}
6 #'
7 #' @param data Dataset, object of type \code{Data} output of \code{getData}
8 #' @param indices Days indices where to forecast (the day after)
9 #' @param memory Data depth (in days) to be used for prediction
10 #' @param horizon Number of time steps to predict
11 #' @param shape_forecaster_name Name of the shape forcaster
12 #' \itemize{
13 #' \item Persistence : use values of last (similar, next) day
14 #' \item Neighbors : use PM10 from the k closest neighbors' tomorrows
15 #' \item Average : global average of all the (similar) "tomorrow of past"
16 #' }
17 #' @param delta_forecaster_name Name of the delta forecaster
18 #' \itemize{
19 #' \item Persistence : use last (similar) day values
20 #' \item Neighbors: re-use the weights optimized in corresponding shape forecaster
21 #' \item Zero: just output 0 (no adjustment)
22 #' }
23 #' @param ... Additional parameters for the forecasting models
24 #'
25 #' @return An object of class Forecast
26 #'
27 #' @examples
28 #' data = getData(ts_data="data/pm10_mesures_H_loc.csv", exo_data="data/meteo_extra_noNAs.csv",
29 #' input_tz = "Europe/Paris", working_tz="Europe/Paris", predict_at="07")
30 #' pred = getForecast(data, 2200:2230, Inf, 12, "Persistence", "Persistence")
31 #' \dontrun{#Sketch for real-time mode:
32 #' data = new("Data", ...)
33 #' repeat {
34 #' data$append(some_new_data)
35 #' pred = getForecast(data, ...)
36 #' #do_something_with_pred
37 #' }}
38 #' @export
39 getForecast = function(data, indices, memory, horizon,
40 shape_forecaster_name, delta_forecaster_name, ...)
41 {
42 horizon = as.integer(horizon)[1]
43 if (horizon<=0 || horizon>length(data$getCenteredSerie(2)))
44 stop("Horizon too short or too long")
45 indices = as.integer(indices)
46 if (any(indices<=0 | indices>data$getSize()))
47 stop("Indices out of range")
48 indices = sapply(indices, dateIndexToInteger, data)
49
50 #NOTE: some assymetry here...
51 shape_forecaster = new(paste(shape_forecaster_name,"ShapeForecaster",sep=""), data=data)
52 #A little bit strange, but match.fun() and get() fail
53 delta_forecaster = getFromNamespace(
54 paste("get",delta_forecaster_name,"DeltaForecast",sep=""), "talweg")
55
56 pred = list()
57 for (today in indices)
58 {
59 #NOTE: To estimate timing...
60 # print(paste("Predict until index",today))
61
62 #shape always predicted first (on centered series, no scaling taken into account),
63 #with side-effect: optimize some parameters (h, weights, ...)
64 predicted_shape = shape_forecaster$predict(today, memory, horizon, ...)
65 #then, delta prediction can re-use some variables optimized previously (like neighbors infos)
66 predicted_delta = delta_forecaster(data, today, memory, horizon,
67 shape_forecaster$getParameters(), ...)
68
69 #TODO: this way is faster than a call to append(); why ?
70 pred[[length(pred)+1]] = list(
71 # Predict shape and align it on end of current day
72 serie = predicted_shape + tail( data$getSerie(today), 1 ) - predicted_shape[1],
73 predicted_delta, #add predicted jump
74 params = shape_forecaster$getParameters(),
75 index = today )
76 }
77 new("Forecast",pred=pred)
78 }