# ces() - Complex Exponential Smoothing

#### Ivan Svetunkov

#### 2025-10-24

This vignette covers `ces()` and `auto.ces()` functions, which are part of smooth package.

Let’s load the necessary packages:

    require(smooth)

`ces()` function allows constructing Complex Exponential Smoothing either with no seasonality, or with simple/partial/full one. A simple call for `ces()` results in estimation of non-seasonal model:

For the same series from M3 dataset `ces()` can be constructed using:

    ces(BJsales, h=12, holdout=TRUE, silent=FALSE)

    ## Time elapsed: 0.03 seconds
    ## Model estimated using ces() function: CES(none)
    ## With backcasting initialisation
    ## Distribution assumed in the model: Normal
    ## Loss function type: likelihood; Loss function value: 250.0863
    ##         a0+ia1
    ## 1.9975+1.0033i
    ##
    ## Sample size: 138
    ## Number of estimated parameters: 3
    ## Number of degrees of freedom: 135
    ## Information criteria:
    ##      AIC     AICc      BIC     BICc
    ## 506.1726 506.3517 514.9544 515.3956
    ##
    ## Forecast errors:
    ## ME: 0.184; MAE: 1.014; RMSE: 1.319
    ## sCE: 0.973%; Asymmetry: 5.6%; sMAE: 0.446%; sMSE: 0.003%
    ## MASE: 0.851; RMSSE: 0.86; rMAE: 0.327; rRMSE: 0.344

This output is very similar to ones printed out by `adam()` function. The only difference is complex smoothing parameter values which are printed out instead of persistence vector in `adam()`.

If we want automatic model selection, then we use `auto.ces()` function:

    auto.ces(AirPassengers, h=12, holdout=TRUE, silent=FALSE)

    ## Estimating CES with seasonality: "none" "simple" "partial" "full"
    ## The best model is with seasonality = "partial"

    ## Time elapsed: 0.13 seconds
    ## Model estimated using ces() function: CES(partial)
    ## With backcasting initialisation
    ## Distribution assumed in the model: Normal
    ## Loss function type: likelihood; Loss function value: 516.9014
    ##  a0+ia1
    ## 1.49+1i
    ##      b
    ## 0.9485
    ##
    ## Sample size: 132
    ## Number of estimated parameters: 4
    ## Number of degrees of freedom: 128
    ## Information criteria:
    ##      AIC     AICc      BIC     BICc
    ## 1041.803 1042.118 1053.334 1054.103
    ##
    ## Forecast errors:
    ## ME: 10.817; MAE: 18.844; RMSE: 22.061
    ## sCE: 49.452%; Asymmetry: 66.7%; sMAE: 7.179%; sMSE: 0.706%
    ## MASE: 0.782; RMSSE: 0.704; rMAE: 0.248; rRMSE: 0.214

By default, the function optimises the initial values, but other options (“backcasting” and “complete”) are supported as well:

    ces(BJsales, h=12, holdout=TRUE, initial="back")

    ## Time elapsed: 0.03 seconds
    ## Model estimated using ces() function: CES(none)
    ## With backcasting initialisation
    ## Distribution assumed in the model: Normal
    ## Loss function type: likelihood; Loss function value: 250.0863
    ##         a0+ia1
    ## 1.9975+1.0033i
    ##
    ## Sample size: 138
    ## Number of estimated parameters: 3
    ## Number of degrees of freedom: 135
    ## Information criteria:
    ##      AIC     AICc      BIC     BICc
    ## 506.1726 506.3517 514.9544 515.3956
    ##
    ## Forecast errors:
    ## ME: 0.184; MAE: 1.014; RMSE: 1.319
    ## sCE: 0.973%; Asymmetry: 5.6%; sMAE: 0.446%; sMSE: 0.003%
    ## MASE: 0.851; RMSSE: 0.86; rMAE: 0.327; rRMSE: 0.344

The function also works with explanatory variables if the data frame or a matrix is provided instead of the vector of values:

    BJData <- cbind(y=BJsales, x=BJsales.lead)
    cesModel <- ces(BJData, h=12, holdout=TRUE, regressors="use")

Finally, all the main methods for the adam function are supported by `ces()` as well. For example, here how we can produce prediction interval:

    forecast(cesModel, h=12, interval="pred") |> plot()