Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,4 @@ Encoding: UTF-8
Language: en-GB
Roxygen: list(markdown = TRUE, roclets=c('rd', 'collate',
'namespace'))
RoxygenNote: 7.3.2
RoxygenNote: 7.3.3
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ S3method(glance,model_mean)
S3method(hfitted,ARIMA)
S3method(hfitted,ETS)
S3method(interpolate,ARIMA)
S3method(interpolate,ETS)
S3method(interpolate,TSLM)
S3method(interpolate,model_mean)
S3method(model_sum,AR)
Expand Down
30 changes: 24 additions & 6 deletions R/ets.R
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@ train_ets <- function(.data, specials, opt_crit,
y <- unclass(.data)[[measured_vars(.data)]]
idx <- unclass(.data)[[index_var(.data)]]

if (any(is.na(y))) {
abort("ETS does not support missing values.")
}

# Build possible models
model_opts <- expand.grid(
errortype = ets_spec$error$method,
Expand All @@ -33,7 +29,7 @@ train_ets <- function(.data, specials, opt_crit,

# Remove bad models
if (NROW(model_opts) > 1) {
if (min(y) <= 0) {
if (min(y, na.rm = TRUE) <= 0) {
model_opts <- model_opts[model_opts$errortype != "M", ]
}
if (restrict) {
Expand Down Expand Up @@ -720,4 +716,26 @@ initial_ets_states <- function(object) {
)
colnames(states_init) <- unsplit(states_names, states_type)
states_init
}
}


#' @inherit interpolate.model_mean
#'
#' @examples
#' library(tsibbledata)
#'
#' olympic_running |>
#' model(mean = ETS(Time)) %>%
#' interpolate(olympic_running)
#' @export
interpolate.ETS <- function(object, new_data, specials, ...) {
# Get missing values
y <- unclass(new_data)[[measured_vars(new_data)]]
miss_val <- which(is.na(y))
# Forward fitted values
forward_fits <- object$est[[".fitted"]][miss_val]
# Ideally, we would also apply the model to the reversed time series
# and get the backward fitted values, then combine the two.
new_data[[measured_vars(new_data)]][miss_val] <- forward_fits
new_data
}
18 changes: 5 additions & 13 deletions R/etsmodel.R
Original file line number Diff line number Diff line change
Expand Up @@ -140,16 +140,11 @@ estimate_ets <- function(y, m, init.state, errortype, trendtype, seasontype,
alpha = unname(alpha), beta = unname(beta),
gamma = unname(gamma), phi = unname(phi), init.state
)
if (errortype == "A") {
fits <- y - e$e
} else {
fits <- y / (1 + e$e)
}

return(list(
loglik = -0.5 * e$lik, aic = aic, bic = bic, aicc = aicc,
mse = mse, amse = amse, mae = mae,
residuals = e$e, fitted = fits,
residuals = e$e, fitted = e$fits,
states = states, par = fit.par
))
}
Expand Down Expand Up @@ -429,7 +424,7 @@ pegelsresid.C <- function(y, m, init.state, errortype, trendtype, seasontype, da
p <- length(init.state)
x <- numeric(p * (n + 1))
x[1:p] <- init.state
e <- numeric(n)
e <- fits <- numeric(n)
lik <- 0
if (!damped) {
phi <- 1
Expand Down Expand Up @@ -457,18 +452,15 @@ pegelsresid.C <- function(y, m, init.state, errortype, trendtype, seasontype, da
as.double(gamma),
as.double(phi),
as.double(e),
as.double(fits),
as.double(lik),
as.double(amse),
as.integer(nmse),
NAOK = TRUE,
PACKAGE = "fable"
)
if (!is.na(Cout[[13]])) {
if (abs(Cout[[13]] + 99999) < 1e-7) {
Cout[[13]] <- NA
}
}

return(list(lik = Cout[[13]], amse = Cout[[14]], e = Cout[[12]], states = matrix(Cout[[3]], nrow = n + 1, ncol = p, byrow = TRUE)))
return(list(lik = Cout[[14]], amse = Cout[[15]], e = Cout[[12]], fits = Cout[[13]], states = matrix(Cout[[3]], nrow = n + 1, ncol = p, byrow = TRUE)))
}

admissible <- function(alpha, beta, gamma, phi, m) {
Expand Down
30 changes: 30 additions & 0 deletions man/interpolate.ETS.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/etsTargetFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ void EtsTargetFunction::init(std::vector<double> & p_y, int p_nstate, int p_erro
// for(int i=0; i < n; i++) this->e.push_back(0);
this->amse.resize(30, 0);
this->e.resize(n, 0);
this->fits.resize(n, 0);

}

Expand Down Expand Up @@ -165,8 +166,7 @@ void EtsTargetFunction::eval(const double* p_par, int p_par_length) {
for(int i=0; i <= p*this->y.size(); i++) state.push_back(0);

etscalc(&this->y[0], &this->n, &this->state[0], &this->m, &this->errortype, &this->trendtype, &this->seasontype,
&this->alpha, &this->beta, &this->gamma, &this->phi, &this->e[0], &this->lik, &this->amse[0], &this->nmse);

&this->alpha, &this->beta, &this->gamma, &this->phi, &this->e[0], &this->fits[0], &this->lik, &this->amse[0], &this->nmse);

// Avoid perfect fits
if (this->lik < -1e10) this->lik = -1e10;
Expand Down
6 changes: 2 additions & 4 deletions src/etsTargetFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,9 @@
extern "C" {

void etscalc(double *, int *, double *, int *, int *, int *, int *,
double *, double *, double *, double *, double *, double *, double *, int *);
double *, double *, double *, double *, double *, double *, double *, double *, int *);

void cpolyroot(double *opr, double *opi, int *degree,
double *zeror, double *zeroi, Rboolean *fail);
}

class EtsTargetFunction {

public:
Expand Down Expand Up @@ -53,6 +50,7 @@ class EtsTargetFunction {
double alpha, beta, gamma, phi;

std::vector<double> e;
std::vector<double> fits;
std::vector<double> amse;

double lik, objval;
Expand Down
Loading