X-Git-Url: https://git.auder.net/?a=blobdiff_plain;f=pkg%2FR%2FForecaster.R;h=2b259fc9bacdfd78e0ca073b28396ab9b1733716;hb=4f3fdbb8e2ac4bd57a4e27539a58ef0e7ec2304c;hp=4c8437e195b6bcf6ab501ec187e23bd42d0469cd;hpb=25b75559e2d9bf84e2de35b851d93fefdae36e17;p=talweg.git diff --git a/pkg/R/Forecaster.R b/pkg/R/Forecaster.R index 4c8437e..2b259fc 100644 --- a/pkg/R/Forecaster.R +++ b/pkg/R/Forecaster.R @@ -1,71 +1,82 @@ #' Forecaster #' -#' Forecaster (abstract class, implemented by all forecasters) +#' Forecaster (abstract class, implemented by all forecasters). #' -#' @field params List of computed parameters, for post-run analysis (dev) -#' @field data Dataset, object of class Data -#' @field pjump Function: how to predict the jump at day interface ? +#' A Forecaster object encapsulates parameters (which can be of various kinds, for +#' example "Neighbors" method stores informations about the considered neighborhood for +#' the current prediction task) and one main function: \code{predictSerie()}. This last +#' function (by default) calls \code{predictShape()} to get a forecast of a centered +#' serie, and then calls the "jump prediction" function if it's provided -- see "field" +#' section -- to adjust it based on the last observed values. The main method in derived +#' forecasters is \code{predictShape()}; see 'Methods' section. +#' +#' @usage # Forecaster$new(pjump) #warning: predictShape() is unimplemented +#' +#' @field .params List of computed parameters (if applicable). +#' @field .pjump Function: how to predict the jump at day interface? The arguments of +#' this function are -- in this order: +#' \itemize{ +#' \item data: object output of \code{getData()}, +#' \item today: index of the current day in data (known until predict_from-1), +#' \item memory: number of days to use in the past (including today), +#' \item predict_from: first time step to predict (in [1,24]) +#' \item horizon: last time step to predict (in [predict_from,24]), +#' \item params: optimized parameters in the main method \code{predictShape()}, +#' \item ...: additional arguments. +#' } +#' .pjump returns an estimation of the jump after the last observed value. +#' +#' @section Methods: +#' \describe{ +#' \item{\code{initialize(data, pjump)}}{ +#' Initialize a Forecaster object with a Data object and a jump prediction function, +#' or NULL if \code{predictShape()} returns an adjusted curve.} +#' \item{\code{predictSerie(data,today,memory,predict_from,horizon,...)}}{ +#' Predict the next curve (at index today) from predict_from to horizon (hours), using +#' \code{memory} days in the past.} +#' \item{\code{predictShape(data,today,memory,predict_from,horizon,...)}}{ +#' Predict the shape of the next curve (at index today) from predict_from to horizon +#' (hours), using \code{memory} days in the past.} +#' \item{\code{getParameters()}}{ +#' Return (internal) parameters.} +#' } #' #' @docType class -#' @importFrom R6 R6Class +#' @format R6 class +#' Forecaster = R6::R6Class("Forecaster", private = list( - .params = "list", - .data = "Data", - .pjump = "function" + .params = list(), + .pjump = NULL ), public = list( - initialize = function(data, pjump) - initialize(self, private, data, pjump) - , - predictSerie = function(today, memory, horizon, ...) - predictSerie(private, today, memory, horizon, ...) - , - predictShape = function(today, memory, horizon, ...) - predictShape(private, today, memory, horizon, ...) + initialize = function(pjump) + { + private$.pjump <- pjump + invisible(self) + }, + predictSerie = function(data, today, memory, predict_from, horizon, ...) + { + # Parameters (potentially) computed during shape prediction stage + predicted_shape <- self$predictShape(data,today,memory,predict_from,horizon,...) + predicted_delta <- + if (is.null(private$.pjump)) + NULL + else + private$.pjump(data,today,memory,predict_from,horizon,private$.params,...) + + # Predicted shape is aligned on the end of current day + jump (if jump!=NULL) + c( data$getSerie(today)[if (predict_from>=2) 1:(predict_from-1) else c()], + predicted_shape + ifelse( is.null(private$.pjump), + 0, + predicted_delta - predicted_shape[1] + + ifelse(predict_from>=2, + data$getSerie(today)[predict_from-1], tail(data$getSerie(today-1),1)) ) ) + }, + predictShape = function(data, today, memory, predict_from, horizon, ...) + NULL #empty default implementation: to implement in inherited classes , getParameters = function() - getParameters(private) + private$.params ) ) - -#' Initialize (generic) Forecaster object -#' -#' @param o Object of class Forecaster -#' @param private List of private members in o -#' @param data Object of class Data -#' @param pjump Function to predict jump -initialize = function(o, private, data, pjump) -{ - .params <<- list() - .data <<- data - .pjump <<- pjump - invisible(o) -} - -#' Obtain a new forecasted time-serie -#' -#' @inheritParams initialize -#' @param today Index for current prediction -#' @param memory Depth in data (in days) -#' @param horizon Number of hours to forecast -predictSerie = function(private, today, memory, horizon, ...) -{ - # Parameters (potentially) computed during shape prediction stage - predicted_shape = predictShape(today, memory, horizon, ...) - predicted_delta = private$.pjump(private$.data, today, memory, horizon, params, ...) - # Predicted shape is aligned it on the end of current day + jump - predicted_shape + tail(private$.data$getSerie(today),1) - predicted_shape[1] + predicted_delta -} - -#' Shape prediction (centered curve) -#' -#' @inheritParams predictSerie -predictShape = function(private, today, memory, horizon, ...) - #empty default implementation: to implement in inherited classes - -#' Get parameters list -#' -#' @inheritParams initialize -getParameters = function(private) - private$.params