├── .Rbuildignore
├── .github
└── workflows
│ ├── python_ci.yml
│ ├── revdep.yaml
│ ├── rhub.yaml
│ └── test.yml
├── .gitignore
├── .gitmodules
├── CRAN-RELEASE
├── CRAN-SUBMISSION
├── DESCRIPTION
├── NAMESPACE
├── NEWS
├── R
├── RcppExports.R
├── adam-ces.R
├── adam-es.R
├── adam-gum.R
├── adam-msarima.R
├── adam-sma.R
├── adam-ssarima.R
├── adam.R
├── adamGeneral.R
├── arimaCompact.R
├── autoadam.R
├── autoces.R
├── autogum.R
├── automsarima.R
├── autossarima.R
├── ces.R
├── cma.R
├── depricator.R
├── es.R
├── gum.R
├── isFunctions.R
├── iss.R
├── methods.R
├── msarima.R
├── msdecompose.R
├── oes.R
├── oesg.R
├── randomARIMA.R
├── simces.R
├── simes.R
├── simgum.R
├── simoes.R
├── simsma.R
├── simssarima.R
├── sm.R
├── sma.R
├── smooth-package.R
├── smoothCombine.R
├── sowhat.R
├── ssarima.R
├── ssfunctions.R
├── variance-covariance.R
└── zzz.R
├── README.md
├── cran-comments.md
├── man-roxygen
├── ADAMDataFormulaRegLossSilentHHoldout.R
├── ADAMInitial.R
├── smoothRef.R
├── ssADAMRef.R
├── ssARIMARef.R
├── ssAdvancedParam.R
├── ssAuthor.R
├── ssBasicParam.R
├── ssCESRef.R
├── ssETSRef.R
├── ssGeneralRef.R
├── ssInitialParam.R
├── ssIntermittentRef.R
├── ssIntervals.R
├── ssIntervalsRef.R
├── ssKeywords.R
├── ssPersistenceParam.R
├── ssSimParam.R
└── ssXregParam.R
├── man
├── accuracy.Rd
├── adam.Rd
├── ces.Rd
├── cma.Rd
├── es.Rd
├── figures
│ └── smooth-web.png
├── forecast.smooth.Rd
├── gum.Rd
├── isFunctions.Rd
├── msarima.Rd
├── msdecompose.Rd
├── multicov.Rd
├── oes.Rd
├── oesg.Rd
├── orders.Rd
├── plot.smooth.Rd
├── pls.Rd
├── reapply.Rd
├── reexports.Rd
├── rmultistep.Rd
├── sim.ces.Rd
├── sim.es.Rd
├── sim.gum.Rd
├── sim.oes.Rd
├── sim.sma.Rd
├── sim.ssarima.Rd
├── sma.Rd
├── smooth.Rd
├── smoothCombine.Rd
├── sowhat.Rd
└── ssarima.Rd
├── python
├── CMakeLists.txt
├── Makefile
├── README.md
├── pyproject.toml
├── setup.cfg
└── smooth
│ ├── __init__.py
│ └── adam_general
│ ├── __init__.py
│ ├── adam_profile.py
│ ├── core
│ ├── __init__.py
│ ├── adam.py
│ ├── checker.py
│ ├── creator.py
│ ├── estimator.py
│ ├── forecaster.py
│ ├── sma.py
│ └── utils
│ │ ├── cost_functions.py
│ │ ├── dump.py
│ │ ├── ic.py
│ │ ├── likelihood.py
│ │ ├── polynomials.py
│ │ └── utils.py
│ ├── load_r_package.py
│ ├── sma.py
│ ├── test.py
│ ├── test_3.ipynb
│ ├── test_adam.ipynb
│ ├── test_adam_r.ipynb
│ ├── test_script.py
│ ├── tests.ipynb
│ └── tests_2.ipynb
├── smooth.Rproj
├── src
├── Makevars
├── Makevars.win
├── RcppExports.cpp
├── adamGeneral.cpp
├── adamGeneral.h
├── adamRefitter.cpp
├── adamSimulator.cpp
├── matrixPowerWrap.cpp
├── python_examples
│ ├── adamGeneral copy.cpp
│ ├── adamGeneral.cpp
│ ├── adamGeneral.h
│ └── my_linalg.cpp
├── registerDynamicSymbol.c
├── ssGeneral.cpp
├── ssGeneral.h
├── ssOccurrence.cpp
└── ssSimulator.cpp
├── tests
├── testthat.R
└── testthat
│ ├── test_adam.R
│ ├── test_ces.R
│ ├── test_es.R
│ ├── test_gum.R
│ ├── test_oes.R
│ ├── test_simulate.R
│ └── test_ssarima.R
└── vignettes
├── .install_extras
├── adam.Rmd
├── ces.Rmd
├── es.Rmd
├── gum.Rmd
├── library.bib
├── oes.Rmd
├── simulate.Rmd
├── sma.Rmd
├── smooth-Documentation.pdf
├── smooth.Rmd
└── ssarima.Rmd
/.Rbuildignore:
--------------------------------------------------------------------------------
1 | ^CRAN-RELEASE$
2 | ^Meta$
3 | ^doc$
4 | ^.*\.Rproj$
5 | ^\.Rproj\.user$
6 | .github
7 | vignettes/rsconnect
8 | man-roxygen
9 | ^revdep$
10 | cran-comments.md
11 | ^CRAN-SUBMISSION$
12 | ^python
13 | ^src/python_examples
14 | ^src/libs
15 | dev_load.R
16 |
--------------------------------------------------------------------------------
/.github/workflows/python_ci.yml:
--------------------------------------------------------------------------------
1 | name: Python CI
2 |
3 | on:
4 | push:
5 | branches: [Python]
6 | pull_request:
7 | branches: [Python]
8 |
9 | jobs:
10 | linting:
11 | runs-on: ubuntu-latest
12 | steps:
13 | - uses: actions/checkout@v4
14 | - uses: chartboost/ruff-action@v1
15 | with:
16 | src: "./python"
17 |
--------------------------------------------------------------------------------
/.github/workflows/revdep.yaml:
--------------------------------------------------------------------------------
1 | name: R-Revdep-check
2 |
3 | on:
4 | workflow_dispatch:
5 |
6 | jobs:
7 | R-CMD-check:
8 | runs-on: ${{ matrix.config.os }}
9 |
10 | name: ${{ matrix.config.os }} (${{ matrix.config.r }})
11 |
12 | strategy:
13 | fail-fast: false
14 | matrix:
15 | config:
16 | # - {os: macos-latest, r: 'release'}
17 | # - {os: windows-latest, r: 'release'}
18 | #- {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'}
19 | - {os: ubuntu-latest, r: 'release'}
20 | #- {os: ubuntu-latest, r: 'oldrel-1'}
21 |
22 | env:
23 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
24 | R_KEEP_PKG_SOURCE: yes
25 |
26 | steps:
27 | - uses: actions/checkout@v4
28 |
29 | - uses: r-lib/actions/setup-pandoc@v2
30 |
31 | - uses: r-lib/actions/setup-r@v2
32 | with:
33 | r-version: ${{ matrix.config.r }}
34 | http-user-agent: ${{ matrix.config.http-user-agent }}
35 | use-public-rspm: true
36 |
37 | - uses: r-lib/actions/setup-r-dependencies@v2
38 | with:
39 | # Don't check suggests to avoid Windows issues with doMC
40 | cache: false
41 | extra-packages: |
42 | any::rcmdcheck
43 | any::testthat
44 | any::knitr
45 | any::rmarkdown
46 | any::numDeriv
47 | any::doParallel
48 | any::foreach
49 | any::remotes
50 | needs: check
51 |
52 | - name: Install revdepcheck
53 | run: |
54 | Rscript -e 'remotes::install_github("r-lib/revdepcheck")'
55 |
56 | - name: Run revdepcheck
57 | run: |
58 | Rscript -e 'revdepcheck::revdep_check(num_workers = 4)'
59 |
--------------------------------------------------------------------------------
/.github/workflows/rhub.yaml:
--------------------------------------------------------------------------------
1 | # R-hub's generic GitHub Actions workflow file. It's canonical location is at
2 | # https://github.com/r-hub/actions/blob/v1/workflows/rhub.yaml
3 | # You can update this file to a newer version using the rhub2 package:
4 | #
5 | # rhub::rhub_setup()
6 | #
7 | # It is unlikely that you need to modify this file manually.
8 |
9 | name: R-hub
10 | run-name: "${{ github.event.inputs.id }}: ${{ github.event.inputs.name || format('Manually run by {0}', github.triggering_actor) }}"
11 |
12 | on:
13 | workflow_dispatch:
14 | inputs:
15 | config:
16 | description: 'A comma separated list of R-hub platforms to use.'
17 | type: string
18 | default: 'linux,windows,macos'
19 | name:
20 | description: 'Run name. You can leave this empty now.'
21 | type: string
22 | id:
23 | description: 'Unique ID. You can leave this empty now.'
24 | type: string
25 |
26 | jobs:
27 |
28 | setup:
29 | runs-on: ubuntu-latest
30 | outputs:
31 | containers: ${{ steps.rhub-setup.outputs.containers }}
32 | platforms: ${{ steps.rhub-setup.outputs.platforms }}
33 |
34 | steps:
35 | # NO NEED TO CHECKOUT HERE
36 | - uses: r-hub/actions/setup@v1
37 | with:
38 | config: ${{ github.event.inputs.config }}
39 | id: rhub-setup
40 |
41 | linux-containers:
42 | needs: setup
43 | if: ${{ needs.setup.outputs.containers != '[]' }}
44 | runs-on: ubuntu-latest
45 | name: ${{ matrix.config.label }}
46 | strategy:
47 | fail-fast: false
48 | matrix:
49 | config: ${{ fromJson(needs.setup.outputs.containers) }}
50 | container:
51 | image: ${{ matrix.config.container }}
52 |
53 | steps:
54 | - uses: r-hub/actions/checkout@v1
55 | - uses: r-hub/actions/platform-info@v1
56 | with:
57 | token: ${{ secrets.RHUB_TOKEN }}
58 | job-config: ${{ matrix.config.job-config }}
59 | - uses: r-hub/actions/setup-deps@v1
60 | with:
61 | token: ${{ secrets.RHUB_TOKEN }}
62 | job-config: ${{ matrix.config.job-config }}
63 | - uses: r-hub/actions/run-check@v1
64 | with:
65 | token: ${{ secrets.RHUB_TOKEN }}
66 | job-config: ${{ matrix.config.job-config }}
67 |
68 | other-platforms:
69 | needs: setup
70 | if: ${{ needs.setup.outputs.platforms != '[]' }}
71 | runs-on: ${{ matrix.config.os }}
72 | name: ${{ matrix.config.label }}
73 | strategy:
74 | fail-fast: false
75 | matrix:
76 | config: ${{ fromJson(needs.setup.outputs.platforms) }}
77 |
78 | steps:
79 | - uses: r-hub/actions/checkout@v1
80 | - uses: r-hub/actions/setup-r@v1
81 | with:
82 | job-config: ${{ matrix.config.job-config }}
83 | token: ${{ secrets.RHUB_TOKEN }}
84 | - uses: r-hub/actions/platform-info@v1
85 | with:
86 | token: ${{ secrets.RHUB_TOKEN }}
87 | job-config: ${{ matrix.config.job-config }}
88 | - uses: r-hub/actions/setup-deps@v1
89 | with:
90 | job-config: ${{ matrix.config.job-config }}
91 | token: ${{ secrets.RHUB_TOKEN }}
92 | - uses: r-hub/actions/run-check@v1
93 | with:
94 | job-config: ${{ matrix.config.job-config }}
95 | token: ${{ secrets.RHUB_TOKEN }}
96 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: R-CMD-check
2 |
3 | on:
4 | pull_request:
5 | workflow_dispatch:
6 | schedule:
7 | - cron: '0 0 * * 1'
8 |
9 | jobs:
10 | R-CMD-check:
11 | runs-on: ${{ matrix.config.os }}
12 |
13 | name: ${{ matrix.config.os }} (${{ matrix.config.r }})
14 |
15 | strategy:
16 | fail-fast: false
17 | matrix:
18 | config:
19 | - {os: macos-latest, r: 'release'}
20 | - {os: windows-latest, r: 'release'}
21 | #- {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'}
22 | - {os: ubuntu-latest, r: 'release'}
23 | #- {os: ubuntu-latest, r: 'oldrel-1'}
24 |
25 | env:
26 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
27 | R_KEEP_PKG_SOURCE: yes
28 |
29 | steps:
30 | - uses: actions/checkout@v4
31 |
32 | - uses: r-lib/actions/setup-pandoc@v2
33 |
34 | - uses: r-lib/actions/setup-r@v2
35 | with:
36 | r-version: ${{ matrix.config.r }}
37 | http-user-agent: ${{ matrix.config.http-user-agent }}
38 | use-public-rspm: true
39 |
40 | - uses: r-lib/actions/setup-r-dependencies@v2
41 | with:
42 | # Don't check suggests to avoid Windows issues with doMC
43 | dependencies: '"hard"'
44 | cache: false
45 | extra-packages: |
46 | any::rcmdcheck
47 | any::testthat
48 | any::knitr
49 | any::rmarkdown
50 | any::numDeriv
51 | any::doParallel
52 | any::foreach
53 | needs: check
54 |
55 | - uses: r-lib/actions/check-r-package@v2
56 | with:
57 | upload-snapshots: true
58 | build_args: 'c("--no-manual","--compact-vignettes=gs+qpdf")'
59 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | Meta
2 | doc
3 | # History files
4 | .Rhistory
5 | .Rapp.history
6 | # Session Data files
7 | .RData
8 | # RStudio files
9 | .Rproj.user/
10 | # bak files
11 | *.bak
12 | # produced vignettes
13 | # OAuth2 token, see https://github.com/hadley/httr/releases/tag/v0.3
14 | .httr-oauth
15 | # stuff precompiled by R
16 | src/*.o
17 | src/*.so
18 | src/*.dll
19 | .directory
20 | .Rproj.user
21 | inst/doc/*.html
22 | inst/doc/*.R
23 | inst/doc/*.Rmd
24 | vignettes/rsconnect
25 | vignettes/Figs
26 | # Rprofile
27 | .Rprofile
28 |
29 | ########################
30 | ### python gitignore ###
31 | ########################
32 |
33 | # Byte-compiled / optimized / DLL files
34 | __pycache__/
35 | *.py[cod]
36 | *$py.class
37 |
38 | # C extensions
39 | *.so
40 |
41 | # Distribution / packaging
42 | .Python
43 | build/
44 | develop-eggs/
45 | dist/
46 | downloads/
47 | eggs/
48 | .eggs/
49 | lib/
50 | lib64/
51 | parts/
52 | sdist/
53 | var/
54 | wheels/
55 | pip-wheel-metadata/
56 | share/python-wheels/
57 | *.egg-info/
58 | .installed.cfg
59 | *.egg
60 | MANIFEST
61 |
62 | # PyInstaller
63 | # Usually these files are written by a python script from a template
64 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
65 | *.manifest
66 | *.spec
67 |
68 | # Installer logs
69 | pip-log.txt
70 | pip-delete-this-directory.txt
71 |
72 | # Unit test / coverage reports
73 | htmlcov/
74 | .tox/
75 | .nox/
76 | .coverage
77 | .coverage.*
78 | .cache
79 | nosetests.xml
80 | coverage.xml
81 | *.cover
82 | *.py,cover
83 | .hypothesis/
84 | .pytest_cache/
85 |
86 | # Translations
87 | *.mo
88 | *.pot
89 |
90 | # Django stuff:
91 | *.log
92 | local_settings.py
93 | db.sqlite3
94 | db.sqlite3-journal
95 |
96 | # Flask stuff:
97 | instance/
98 | .webassets-cache
99 |
100 | # Scrapy stuff:
101 | .scrapy
102 |
103 | # Sphinx documentation
104 | docs/_build/
105 |
106 | # PyBuilder
107 | target/
108 |
109 | # Jupyter Notebook
110 | .ipynb_checkpoints
111 |
112 | # IPython
113 | profile_default/
114 | ipython_config.py
115 |
116 | # pyenv
117 | .python-version
118 |
119 | # pipenv
120 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
121 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
122 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
123 | # install all needed dependencies.
124 | #Pipfile.lock
125 |
126 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow
127 | __pypackages__/
128 |
129 | # Celery stuff
130 | celerybeat-schedule
131 | celerybeat.pid
132 |
133 | # SageMath parsed files
134 | *.sage.py
135 |
136 | # Environments
137 | .env
138 | .venv
139 | env/
140 | venv/
141 | ENV/
142 | env.bak/
143 | venv.bak/
144 |
145 | # Spyder project settings
146 | .spyderproject
147 | .spyproject
148 |
149 | # Rope project settings
150 | .ropeproject
151 |
152 | # mkdocs documentation
153 | /site
154 |
155 | # mypy
156 | .mypy_cache/
157 | .dmypy.json
158 | dmypy.json
159 |
160 | # Pyre type checker
161 | .pyre/
162 |
163 | #IDEs
164 | .vscode
165 |
166 | # memory system file
167 | .DS_Store
168 |
169 | #vim swap files
170 | *.swp
171 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "src/libs/carma"]
2 | path = src/libs/carma
3 | url = https://github.com/RUrlus/carma.git
4 |
--------------------------------------------------------------------------------
/CRAN-RELEASE:
--------------------------------------------------------------------------------
1 | This package was submitted to CRAN on 2021-12-01.
2 | Once it is accepted, delete this file and tag the release (commit 944d190).
3 |
--------------------------------------------------------------------------------
/CRAN-SUBMISSION:
--------------------------------------------------------------------------------
1 | Version: 4.2.0
2 | Date: 2025-04-02 15:23:55 UTC
3 | SHA: 970bef2a416d48314c7105d8dd4214385f5d2231
4 |
--------------------------------------------------------------------------------
/DESCRIPTION:
--------------------------------------------------------------------------------
1 | Package: smooth
2 | Type: Package
3 | Title: Forecasting Using State Space Models
4 | Version: 4.3.0.41005
5 | Date: 2025-06-03
6 | Authors@R: person("Ivan", "Svetunkov", email = "ivan@svetunkov.com", role = c("aut", "cre"),
7 | comment="Senior Lecturer at Centre for Marketing Analytics and Forecasting, Lancaster University, UK")
8 | URL: https://github.com/config-i1/smooth
9 | BugReports: https://github.com/config-i1/smooth/issues
10 | Language: en-GB
11 | Description: Functions implementing Single Source of Error state space models for purposes of time series analysis and forecasting.
12 | The package includes ADAM (Svetunkov, 2023, ),
13 | Exponential Smoothing (Hyndman et al., 2008, ),
14 | SARIMA (Svetunkov & Boylan, 2019 ),
15 | Complex Exponential Smoothing (Svetunkov & Kourentzes, 2018, ),
16 | Simple Moving Average (Svetunkov & Petropoulos, 2018 )
17 | and several simulation functions. It also allows dealing with intermittent demand based on the
18 | iETS framework (Svetunkov & Boylan, 2019, ).
19 | License: LGPL-2.1
20 | Depends:
21 | R (>= 3.0.2),
22 | greybox (>= 2.0.2)
23 | Imports:
24 | Rcpp (>= 0.12.3),
25 | stats,
26 | generics (>= 0.1.2),
27 | graphics,
28 | grDevices,
29 | pracma,
30 | statmod,
31 | MASS,
32 | nloptr,
33 | utils,
34 | xtable,
35 | zoo
36 | LinkingTo: Rcpp, RcppArmadillo (>= 0.8.100.0.0)
37 | Suggests:
38 | legion,
39 | numDeriv,
40 | testthat,
41 | knitr,
42 | rmarkdown,
43 | doMC,
44 | doParallel,
45 | foreach
46 | VignetteBuilder: knitr
47 | RoxygenNote: 7.3.2
48 | Encoding: UTF-8
49 | Roxygen: list(old_usage = TRUE)
50 | ByteCompile: true
51 |
--------------------------------------------------------------------------------
/R/arimaCompact.R:
--------------------------------------------------------------------------------
1 | # arimaCompact <- function(y, lags=c(1,frequency(y)), ic=c("AICc","AIC","BIC","BICc"), ...){
2 | #
3 | # # Start measuring the time of calculations
4 | # startTime <- Sys.time();
5 | #
6 | # # If there are no lags for the basic components, correct this.
7 | # if(sum(lags==1)==0){
8 | # lags <- c(1,lags);
9 | # }
10 | #
11 | # orderLength <- length(lags);
12 | # ic <- match.arg(ic);
13 | # IC <- switch(ic,
14 | # "AIC"=AIC,
15 | # "AICc"=AICc,
16 | # "BIC"=BIC,
17 | # "BICc"=BICc);
18 | #
19 | # # We consider the following list of models:
20 | # # ARIMA(0,1,1), (1,1,2), (0,2,2),
21 | # # ARIMA(0,0,0)+c, ARIMA(0,1,1)+c,
22 | # # seasonal orders (0,1,1), (1,1,2), (0,2,2)
23 | # # And all combinations between seasonal and non-seasonal parts
24 | # #
25 | # # Encode all non-seasonal parts
26 | # nNonSeasonal <- 5
27 | # arimaNonSeasonal <- matrix(c(0,0,0,1, 0,1,1,0, 0,1,1,1, 1,1,2,0, 0,2,2,0), nNonSeasonal,4,
28 | # dimnames=list(NULL, c("ar","i","ma","const")), byrow=TRUE)
29 | # # Encode all seasonal parts ()
30 | # nSeasonal <- 4
31 | # arimaSeasonal <- matrix(c(0,0,0, 0,1,1, 1,1,2, 0,2,2), nSeasonal,3,
32 | # dimnames=list(NULL, c("sar","si","sma")), byrow=TRUE)
33 | #
34 | # # Check all the models in the pool
35 | # testModels <- vector("list", nSeasonal*nNonSeasonal);
36 | # stop <- FALSE;
37 | # m <- 1;
38 | # for(i in 1:nSeasonal){
39 | # for(j in 1:nNonSeasonal){
40 | # testModels[[m]] <- msarima(y, orders=list(ar=c(arimaNonSeasonal[j,1],arimaSeasonal[i,1]),
41 | # i=c(arimaNonSeasonal[j,2],arimaSeasonal[i,2]),
42 | # ma=c(arimaNonSeasonal[j,3],arimaSeasonal[i,3])),
43 | # constant=arimaNonSeasonal[j,4]==1, lags=lags, ...);
44 | # # If SARIMA(0,1,1)(0,1,1) is worse than ARIMA(0,1,1), don't check other seasonal models
45 | # # If SARIMA(0,1,1)(1,1,2) is worse than SARIMA(0,1,1)(0,1,1), stop
46 | # # etc
47 | # if(j==1 && i>1){
48 | # if(IC(testModels[[m-nNonSeasonal]])obsInSample){
30 | pFitted <- matrix(fitted(occurrenceModel)[1:obsInSample],obsInSample,1);
31 | }
32 | else if(length(fitted(occurrenceModel))=h){
42 | pForecast <- matrix(occurrenceModel$forecast[1:h],h,1);
43 | }
44 | else{
45 | pForecast <- matrix(c(occurrenceModel$forecast,
46 | rep(occurrenceModel$forecast[1],h-length(occurrenceModel$forecast))),h,1);
47 | }
48 |
49 | }
50 | }
51 | else{
52 | obsNonzero <- obsInSample;
53 | obsZero <- 0;
54 | }
55 |
56 | if(occurrence=="n"){
57 | ot <- rep(1,obsInSample);
58 | obsNonzero <- obsInSample;
59 | yot <- yInSample;
60 | pFitted <- matrix(1,obsInSample,1);
61 | pForecast <- matrix(1,h,1);
62 | nParamOccurrence <- 0;
63 | }
64 | ot <- ts(ot,start=dataStart,frequency=dataFreq);
65 |
66 | assign("ot",ot,ParentEnvironment);
67 | assign("obsNonzero",obsNonzero,ParentEnvironment);
68 | assign("obsZero",obsZero,ParentEnvironment);
69 | assign("yot",yot,ParentEnvironment);
70 | assign("pFitted",pFitted,ParentEnvironment);
71 | assign("pForecast",pForecast,ParentEnvironment);
72 | assign("nParamOccurrence",nParamOccurrence,ParentEnvironment);
73 | }
74 |
75 | intermittentMaker <- function(occurrence="n",...){
76 | # Function returns all the necessary stuff from occurrence models
77 | ellipsis <- list(...);
78 | ParentEnvironment <- ellipsis[['ParentEnvironment']];
79 |
80 | ##### If occurrence is not absent or provided, then work normally #####
81 | if(all(occurrence!=c("n","p"))){
82 | if(!occurrenceModelProvided){
83 | occurrenceModel <- oes(ot, model=occurrenceModel, occurrence=occurrence, h=h);
84 | }
85 | else{
86 | occurrenceModel <- oes(ot, model=occurrenceModel, h=h);
87 | }
88 | nParamOccurrence <- nparam(occurrenceModel);
89 | pFitted[,] <- fitted(occurrenceModel);
90 | pForecast <- occurrenceModel$forecast;
91 | occurrence <- occurrenceModel$occurrence;
92 | }
93 | else{
94 | occurrenceModel <- NULL;
95 | nParamOccurrence <- 0;
96 | }
97 |
98 | assign("occurrence",occurrence,ParentEnvironment);
99 | assign("pFitted",pFitted,ParentEnvironment);
100 | assign("pForecast",pForecast,ParentEnvironment);
101 | assign("nParamOccurrence",nParamOccurrence,ParentEnvironment);
102 | assign("occurrenceModel",occurrenceModel,ParentEnvironment);
103 | }
104 |
--------------------------------------------------------------------------------
/R/simsma.R:
--------------------------------------------------------------------------------
1 | #' Simulate Simple Moving Average
2 | #'
3 | #' Function generates data using SMA in a Single Source of Error state space
4 | #' model as a data generating process.
5 | #'
6 | #' For the information about the function, see the vignette:
7 | #' \code{vignette("simulate","smooth")}
8 | #'
9 | #' @template ssSimParam
10 | #' @template ssAuthor
11 | #' @template ssKeywords
12 | #'
13 | #' @template ssGeneralRef
14 | #'
15 | #' @param order Order of the modelled series. If omitted, then a random order from 1 to 100 is selected.
16 | #' @param initial Vector of initial states for the model. If \code{NULL},
17 | #' values are generated.
18 | #' @param ... Additional parameters passed to the chosen randomizer. All the
19 | #' parameters should be passed in the order they are used in chosen randomizer.
20 | #' For example, passing just \code{sd=0.5} to \code{rnorm} function will lead
21 | #' to the call \code{rnorm(obs, mean=0.5, sd=1)}.
22 | #'
23 | #' @return List of the following values is returned:
24 | #' \itemize{
25 | #' \item \code{model} - Name of SMA model.
26 | #' \item \code{data} - Time series vector (or matrix if \code{nsim>1}) of the generated
27 | #' series.
28 | #' \item \code{states} - Matrix (or array if \code{nsim>1}) of states. States are in
29 | #' columns, time is in rows.
30 | #' \item \code{initial} - Vector (or matrix) of initial values.
31 | #' \item \code{probability} - vector of probabilities used in the simulation.
32 | #' \item \code{intermittent} - type of the intermittent model used.
33 | #' \item \code{residuals} - Error terms used in the simulation. Either vector or matrix,
34 | #' depending on \code{nsim}.
35 | #' \item \code{occurrence} - Values of occurrence variable. Once again, can be either
36 | #' a vector or a matrix...
37 | #' \item \code{logLik} - Log-likelihood of the constructed model.
38 | #' }
39 | #'
40 | #' @seealso \code{\link[smooth]{es}, \link[stats]{ts}, \link[stats]{Distributions}}
41 | #'
42 | #' @examples
43 | #'
44 | #' # Create 40 observations of quarterly data using AAA model with errors from normal distribution
45 | #' sma10 <- sim.sma(order=10,frequency=4,obs=40,randomizer="rnorm",mean=0,sd=100)
46 | #'
47 | #' @export sim.sma
48 | sim.sma <- function(order=NULL, obs=10, nsim=1,
49 | frequency=1,
50 | initial=NULL,
51 | randomizer=c("rnorm","rt","rlaplace","rs"),
52 | probability=1, ...){
53 | # Function generates data using SMA model as a data generating process.
54 | # Copyright (C) 2017 Ivan Svetunkov
55 |
56 | randomizer <- randomizer[1];
57 |
58 | if(is.null(order)){
59 | order <- ceiling(runif(1,0,100));
60 | }
61 |
62 | # In the case of wrong nsim, make it natural number. The same is for obs and frequency.
63 | nsim <- abs(round(nsim,0));
64 | obs <- abs(round(obs,0));
65 | frequency <- abs(round(frequency,0));
66 |
67 | # Check the inital vector length
68 | if(!is.null(initial)){
69 | if(order!=length(initial)){
70 | warning(paste0("The length of initial state vector does not correspond to the chosen model!\n",
71 | "Falling back to random number generator."),call.=FALSE);
72 | initial <- NULL;
73 | }
74 | }
75 |
76 | ARIMAModel <- sim.ssarima(orders=list(ar=order,i=0,ma=0), lags=1,
77 | obs=obs, nsim=nsim,
78 | frequency=frequency, AR=rep(1/order,order), MA=NULL, constant=FALSE,
79 | initial=initial, bounds="none",
80 | randomizer=randomizer,
81 | probability=probability, ...)
82 |
83 | ARIMAModel$model <- paste0("SMA(",order,")");
84 | if(any(probability!=1)){
85 | ARIMAModel$model <- paste0("i",ARIMAModel$model);
86 | }
87 | ARIMAModel$AR <- NULL;
88 | ARIMAModel$MA <- NULL;
89 | ARIMAModel$constant <- NULL;
90 | return(ARIMAModel)
91 | }
92 |
--------------------------------------------------------------------------------
/R/smooth-package.R:
--------------------------------------------------------------------------------
1 | #' Smooth package
2 | #'
3 | #' Package contains functions implementing Single Source of Error state space models for
4 | #' purposes of time series analysis and forecasting.
5 | #'
6 | #' \tabular{ll}{ Package: \tab smooth\cr Type: \tab Package\cr Date: \tab
7 | #' 2016-01-27 - Inf\cr License: \tab GPL-2 \cr } The following functions are
8 | #' included in the package:
9 | #' \itemize{
10 | #' \item \link[smooth]{es} - Exponential Smoothing in Single Source of Errors State Space form.
11 | #' \item \link[smooth]{ces} - Complex Exponential Smoothing.
12 | #' \item \link[smooth]{gum} - Generalised Exponential Smoothing.
13 | #' \item \link[smooth]{ssarima} - SARIMA in state space framework.
14 | #' % \item \link[smooth]{nus} - Non-Uniform Smoothing.
15 | #' \item \link[smooth]{auto.ces} - Automatic selection between seasonal and non-seasonal CES.
16 | #' \item \link[smooth]{auto.ssarima} - Automatic selection of ARIMA orders.
17 | #' \item \link[smooth]{sma} - Simple Moving Average in state space form.
18 | #' \item \link[smooth]{smoothCombine} - the function that combines forecasts from es(),
19 | #' ces(), gum(), ssarima() and sma() functions.
20 | #' \item \link[smooth]{cma} - Centered Moving Average. This is for smoothing time series,
21 | #' not for forecasting.
22 | #' \item \link[smooth]{sim.es} - simulate time series using ETS as a model.
23 | #' \item \link[smooth]{sim.ces} - simulate time series using CES as a model.
24 | #' \item \link[smooth]{sim.ssarima} - simulate time series using SARIMA as a model.
25 | #' \item \link[smooth]{sim.gum} - simulate time series using GUM as a model.
26 | #' \item \link[smooth]{sim.sma} - simulate time series using SMA.
27 | #' \item \link[smooth]{sim.oes} - simulate time series based on occurrence part of ETS model.
28 | #' \item \link[smooth]{oes} - occurrence part of the intermittent state space model.
29 | #' }
30 | #' There are also several methods implemented in the package for the classes
31 | #' "smooth" and "smooth.sim":
32 | #' \itemize{
33 | #' \item \link[smooth]{orders} - extracts orders of the fitted model.
34 | #' \item lags - extracts lags of the fitted model.
35 | #' \item modelType - extracts type of the fitted model.
36 | #' \item forecast - produces forecast using provided model.
37 | #' \item \link[smooth]{multicov} - returns covariance matrix of multiple steps ahead forecast errors.
38 | #' \item \link[smooth]{pls} - returns Prediction Likelihood Score.
39 | #' \item \link[greybox]{nparam} - returns number of the estimated parameters.
40 | #' \item fitted - extracts fitted values from provided model.
41 | #' \item getResponse - returns actual values from the provided model.
42 | #' \item residuals - extracts residuals of provided model.
43 | #' \item plot - plots either states of the model or produced forecast (depending on what object
44 | #' is passed).
45 | #' \item simulate - uses sim functions (\link[smooth]{sim.es}, \link[smooth]{sim.ces},
46 | #' \link[smooth]{sim.ssarima}, \link[smooth]{sim.gum}, \link[smooth]{sim.sma} and
47 | #' \link[smooth]{sim.oes}) in order to simulate data using the provided object.
48 | #' \item summary - provides summary of the object.
49 | #' \item AICc, BICc - return, guess what...
50 | #' }
51 | #'
52 | #' @name smooth
53 | #' @aliases smooth-package
54 | #' @template ssAuthor
55 | #'
56 | #' @seealso \code{\link[greybox]{forecast}, \link[smooth]{es},
57 | #' \link[smooth]{ssarima}, \link[smooth]{ces}, \link[smooth]{gum}}
58 | #'
59 | #' @template ssGeneralRef
60 | #' @template ssIntermittentRef
61 | #' @template ssCESRef
62 | #' @template smoothRef
63 | #' @template ssETSRef
64 | #' @template ssIntervalsRef
65 | #' @template ssKeywords
66 | #'
67 | #' @examples
68 | #'
69 | #' \donttest{y <- ts(rnorm(100,10,3), frequency=12)
70 | #'
71 | #' adam(y, h=20, holdout=TRUE)
72 | #' es(y, h=20, holdout=TRUE)
73 | #' gum(y, h=20, holdout=TRUE)
74 | #' auto.ces(y, h=20, holdout=TRUE)
75 | #' auto.ssarima(y, h=20, holdout=TRUE)}
76 | #'
77 | #' @import zoo Rcpp
78 | #' @importFrom nloptr nloptr
79 | #' @importFrom graphics abline layout legend lines par points polygon
80 | #' @importFrom stats AIC BIC cov decompose median coef optimize nlminb cor var simulate lm as.formula residuals
81 | #' @importFrom stats dbeta qnorm qt qlnorm quantile rbinom rlnorm rnorm rt runif plnorm pnorm
82 | #' @importFrom stats deltat end frequency is.ts start time ts
83 | #' @importFrom utils packageVersion
84 | #' @importFrom greybox xregExpander stepwise qs qlaplace ps plaplace ds dlaplace graphmaker measures hm
85 | #' @useDynLib smooth
86 | NULL
87 |
--------------------------------------------------------------------------------
/R/sowhat.R:
--------------------------------------------------------------------------------
1 | #' Function returns the ultimate answer to any question
2 | #'
3 | #' You need a description? So what?
4 | #'
5 | #' You need details? So what?
6 | #'
7 | #' @param ... Any number of variables or string with a question.
8 | #' @return It doesn't return any value, only messages. So what?
9 | #' @template ssAuthor
10 | #' @seealso Nowwhat (to be implemented),
11 | #' @references \itemize{
12 | #' \item\href{https://en.wiktionary.org/wiki/so_what}{Sowhat?}
13 | #' \item\href{https://www.youtube.com/watch?v=FJfFZqTlWrQ}{Sowhat?}
14 | #' \item\href{https://en.wikipedia.org/wiki/Douglas_Adams}{42}
15 | #' }
16 | #' @keywords sowhat 42
17 | #' @examples
18 | #'
19 | #' x <- rnorm(10000,0,1);
20 | #' sowhat(x);
21 | #'
22 | #' sowhat("What's the meaning of life?")
23 | #'
24 | #' sowhat("I don't have a girlfriend.")
25 | #'
26 | #' @export sowhat
27 | sowhat <- function(...){
28 | # Function returns ultimate answer to any question
29 | if(any(grepl("\\?",unlist(list(...))))){
30 | message("42");
31 | }
32 | message("So what?");
33 | }
34 |
35 | # Function is needed to ask additional question before the release
36 | release_questions <- function(){
37 | c("i1: Did you check package with --use-valgrind if C++ code changed?");
38 | }
39 |
--------------------------------------------------------------------------------
/R/variance-covariance.R:
--------------------------------------------------------------------------------
1 | covarAnal <- function(lagsModel, h, measurement, transition, persistence, s2){
2 | # Function returns analytical conditional h-steps ahead covariance matrix
3 | # This is used in covar() method and in the construction of parametric prediction intervals
4 | covarMat <- diag(h);
5 | if(h > min(lagsModel)){
6 | lagsUnique <- unique(lagsModel);
7 | steps <- sort(lagsUnique[lagsUnique<=h]);
8 | stepsNumber <- length(steps);
9 | nComponents <- nrow(transition);
10 | arrayTransition <- array(0,c(nComponents,nComponents,stepsNumber));
11 | arrayMeasurement <- array(0,c(1,nComponents,stepsNumber));
12 | for(i in 1:stepsNumber){
13 | arrayTransition[,lagsModel==steps[i],i] <- transition[,lagsModel==steps[i]];
14 | arrayMeasurement[,lagsModel==steps[i],i] <- measurement[,lagsModel==steps[i]];
15 | }
16 | cValues <- rep(0,h);
17 |
18 | # Prepare transition array
19 | transitionPowered <- array(0,c(nComponents,nComponents,h,stepsNumber));
20 | transitionPowered[,,1:min(steps),] <- diag(nComponents);
21 |
22 | # Generate values for the transition matrix
23 | for(i in (min(steps)+1):h){
24 | for(k in 1:sum(steps1)){
30 | transitionNew <- arrayTransition[,,j];
31 | }
32 | else{
33 | transitionNew <- diag(nComponents);
34 | }
35 |
36 | # If this is a zero matrix, do simple multiplication
37 | if(all(transitionPowered[,,i,k]==0)){
38 | transitionPowered[,,i,k] <- (transitionNew %*%
39 | transitionPowered[,,i-steps[j],k]);
40 | }
41 | else{
42 | # Check that the multiplication is not an identity matrix
43 | if(!all((transitionNew %*% transitionPowered[,,i-steps[j],k])==diag(nComponents))){
44 | transitionPowered[,,i,k] <- transitionPowered[,,i,k] + (transitionNew %*%
45 | transitionPowered[,,i-steps[j],k]);
46 | }
47 | }
48 | }
49 | }
50 | # Copy the structure from the lower lags
51 | else{
52 | transitionPowered[,,i,k] <- transitionPowered[,,i-steps[k]+1,1];
53 | }
54 | # Generate values of cj
55 | cValues[i] <- cValues[i] + arrayMeasurement[,,k] %*% transitionPowered[,,i,k] %*% persistence;
56 | }
57 | }
58 |
59 | # Fill in diagonals
60 | for(i in 2:h){
61 | covarMat[i,i] <- covarMat[i-1,i-1] + cValues[i]^2;
62 | }
63 | # Fill in off-diagonals
64 | for(i in 1:h){
65 | for(j in 1:h){
66 | if(i==j){
67 | next;
68 | }
69 | else if(i==1){
70 | covarMat[i,j] = cValues[j];
71 | }
72 | else if(i>j){
73 | covarMat[i,j] <- covarMat[j,i];
74 | }
75 | else{
76 | covarMat[i,j] = covarMat[i-1,j-1] + covarMat[1,j] * covarMat[1,i];
77 | }
78 | }
79 | }
80 | }
81 | # Multiply the matrix by the one-step-ahead variance
82 | covarMat <- covarMat * s2;
83 |
84 | return(covarMat);
85 | }
86 |
87 | adamVarAnal <- function(lagsModel, h, measurement, transition, persistence, s2){
88 | #### The function returns variances for the multiplicative error ETS models
89 | # Prepare the necessary parameters
90 | lagsUnique <- unique(lagsModel);
91 | steps <- sort(lagsUnique[lagsUnique<=h]);
92 | stepsNumber <- length(steps);
93 | nComponents <- nrow(transition);
94 | k <- length(persistence);
95 |
96 | # Prepare the persistence array and measurement matrix
97 | arrayPersistenceQ <- array(0,c(nComponents,nComponents,stepsNumber));
98 | matrixMeasurement <- matrix(measurement,1,nComponents);
99 |
100 | # Form partial matrices for different steps
101 | for(i in 1:stepsNumber){
102 | arrayPersistenceQ[,lagsModel==steps[i],i] <- diag(as.vector(persistence),k,k)[,lagsModel==steps[i]];
103 | }
104 |
105 | ## The matrices that will be used in the loop
106 | matrixPersistenceQ <- matrix(0,nComponents,nComponents);
107 | # The interrim value (Q), which accumulates the values before taking logs
108 | IQ <- vector("numeric",1);
109 | Ik <- diag(k);
110 |
111 | # The vector of variances
112 | varMat <- rep(0, h);
113 |
114 | if(h>1){
115 | # Start the loop for varMat
116 | for(i in 2:h){
117 | IQ[] <- 0;
118 | # Form the correct interrim Q that will be used for variances
119 | for(k in 1:sum(steps install.packages("smooth")
72 |
73 | A recent, development version, is available via github and can be installed using "remotes" in R. First, make sure that you have remotes:
74 | > if (!require("remotes")){install.packages("remotes")}
75 |
76 | and after that run:
77 | > remotes::install_github("config-i1/smooth")
78 |
79 | ## Notes
80 |
81 | The package depends on Rcpp and RcppArmadillo, which will be installed automatically.
82 |
83 | However Mac OS users may need to install gfortran libraries in order to use Rcpp. Follow the link for the instructions: http://www.thecoatlessprofessor.com/programming/rcpp-rcpparmadillo-and-os-x-mavericks-lgfortran-and-lquadmath-error/
84 |
85 | Sometimes after upgrade of smooth from previous versions some functions stop working. This is because C++ functions are occasionally stored in deeper unknown corners of R's mind. Restarting R usually solves the problem. If it doesn't, completely remove smooth (uninstal + delete the folder "smooth" from R packages folder), restart R and reinstall smooth.
86 |
--------------------------------------------------------------------------------
/cran-comments.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Cran Comments"
3 | author: "Ivan Svetunkov"
4 | date: "02 April 2025"
5 | output: html_document
6 | ---
7 |
8 | ## Version
9 | This is ``smooth`` package, v4.2.0
10 |
11 | This is a try to fix the errors on CRAN.
12 |
13 | ## Test environments
14 | * local Ubuntu 24.04.1, R 4.4.1
15 | * github actions
16 | * win-builder (devel and release)
17 | * rhub v2
18 |
19 | ## R CMD check results
20 | R CMD check results
21 | checking installed package size ... NOTE
22 | installed size is 20.8Mb
23 | sub-directories of 1Mb or more:
24 | R 1.2Mb
25 | doc 3.3Mb
26 | libs 15.7Mb
27 | 0 errors | 0 warnings | 1 note
28 |
29 | ## Github actions
30 | Successful checks for:
31 |
32 | - Windows latest release with R 4.4.1
33 | - MacOS latest macOS Sonoma 14.6.1 with R 4.4.1
34 | - Ubuntu 22.04.5 LTS with R 4.4.1
35 |
36 | ## win-builder check results
37 | >* checking package dependencies ... NOTE
38 | >Package suggested but not available for checking: 'doMC'
39 |
40 | This is expected, because doMC is not available for Windows.
41 |
42 | ## R-hub
43 | All is fine
44 |
45 | ## Downstream dependencies
46 | I have also run R CMD check on reverse dependencies of smooth.
47 | No ERRORs or WARNINGs found.
48 |
--------------------------------------------------------------------------------
/man-roxygen/ADAMDataFormulaRegLossSilentHHoldout.R:
--------------------------------------------------------------------------------
1 | #' @param data Vector, containing data needed to be forecasted. If a matrix (or
2 | #' data.frame / data.table) is provided, then the first column is used as a
3 | #' response variable, while the rest of the matrix is used as a set of explanatory
4 | #' variables. \code{formula} can be used in the latter case in order to define what
5 | #' relation to have.
6 | #' @param formula Formula to use in case of explanatory variables. If \code{NULL},
7 | #' then all the variables are used as is. Can also include \code{trend}, which would add
8 | #' the global trend. Only needed if \code{data} is a matrix or if \code{trend} is provided.
9 | #' @param regressors The variable defines what to do with the provided explanatory
10 | #' variables:
11 | #' \code{"use"} means that all of the data should be used, while
12 | #' \code{"select"} means that a selection using \code{ic} should be done,
13 | #' \code{"adapt"} will trigger the mechanism of time varying parameters for the
14 | #' explanatory variables.
15 | #' @param loss The type of Loss Function used in optimization. \code{loss} can
16 | #' be:
17 | #' \itemize{
18 | #' \item \code{likelihood} - the model is estimated via the maximisation of the
19 | #' likelihood of the function specified in \code{distribution};
20 | #' \item \code{MSE} (Mean Squared Error),
21 | #' \item \code{MAE} (Mean Absolute Error),
22 | #' \item \code{HAM} (Half Absolute Moment),
23 | #' \item \code{LASSO} - use LASSO to shrink the parameters of the model;
24 | #' \item \code{RIDGE} - use RIDGE to shrink the parameters of the model;
25 | #' \item \code{TMSE} - Trace Mean Squared Error,
26 | #' \item \code{GTMSE} - Geometric Trace Mean Squared Error,
27 | #' \item \code{MSEh} - optimisation using only h-steps ahead error,
28 | #' \item \code{MSCE} - Mean Squared Cumulative Error.
29 | #' }
30 | #' In case of LASSO / RIDGE, the variables are not normalised prior to the estimation,
31 | #' but the parameters are divided by the mean values of explanatory variables.
32 | #'
33 | #' Note that model selection and combination works properly only for the default
34 | #' \code{loss="likelihood"}.
35 | #'
36 | #' Furthermore, just for fun the absolute and half analogues of multistep estimators
37 | #' are available: \code{MAEh}, \code{TMAE}, \code{GTMAE}, \code{MACE},
38 | #' \code{HAMh}, \code{THAM}, \code{GTHAM}, \code{CHAM}.
39 | #'
40 | #' Last but not least, user can provide their own function here as well, making sure
41 | #' that it accepts parameters \code{actual}, \code{fitted} and \code{B}. Here is an
42 | #' example:
43 | #'
44 | #' \code{lossFunction <- function(actual, fitted, B) return(mean(abs(actual-fitted)))}
45 | #'
46 | #' \code{loss=lossFunction}
47 | #' @param silent Specifies, whether to provide the progress of the function or not.
48 | #' If \code{TRUE}, then the function will print what it does and how much it has
49 | #' already done.
50 | #' @param h The forecast horizon. Mainly needed for the multistep loss functions.
51 | #' @param holdout Logical. If \code{TRUE}, then the holdout of the size \code{h}
52 | #' is taken from the data (can be used for the model testing purposes).
53 |
--------------------------------------------------------------------------------
/man-roxygen/ADAMInitial.R:
--------------------------------------------------------------------------------
1 | #' @param initial Can be either character or a list, or a vector of initial states.
2 | #' If it is character, then it can be \code{"backcasting"}, meaning that the initials of
3 | #' dynamic part of the model are produced using backcasting procedure (advised
4 | #' for data with high frequency), or \code{"optimal"}, meaning that all initial
5 | #' states are optimised, or \code{"two-stage"}, meaning that optimisation is done
6 | #' after the backcasting, refining the states. In case of backcasting, the parameters of the
7 | #' explanatory variables are optimised. Alternatively, you can set \code{initial="complete"}
8 | #' backcasting, which means that all states (including explanatory variables) are initialised
9 | #' via backcasting.
10 |
--------------------------------------------------------------------------------
/man-roxygen/smoothRef.R:
--------------------------------------------------------------------------------
1 | #' @references \itemize{
2 | #' \item Svetunkov I. (2023) Smooth forecasting with the smooth package in R. arXiv:2301.01790.
3 | #' \doi{10.48550/arXiv.2301.01790}.
4 | #' \item Svetunkov I. (2015 - Inf) "smooth" package for R - series of posts about the underlying
5 | #' models and how to use them: \url{https://openforecast.org/category/r-en/smooth/}.
6 | #' }
7 |
--------------------------------------------------------------------------------
/man-roxygen/ssADAMRef.R:
--------------------------------------------------------------------------------
1 | #' @references \itemize{
2 | #' \item Svetunkov, I. (2023). Forecasting and Analytics with the Augmented
3 | #' Dynamic Adaptive Model (ADAM) (1st ed.). Chapman and Hall/CRC.
4 | #' \doi{10.1201/9781003452652}, online version: \url{https://openforecast.org/adam/}.
5 | #' }
6 |
--------------------------------------------------------------------------------
/man-roxygen/ssARIMARef.R:
--------------------------------------------------------------------------------
1 | #' @references \itemize{
2 | #' \item Svetunkov, I., & Boylan, J. E. (2019). State-space ARIMA for supply-chain forecasting.
3 | #' International Journal of Production Research, 0(0), 1–10.
4 | #' \doi{10.1080/00207543.2019.1600764}
5 | #' }
6 |
--------------------------------------------------------------------------------
/man-roxygen/ssAdvancedParam.R:
--------------------------------------------------------------------------------
1 | #' @param loss The type of Loss Function used in optimization. \code{loss} can
2 | #' be: \code{likelihood} (assuming Normal distribution of error term),
3 | #' \code{MSE} (Mean Squared Error), \code{MAE} (Mean Absolute Error),
4 | #' \code{HAM} (Half Absolute Moment), \code{TMSE} - Trace Mean Squared Error,
5 | #' \code{GTMSE} - Geometric Trace Mean Squared Error, \code{MSEh} - optimisation
6 | #' using only h-steps ahead error, \code{MSCE} - Mean Squared Cumulative Error.
7 | #' If \code{loss!="MSE"}, then likelihood and model selection is done based
8 | #' on equivalent \code{MSE}. Model selection in this cases becomes not optimal.
9 | #'
10 | #' There are also available analytical approximations for multistep functions:
11 | #' \code{aMSEh}, \code{aTMSE} and \code{aGTMSE}. These can be useful in cases
12 | #' of small samples.
13 | #'
14 | #' Finally, just for fun the absolute and half analogues of multistep estimators
15 | #' are available: \code{MAEh}, \code{TMAE}, \code{GTMAE}, \code{MACE}, \code{TMAE},
16 | #' \code{HAMh}, \code{THAM}, \code{GTHAM}, \code{CHAM}.
17 |
--------------------------------------------------------------------------------
/man-roxygen/ssAuthor.R:
--------------------------------------------------------------------------------
1 | #' @author Ivan Svetunkov, \email{ivan@svetunkov.com}
2 |
--------------------------------------------------------------------------------
/man-roxygen/ssBasicParam.R:
--------------------------------------------------------------------------------
1 | #' @param y Vector or ts object, containing data needed to be forecasted.
2 | #' @param h Length of forecasting horizon.
3 | #' @param holdout If \code{TRUE}, holdout sample of size \code{h} is taken from
4 | #' the end of the data.
5 | #' @param ic The information criterion used in the model selection procedure.
6 | #' @param silent accepts \code{TRUE} and \code{FALSE}. If FALSE, the function
7 | #' will print its progress and produce a plot at the end.
8 |
--------------------------------------------------------------------------------
/man-roxygen/ssCESRef.R:
--------------------------------------------------------------------------------
1 | #' @references \itemize{
2 | #' \item Svetunkov, I., Kourentzes, N., & Ord, J. K. (2022).
3 | #' Complex exponential smoothing. Naval Research Logistics, 69(8),
4 | #' 1108–1123. https://doi.org/10.1002/nav.22074
5 | #' }
6 |
--------------------------------------------------------------------------------
/man-roxygen/ssETSRef.R:
--------------------------------------------------------------------------------
1 | #' @references \itemize{
2 | #' \item Kolassa, S. (2011) Combining exponential smoothing forecasts using Akaike
3 | #' weights. International Journal of Forecasting, 27, pp 238 - 251.
4 | #' \item Svetunkov, I., Boylan, J.E., 2023b. Staying Positive: Challenges and
5 | #' Solutions in Using Pure Multiplicative ETS Models. IMA Journal of
6 | #' Management Mathematics. p. 403-425. \doi{10.1093/imaman/dpad028}
7 | #' }
8 |
--------------------------------------------------------------------------------
/man-roxygen/ssGeneralRef.R:
--------------------------------------------------------------------------------
1 | #' @references \itemize{
2 | #' \item Svetunkov, I., 2023. Smooth Forecasting with the Smooth Package in R. arXiv.
3 | #' \doi{10.48550/arXiv.2301.01790}
4 | #' \item Snyder, R. D., 1985. Recursive Estimation of Dynamic Linear Models.
5 | #' Journal of the Royal Statistical Society, Series B (Methodological) 47 (2), 272-276.
6 | #' \item Hyndman, R.J., Koehler, A.B., Ord, J.K., and Snyder, R.D. (2008)
7 | #' Forecasting with exponential smoothing: the state space approach,
8 | #' Springer-Verlag. \doi{10.1007/978-3-540-71918-2}.
9 | #' }
10 |
--------------------------------------------------------------------------------
/man-roxygen/ssInitialParam.R:
--------------------------------------------------------------------------------
1 | #' @param initial Can be either character or a vector of initial states. If it
2 | #' is character, then it can be \code{"optimal"}, meaning that the initial
3 | #' states are optimised, or \code{"backcasting"}, meaning that the initials are
4 | #' produced using backcasting procedure.
5 |
--------------------------------------------------------------------------------
/man-roxygen/ssIntermittentRef.R:
--------------------------------------------------------------------------------
1 | #' @references \itemize{
2 | #' \item Svetunkov, I., Boylan, J.E., 2023a. iETS: State Space Model for
3 | #' Intermittent Demand Forecastings. International Journal of Production
4 | #' Economics. 109013. \doi{10.1016/j.ijpe.2023.109013}
5 | #' \item Teunter R., Syntetos A., Babai Z. (2011). Intermittent demand:
6 | #' Linking forecasting to inventory obsolescence. European Journal of
7 | #' Operational Research, 214, 606-615.
8 | #' \item Croston, J. (1972) Forecasting and stock control for intermittent
9 | #' demands. Operational Research Quarterly, 23(3), 289-303.
10 | #' }
11 |
--------------------------------------------------------------------------------
/man-roxygen/ssIntervals.R:
--------------------------------------------------------------------------------
1 | #' @param interval Type of interval to construct. This can be:
2 | #'
3 | #' \itemize{
4 | #' \item \code{"none"}, aka \code{"n"} - do not produce prediction
5 | #' interval.
6 | #' \item \code{"parametric"}, \code{"p"} - use state-space structure of ETS. In
7 | #' case of mixed models this is done using simulations, which may take longer
8 | #' time than for the pure additive and pure multiplicative models. This type
9 | #' of interval relies on unbiased estimate of in-sample error variance, which
10 | #' divides the sume of squared errors by T-k rather than just T.
11 | #' \item \code{"likelihood"}, \code{"l"} - these are the same as \code{"p"}, but
12 | #' relies on the biased estimate of variance from the likelihood (division by
13 | #' T, not by T-k).
14 | #' \item \code{"semiparametric"}, \code{"sp"} - interval based on covariance
15 | #' matrix of 1 to h steps ahead errors and assumption of normal / log-normal
16 | #' distribution (depending on error type).
17 | #' \item \code{"nonparametric"}, \code{"np"} - interval based on values from a
18 | #' quantile regression on error matrix (see Taylor and Bunn, 1999). The model
19 | #' used in this process is e[j] = a j^b, where j=1,..,h.
20 | #' }
21 | #' The parameter also accepts \code{TRUE} and \code{FALSE}. The former means that
22 | #' parametric interval are constructed, while the latter is equivalent to
23 | #' \code{none}.
24 | #' If the forecasts of the models were combined, then the interval are combined
25 | #' quantile-wise (Lichtendahl et al., 2013).
26 | #' @param level Confidence level. Defines width of prediction interval.
27 | #' @param cumulative If \code{TRUE}, then the cumulative forecast and prediction
28 | #' interval are produced instead of the normal ones. This is useful for
29 | #' inventory control systems.
30 |
--------------------------------------------------------------------------------
/man-roxygen/ssIntervalsRef.R:
--------------------------------------------------------------------------------
1 | #' @references \itemize{
2 | #' \item Taylor, J.W. and Bunn, D.W. (1999) A Quantile Regression Approach to
3 | #' Generating Prediction Intervals. Management Science, Vol 45, No 2, pp
4 | #' 225-237.
5 | #' \item Lichtendahl Kenneth C., Jr., Grushka-Cockayne Yael, Winkler
6 | #' Robert L., (2013) Is It Better to Average Probabilities or
7 | #' Quantiles? Management Science 59(7):1594-1611. DOI:
8 | #' \doi{10.1287/mnsc.1120.1667}
9 | #' }
10 |
--------------------------------------------------------------------------------
/man-roxygen/ssKeywords.R:
--------------------------------------------------------------------------------
1 | #' @keywords univar ts models smooth regression nonlinear
2 |
--------------------------------------------------------------------------------
/man-roxygen/ssPersistenceParam.R:
--------------------------------------------------------------------------------
1 | #' @param persistence Persistence vector \eqn{g}, containing smoothing
2 | #' parameters. If \code{NULL}, then estimated.
3 |
--------------------------------------------------------------------------------
/man-roxygen/ssSimParam.R:
--------------------------------------------------------------------------------
1 | #' @param frequency Frequency of generated data. In cases of seasonal models
2 | #' must be greater than 1.
3 | #' @param obs Number of observations in each generated time series.
4 | #' @param nsim Number of series to generate (number of simulations to do).
5 | #' @param randomizer Type of random number generator function used for error
6 | #' term. Defaults are: \code{rnorm}, \code{rt}, \code{rlaplace} and \code{rs}.
7 | #' \code{rlnorm} should be used for multiplicative models (e.g. ETS(M,N,N)).
8 | #' But any function from \link[stats]{Distributions} will do the trick if the
9 | #' appropriate parameters are passed. For example \code{rpois} with
10 | #' \code{lambda=2} can be used as well, but might result in weird values.
11 | #' @param probability Probability of occurrence, used for intermittent data
12 | #' generation. This can be a vector, implying that probability varies in time
13 | #' (in TSB or Croston style).
14 |
--------------------------------------------------------------------------------
/man-roxygen/ssXregParam.R:
--------------------------------------------------------------------------------
1 | #' @param xreg The vector (either numeric or time series) or the matrix (or
2 | #' data.frame) of exogenous variables that should be included in the model. If
3 | #' matrix included than columns should contain variables and rows - observations.
4 | #' Note that \code{xreg} should have number of observations equal either to
5 | #' in-sample or to the whole series. If the number of observations in
6 | #' \code{xreg} is equal to in-sample, then values for the holdout sample are
7 | #' produced using \link[smooth]{es} function.
8 | #' @param regressors The variable defines what to do with the provided xreg:
9 | #' \code{"use"} means that all of the data should be used, while
10 | #' \code{"select"} means that a selection using \code{ic} should be done.
11 | #' @param initialX The vector of initial parameters for exogenous variables.
12 | #' Ignored if \code{xreg} is NULL.
13 |
--------------------------------------------------------------------------------
/man/accuracy.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/methods.R
3 | \name{accuracy.smooth}
4 | \alias{accuracy.smooth}
5 | \alias{accuracy.smooth.forecast}
6 | \title{Error measures for an estimated model}
7 | \usage{
8 | \method{accuracy}{smooth}(object, holdout = NULL, ...)
9 |
10 | \method{accuracy}{smooth.forecast}(object, holdout = NULL, ...)
11 | }
12 | \arguments{
13 | \item{object}{The estimated model or a forecast from the estimated model generated via
14 | either \code{predict()} or \code{forecast()} functions.}
15 |
16 | \item{holdout}{The vector of values of the response variable in the holdout (test) set.
17 | If not provided, then the function will return the in-sample error measures. If the
18 | \code{holdout=TRUE} parameter was used in the estimation of a model, the holdout values
19 | will be extracted automatically.}
20 |
21 | \item{...}{Other variables passed to the \code{forecast()} function (e.g. \code{newdata}).}
22 | }
23 | \description{
24 | Function produces error measures for the provided object and the holdout values of the
25 | response variable. Note that instead of parameters \code{x}, \code{test}, the function
26 | accepts the vector of values in \code{holdout}. Also, the parameters \code{d} and \code{D}
27 | are not supported - MASE is always calculated via division by first differences.
28 | }
29 | \details{
30 | The function is a wrapper for the \link[greybox]{measures} function and is implemented
31 | for convenience.
32 | }
33 | \examples{
34 |
35 | y <- rnorm(100, 100, 10)
36 | ourModel <- adam(y, holdout=TRUE, h=10)
37 | accuracy(ourModel)
38 |
39 | }
40 | \author{
41 | Ivan Svetunkov, \email{ivan@svetunkov.com}
42 | }
43 |
--------------------------------------------------------------------------------
/man/cma.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/cma.R
3 | \name{cma}
4 | \alias{cma}
5 | \title{Centered Moving Average}
6 | \usage{
7 | cma(y, order = NULL, silent = TRUE, ...)
8 | }
9 | \arguments{
10 | \item{y}{Vector or ts object, containing data needed to be smoothed.}
11 |
12 | \item{order}{Order of centered moving average. If \code{NULL}, then the
13 | function will try to select order of SMA based on information criteria.
14 | See \link[smooth]{sma} for details.}
15 |
16 | \item{silent}{If \code{TRUE}, then plot is not produced. Otherwise, there
17 | is a plot...}
18 |
19 | \item{...}{Nothing. Needed only for the transition to the new name of variables.}
20 | }
21 | \value{
22 | Object of class "smooth" is returned. It contains the list of the
23 | following values:
24 |
25 | \itemize{
26 | \item \code{model} - the name of the estimated model.
27 | \item \code{timeElapsed} - time elapsed for the construction of the model.
28 | \item \code{order} - order of the moving average.
29 | \item \code{nParam} - table with the number of estimated / provided parameters.
30 | If a previous model was reused, then its initials are reused and the number of
31 | provided parameters will take this into account.
32 | \item \code{fitted} - the fitted values, shifted in time.
33 | \item \code{forecast} - NAs, because this function does not produce forecasts.
34 | \item \code{residuals} - the residuals of the SMA / AR model.
35 | \item \code{s2} - variance of the residuals (taking degrees of freedom into
36 | account) of the SMA / AR model.
37 | \item \code{y} - the original data.
38 | \item \code{ICs} - values of information criteria from the respective SMA or
39 | AR model. Includes AIC, AICc, BIC and BICc.
40 | \item \code{logLik} - log-likelihood of the SMA / AR model.
41 | \item \code{lossValue} - Cost function value (for the SMA / AR model).
42 | \item \code{loss} - Type of loss function used in the estimation.
43 | }
44 | }
45 | \description{
46 | Function constructs centered moving average based on state space SMA
47 | }
48 | \details{
49 | If the order is odd, then the function constructs SMA(order) and
50 | shifts it back in time. Otherwise an AR(order+1) model is constructed
51 | with the preset parameters:
52 |
53 | \deqn{phi_i = {0.5,1,1,...,0.5} / order}
54 |
55 | This then corresponds to the centered MA with 0.5 weight for the
56 | first observation and 0.5 weight for an additional one. e.g. if this is
57 | monthly data and we use order=12, then half of the first January and
58 | half of the new one is taken.
59 |
60 | This is not a forecasting tool. This is supposed to smooth the time
61 | series in order to find trend. So don't expect any forecasts from this
62 | function!
63 | }
64 | \examples{
65 |
66 | # CMA of specific order
67 | ourModel <- cma(rnorm(118,100,3),order=12)
68 |
69 | # CMA of arbitrary order
70 | ourModel <- cma(rnorm(118,100,3))
71 |
72 | summary(ourModel)
73 |
74 | }
75 | \references{
76 | \itemize{
77 | \item Svetunkov I. (2023) Smooth forecasting with the smooth package in R. arXiv:2301.01790.
78 | \doi{10.48550/arXiv.2301.01790}.
79 | \item Svetunkov I. (2015 - Inf) "smooth" package for R - series of posts about the underlying
80 | models and how to use them: \url{https://openforecast.org/category/r-en/smooth/}.
81 | }
82 | }
83 | \seealso{
84 | \code{\link[smooth]{es}, \link[smooth]{ssarima}}
85 | }
86 | \author{
87 | Ivan Svetunkov, \email{ivan@svetunkov.com}
88 | }
89 | \keyword{models}
90 | \keyword{nonlinear}
91 | \keyword{regression}
92 | \keyword{smooth}
93 | \keyword{ts}
94 | \keyword{univar}
95 |
--------------------------------------------------------------------------------
/man/figures/smooth-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/config-i1/smooth/c529c51c1aa221fd49117f17e68064b57d2ae9ff/man/figures/smooth-web.png
--------------------------------------------------------------------------------
/man/forecast.smooth.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/adam.R, R/methods.R, R/msdecompose.R
3 | \name{forecast.adam}
4 | \alias{forecast.adam}
5 | \alias{forecast.smooth}
6 | \alias{forecast}
7 | \alias{forecast.oes}
8 | \alias{forecast.msdecompose}
9 | \title{Forecasting time series using smooth functions}
10 | \usage{
11 | \method{forecast}{adam}(object, h = 10, newdata = NULL,
12 | occurrence = NULL, interval = c("none", "prediction", "confidence",
13 | "simulated", "approximate", "semiparametric", "nonparametric", "empirical",
14 | "complete"), level = 0.95, side = c("both", "upper", "lower"),
15 | cumulative = FALSE, nsim = NULL, scenarios = FALSE, ...)
16 |
17 | \method{forecast}{smooth}(object, h = 10, interval = c("parametric",
18 | "semiparametric", "nonparametric", "none"), level = 0.95,
19 | side = c("both", "upper", "lower"), ...)
20 |
21 | \method{forecast}{oes}(object, h = 10, ...)
22 |
23 | \method{forecast}{msdecompose}(object, h = 10, interval = c("parametric",
24 | "semiparametric", "nonparametric", "none"), level = 0.95, model = NULL,
25 | ...)
26 | }
27 | \arguments{
28 | \item{object}{Time series model for which forecasts are required.}
29 |
30 | \item{h}{Forecast horizon.}
31 |
32 | \item{newdata}{The new data needed in order to produce forecasts.}
33 |
34 | \item{occurrence}{The vector containing the future occurrence variable
35 | (values in [0,1]), if it is known.}
36 |
37 | \item{interval}{What type of mechanism to use for interval construction.
38 | the recommended option is \code{interval="prediction"}, which will use analytical
39 | solutions for pure additive models and simulations for the others.
40 | \code{interval="simulated"} is the slowest method, but is robust to the type of
41 | model. \code{interval="approximate"} (aka \code{interval="parametric"}) uses
42 | analytical formulae for conditional h-steps ahead variance, but is approximate
43 | for the non-additive error models. \code{interval="semiparametric"} relies on the
44 | multiple steps ahead forecast error (extracted via \code{rmultistep} method) and on
45 | the assumed distribution of the error term. \code{interval="nonparametric"} uses
46 | Taylor & Bunn (1999) approach with quantile regressions. \code{interval="empirical"}
47 | constructs intervals based on empirical quantiles of multistep forecast errors.
48 | \code{interval="complete"} will call for \code{reforecast()} function and produce
49 | interval based on the uncertainty around the parameters of the model.
50 | Finally, \code{interval="confidence"} tries to generate the confidence intervals
51 | for the point forecast based on the \code{reforecast} method.}
52 |
53 | \item{level}{Confidence level. Defines width of prediction interval.}
54 |
55 | \item{side}{Defines, whether to provide \code{"both"} sides of prediction
56 | interval or only \code{"upper"}, or \code{"lower"}.}
57 |
58 | \item{cumulative}{If \code{TRUE}, then the cumulative forecast and prediction
59 | interval are produced instead of the normal ones. This is useful for
60 | inventory control systems.}
61 |
62 | \item{nsim}{Number of iterations to do in cases of \code{interval="simulated"},
63 | \code{interval="prediction"} (for mixed and multiplicative model),
64 | \code{interval="confidence"} and \code{interval="complete"}.
65 | The default value for the prediction / simulated interval is 1000. In case of
66 | confidence or complete intervals, this is set to 100.}
67 |
68 | \item{scenarios}{Binary, defining whether to return scenarios produced via
69 | simulations or not. Only works if \code{interval="simulated"}. If \code{TRUE}
70 | the object will contain \code{scenarios} variable.}
71 |
72 | \item{...}{Other arguments accepted by either \link[smooth]{es},
73 | \link[smooth]{ces}, \link[smooth]{gum} or \link[smooth]{ssarima}.}
74 |
75 | \item{model}{The type of ETS model to fit on the decomposed trend. Only applicable to
76 | "msdecompose" class. This is then returned in parameter "esmodel". If \code{NULL}, then
77 | it will be selected automatically based on the type of the used decomposition (either
78 | among pure additive or among pure multiplicative ETS models).}
79 | }
80 | \value{
81 | Returns object of class "smooth.forecast", which contains:
82 |
83 | \itemize{
84 | \item \code{model} - the estimated model (ES / CES / GUM / SSARIMA).
85 | \item \code{method} - the name of the estimated model (ES / CES / GUM / SSARIMA).
86 | \item \code{forecast} aka \code{mean} - point forecasts of the model
87 | (conditional mean).
88 | \item \code{lower} - lower bound of prediction interval.
89 | \item \code{upper} - upper bound of prediction interval.
90 | \item \code{level} - confidence level.
91 | \item \code{interval} - binary variable (whether interval were produced or not).
92 | \item \code{scenarios} - in case of \code{forecast.adam()} and
93 | \code{interval="simulated"} returns matrix with scenarios (future paths) that were
94 | used in simulations.
95 | }
96 | }
97 | \description{
98 | Function produces conditional expectation (point forecasts) and prediction
99 | intervals for the estimated model.
100 | }
101 | \details{
102 | By default the function will generate conditional expectations from the
103 | estimated model and will also produce a variety of prediction intervals
104 | based on user preferences.
105 | }
106 | \examples{
107 |
108 | ourModel <- es(rnorm(100,0,1), h=10)
109 | forecast(ourModel, h=10, interval="parametric")
110 |
111 | }
112 | \references{
113 | Hyndman, R.J., Koehler, A.B., Ord, J.K., and Snyder, R.D. (2008)
114 | Forecasting with exponential smoothing: the state space approach,
115 | Springer-Verlag.
116 | }
117 | \seealso{
118 | \code{\link[generics]{forecast}}
119 | }
120 | \author{
121 | Ivan Svetunkov, \email{ivan@svetunkov.com}
122 | }
123 | \keyword{ts}
124 | \keyword{univar}
125 |
--------------------------------------------------------------------------------
/man/isFunctions.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/isFunctions.R, R/msdecompose.R
3 | \name{is.smooth}
4 | \alias{is.smooth}
5 | \alias{is.smoothC}
6 | \alias{is.msarima}
7 | \alias{is.oes}
8 | \alias{is.oesg}
9 | \alias{is.smooth.sim}
10 | \alias{is.smooth.forecast}
11 | \alias{is.adam}
12 | \alias{is.adam.sim}
13 | \alias{is.msdecompose}
14 | \alias{is.msdecompose.forecast}
15 | \title{Smooth classes checkers}
16 | \usage{
17 | is.smooth(x)
18 |
19 | is.smoothC(x)
20 |
21 | is.msarima(x)
22 |
23 | is.oes(x)
24 |
25 | is.oesg(x)
26 |
27 | is.smooth.sim(x)
28 |
29 | is.smooth.forecast(x)
30 |
31 | is.adam(x)
32 |
33 | is.adam.sim(x)
34 |
35 | is.msdecompose(x)
36 |
37 | is.msdecompose.forecast(x)
38 | }
39 | \arguments{
40 | \item{x}{The object to check.}
41 | }
42 | \value{
43 | \code{TRUE} if this is the specified class and \code{FALSE} otherwise.
44 |
45 | \code{TRUE} if this is the specified class and \code{FALSE} otherwise.
46 | }
47 | \description{
48 | Functions to check if an object is of the specified class
49 |
50 | Functions to check if an object is of the specified class
51 | }
52 | \details{
53 | The list of functions includes:
54 | \itemize{
55 | \item \code{is.smooth()} tests if the object was produced by a smooth function
56 | (e.g. \link[smooth]{es} / \link[smooth]{ces} / \link[smooth]{ssarima} /
57 | \link[smooth]{gum} / \link[smooth]{sma} / \link[smooth]{msarima});
58 | \item \code{is.msarima()} tests if the object was produced by the
59 | \link[smooth]{msarima} function;
60 | \item \code{is.smoothC()} tests if the object was produced by a combination
61 | function (currently applies only to \link[smooth]{smoothCombine});
62 | \item \code{is.oes()} tests if the object was produced by \link[smooth]{oes}
63 | function;
64 | \item \code{is.smooth.sim()} tests if the object was produced by simulate functions
65 | (e.g. \link[smooth]{sim.es} / \link[smooth]{sim.ces} / \link[smooth]{sim.ssarima}
66 | / \link[smooth]{sim.sma} / \link[smooth]{sim.gum});
67 | \item \code{is.smooth.forecast()} checks if the forecast was produced from a smooth
68 | function using forecast() function.
69 | }
70 |
71 | The list of functions includes:
72 | \itemize{
73 | \item \code{is.adam()} tests if the object was produced by a \link[smooth]{adam} function
74 | \item \code{is.adam.sim()} tests if the object was produced by sim.adam() function (not implemented yet);
75 | }
76 | }
77 | \examples{
78 |
79 | ourModel <- msarima(rnorm(100,100,10))
80 |
81 | is.smooth(ourModel)
82 | is.msarima(ourModel)
83 |
84 |
85 | ourModel <- adam(rnorm(100,100,10))
86 | is.adam(ourModel)
87 |
88 | }
89 | \author{
90 | Ivan Svetunkov, \email{ivan@svetunkov.com}
91 | }
92 | \keyword{ts}
93 | \keyword{univar}
94 |
--------------------------------------------------------------------------------
/man/msdecompose.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/msdecompose.R
3 | \name{msdecompose}
4 | \alias{msdecompose}
5 | \title{Multiple seasonal classical decomposition}
6 | \usage{
7 | msdecompose(y, lags = c(12), type = c("additive", "multiplicative"),
8 | smoother = c("ma", "lowess", "supsmu"), ...)
9 | }
10 | \arguments{
11 | \item{y}{Vector or ts object, containing data needed to be smoothed.}
12 |
13 | \item{lags}{Vector of lags, corresponding to the frequencies in the data.}
14 |
15 | \item{type}{The type of decomposition. If \code{"multiplicative"} is selected,
16 | then the logarithm of data is taken prior to the decomposition.}
17 |
18 | \item{smoother}{The type of function used in the smoother of the data to
19 | extract the trend and in seasonality smoothing. \code{smoother="ma"} relies
20 | on the centred moving average and will result in the classical decomposition.
21 | \code{smoother="lowess"} will use \link[stats]{lowess}, resulting in a
22 | decomposition similar to the STL (\link[stats]{stl}). Finally,
23 | \code{smoother="supsmu"} will use the Friedman's super smoother via
24 | \link[stats]{supsmu}.}
25 |
26 | \item{...}{Other parameters passed to smoothers. Only works with
27 | lowess/supsmu.}
28 | }
29 | \value{
30 | The object of the class "msdecompose" is return, containing:
31 | \itemize{
32 | \item \code{y} - the original time series.
33 | \item \code{initial} - the estimates of the initial level and trend.
34 | \item \code{trend} - the long term trend in the data.
35 | \item \code{seasonal} - the list of seasonal parameters.
36 | \item \code{lags} - the provided lags.
37 | \item \code{type} - the selected type of the decomposition.
38 | \item \code{yName} - the name of the provided data.
39 | }
40 | }
41 | \description{
42 | Function decomposes multiple seasonal time series into components using
43 | the principles of classical decomposition.
44 | }
45 | \details{
46 | The function applies centred moving averages based on \link[stats]{filter}
47 | function and order specified in \code{lags} variable in order to smooth the
48 | original series and obtain level, trend and seasonal components of the series.
49 | }
50 | \examples{
51 |
52 | # Decomposition of multiple frequency data
53 | \dontrun{ourModel <- msdecompose(forecast::taylor, lags=c(48,336), type="m")}
54 | ourModel <- msdecompose(AirPassengers, lags=c(12), type="m")
55 |
56 | plot(ourModel)
57 | plot(forecast(ourModel, model="AAN", h=12))
58 |
59 | }
60 | \references{
61 | \itemize{
62 | \item Svetunkov I. (2023) Smooth forecasting with the smooth package in R. arXiv:2301.01790.
63 | \doi{10.48550/arXiv.2301.01790}.
64 | \item Svetunkov I. (2015 - Inf) "smooth" package for R - series of posts about the underlying
65 | models and how to use them: \url{https://openforecast.org/category/r-en/smooth/}.
66 | }
67 | }
68 | \seealso{
69 | \code{\link[stats]{filter}}
70 | }
71 | \author{
72 | Ivan Svetunkov, \email{ivan@svetunkov.com}
73 | }
74 | \keyword{models}
75 | \keyword{nonlinear}
76 | \keyword{regression}
77 | \keyword{smooth}
78 | \keyword{ts}
79 | \keyword{univar}
80 |
--------------------------------------------------------------------------------
/man/multicov.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/methods.R
3 | \name{multicov}
4 | \alias{multicov}
5 | \alias{multicov.smooth}
6 | \title{Function returns the multiple steps ahead covariance matrix of forecast errors}
7 | \usage{
8 | multicov(object, type = c("analytical", "empirical", "simulated"), h = 10,
9 | nsim = 1000, ...)
10 |
11 | \method{multicov}{smooth}(object, type = c("analytical", "empirical",
12 | "simulated"), h = 10, nsim = 1000, ...)
13 | }
14 | \arguments{
15 | \item{object}{Model estimated using one of the functions of smooth package.}
16 |
17 | \item{type}{What method to use in order to produce covariance matrix:
18 | \enumerate{
19 | \item \code{analytical} - based on the state space structure of the model and the
20 | one-step-ahead forecast error. This works for pure additive and pure multiplicative
21 | models. The values for the mixed models might be off.
22 | \item \code{empirical} - based on the in-sample 1 to h steps ahead forecast errors
23 | (works fine on larger samples);
24 | \item \code{simulated} - the data is simulated from the estimated model, then the
25 | same model is applied to it and then the empirical 1 to h steps ahead forecast
26 | errors are produced;
27 | }}
28 |
29 | \item{h}{Forecast horizon to use in the calculations.}
30 |
31 | \item{nsim}{Number of iterations to produce in the simulation. Only needed if
32 | \code{type="simulated"}}
33 |
34 | \item{...}{Other parameters passed to simulate function (if \code{type="simulated"}
35 | is used). These are \code{obs} and \code{seed}. By default \code{obs=1000}.
36 | This approach increases the accuracy of covariance matrix on small samples
37 | and intermittent data;}
38 | }
39 | \value{
40 | Scalar in cases of non-smooth functions. (h x h) matrix otherwise.
41 | }
42 | \description{
43 | This function extracts covariance matrix of 1 to h steps ahead forecast errors for
44 | \code{adam()}, \code{ssarima()}, \code{gum()}, \code{sma()}, \code{es()} and
45 | \code{ces()} models.
46 | }
47 | \details{
48 | The function returns either scalar (if it is a non-smooth model)
49 | or the matrix of (h x h) size with variances and covariances of 1 to h steps ahead
50 | forecast errors.
51 | }
52 | \examples{
53 |
54 | x <- rnorm(100,0,1)
55 |
56 | # A simple example with a 5x5 covariance matrix
57 | ourModel <- ces(x, h=5)
58 | multicov(ourModel)
59 |
60 | }
61 | \seealso{
62 | \link[smooth]{orders}
63 | }
64 | \author{
65 | Ivan Svetunkov, \email{ivan@svetunkov.com}
66 | }
67 | \keyword{models}
68 | \keyword{nonlinear}
69 | \keyword{regression}
70 | \keyword{smooth}
71 | \keyword{ts}
72 | \keyword{univar}
73 |
--------------------------------------------------------------------------------
/man/oesg.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/oesg.R
3 | \name{oesg}
4 | \alias{oesg}
5 | \title{Occurrence ETS, general model}
6 | \usage{
7 | oesg(y, modelA = "MNN", modelB = "MNN", persistenceA = NULL,
8 | persistenceB = NULL, phiA = NULL, phiB = NULL, initialA = "o",
9 | initialB = "o", initialSeasonA = NULL, initialSeasonB = NULL,
10 | ic = c("AICc", "AIC", "BIC", "BICc"), h = 10, holdout = FALSE,
11 | bounds = c("usual", "admissible", "none"), silent = c("all", "graph",
12 | "legend", "output", "none"), xregA = NULL, xregB = NULL,
13 | initialXA = NULL, initialXB = NULL, regressorsA = c("use", "select"),
14 | regressorsB = c("use", "select"), ...)
15 | }
16 | \arguments{
17 | \item{y}{Either numeric vector or time series vector.}
18 |
19 | \item{modelA}{The type of the ETS for the model A.}
20 |
21 | \item{modelB}{The type of the ETS for the model B.}
22 |
23 | \item{persistenceA}{The persistence vector \eqn{g}, containing smoothing
24 | parameters used in the model A. If \code{NULL}, then estimated.}
25 |
26 | \item{persistenceB}{The persistence vector \eqn{g}, containing smoothing
27 | parameters used in the model B. If \code{NULL}, then estimated.}
28 |
29 | \item{phiA}{The value of the dampening parameter in the model A. Used only
30 | for damped-trend models.}
31 |
32 | \item{phiB}{The value of the dampening parameter in the model B. Used only
33 | for damped-trend models.}
34 |
35 | \item{initialA}{Either \code{"o"} - optimal or the vector of initials for the
36 | level and / or trend for the model A.}
37 |
38 | \item{initialB}{Either \code{"o"} - optimal or the vector of initials for the
39 | level and / or trend for the model B.}
40 |
41 | \item{initialSeasonA}{The vector of the initial seasonal components for the
42 | model A. If \code{NULL}, then it is estimated.}
43 |
44 | \item{initialSeasonB}{The vector of the initial seasonal components for the
45 | model B. If \code{NULL}, then it is estimated.}
46 |
47 | \item{ic}{Information criteria to use in case of model selection.}
48 |
49 | \item{h}{Forecast horizon.}
50 |
51 | \item{holdout}{If \code{TRUE}, holdout sample of size \code{h} is taken from
52 | the end of the data.}
53 |
54 | \item{bounds}{What type of bounds to use in the model estimation. The first
55 | letter can be used instead of the whole word.}
56 |
57 | \item{silent}{If \code{silent="none"}, then nothing is silent, everything is
58 | printed out and drawn. \code{silent="all"} means that nothing is produced or
59 | drawn (except for warnings). In case of \code{silent="graph"}, no graph is
60 | produced. If \code{silent="legend"}, then legend of the graph is skipped.
61 | And finally \code{silent="output"} means that nothing is printed out in the
62 | console, but the graph is produced. \code{silent} also accepts \code{TRUE}
63 | and \code{FALSE}. In this case \code{silent=TRUE} is equivalent to
64 | \code{silent="all"}, while \code{silent=FALSE} is equivalent to
65 | \code{silent="none"}. The parameter also accepts first letter of words ("n",
66 | "a", "g", "l", "o").}
67 |
68 | \item{xregA}{The vector or the matrix of exogenous variables, explaining some parts
69 | of occurrence variable of the model A.}
70 |
71 | \item{xregB}{The vector or the matrix of exogenous variables, explaining some parts
72 | of occurrence variable of the model B.}
73 |
74 | \item{initialXA}{The vector of initial parameters for exogenous variables in the model
75 | A. Ignored if \code{xregA} is NULL.}
76 |
77 | \item{initialXB}{The vector of initial parameters for exogenous variables in the model
78 | B. Ignored if \code{xregB} is NULL.}
79 |
80 | \item{regressorsA}{Variable defines what to do with the provided \code{xregA}:
81 | \code{"use"} means that all of the data should be used, while
82 | \code{"select"} means that a selection using \code{ic} should be done.}
83 |
84 | \item{regressorsB}{Similar to the \code{regressorsA}, but for the part B of the model.}
85 |
86 | \item{...}{The parameters passed to the optimiser, such as \code{maxeval},
87 | \code{xtol_rel}, \code{algorithm} and \code{print_level}. The description of
88 | these is printed out by \code{nloptr.print.options()} function from the \code{nloptr}
89 | package. The default values in the oes function are \code{maxeval=500},
90 | \code{xtol_rel=1E-8}, \code{algorithm="NLOPT_LN_NELDERMEAD"} and \code{print_level=0}.}
91 | }
92 | \value{
93 | The object of class "occurrence" is returned. It contains following list of
94 | values:
95 |
96 | \itemize{
97 | \item \code{modelA} - the model A of the class oes, that contains the output similar
98 | to the one from the \code{oes()} function;
99 | \item \code{modelB} - the model B of the class oes, that contains the output similar
100 | to the one from the \code{oes()} function.
101 | \item \code{B} - the vector of all the estimated parameters.
102 | }
103 | }
104 | \description{
105 | Function returns the general occurrence model of the of iETS model.
106 | }
107 | \details{
108 | The function estimates probability of demand occurrence, based on the iETS_G
109 | state-space model. It involves the estimation and modelling of the two
110 | simultaneous state space equations. Thus two parts for the model type,
111 | persistence, initials etc.
112 |
113 | For the details about the model and its implementation, see the respective
114 | vignette: \code{vignette("oes","smooth")}
115 |
116 | The model is based on:
117 |
118 | \deqn{o_t \sim Bernoulli(p_t)}
119 | \deqn{p_t = \frac{a_t}{a_t+b_t}},
120 |
121 | where a_t and b_t are the parameters of the Beta distribution and are modelled
122 | using separate ETS models.
123 | }
124 | \examples{
125 |
126 | y <- rpois(100,0.1)
127 | oesg(y, modelA="MNN", modelB="ANN")
128 |
129 | }
130 | \seealso{
131 | \code{\link[smooth]{es}, \link[smooth]{oes}}
132 | }
133 | \author{
134 | Ivan Svetunkov, \email{ivan@svetunkov.com}
135 | }
136 | \keyword{demand}
137 | \keyword{exponential}
138 | \keyword{forecasting}
139 | \keyword{intermittent}
140 | \keyword{iss}
141 | \keyword{model}
142 | \keyword{models}
143 | \keyword{nonlinear}
144 | \keyword{regression}
145 | \keyword{smooth}
146 | \keyword{smoothing}
147 | \keyword{space}
148 | \keyword{state}
149 | \keyword{ts}
150 | \keyword{univar}
151 |
--------------------------------------------------------------------------------
/man/orders.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/methods.R
3 | \name{orders}
4 | \alias{orders}
5 | \alias{lags}
6 | \alias{modelName}
7 | \alias{modelType}
8 | \title{Functions that extract values from the fitted model}
9 | \usage{
10 | orders(object, ...)
11 |
12 | lags(object, ...)
13 |
14 | modelName(object, ...)
15 |
16 | modelType(object, ...)
17 | }
18 | \arguments{
19 | \item{object}{Model estimated using one of the functions of smooth package.}
20 |
21 | \item{...}{Currently nothing is accepted via ellipsis.}
22 | }
23 | \value{
24 | Either vector, scalar or list with values is returned.
25 | \code{orders()} in case of ssarima returns list of values:
26 | \itemize{
27 | \item \code{ar} - AR orders.
28 | \item \code{i} - I orders.
29 | \item \code{ma} - MA orders.
30 | }
31 | \code{lags()} returns the vector of lags of the model.
32 | All the other functions return strings of character.
33 | }
34 | \description{
35 | These functions allow extracting orders and lags for \code{ssarima()}, \code{gum()} and \code{sma()},
36 | type of model from \code{es()} and \code{ces()} and name of model.
37 | }
38 | \details{
39 | \code{orders()} and \code{lags()} are useful only for SSARIMA, GUM and SMA. They return \code{NA} for other functions.
40 | This can also be applied to \code{arima()}, \code{Arima()} and \code{auto.arima()} functions from stats and forecast packages.
41 | \code{modelType()} is useful only for ETS and CES. They return \code{NA} for other functions.
42 | This can also be applied to \code{ets()} function from forecast package. \code{errorType}
43 | extracts the type of error from the model (either additive or multiplicative). Finally, \code{modelName}
44 | returns the name of the fitted model. For example, "ARIMA(0,1,1)". This is purely descriptive and
45 | can also be applied to non-smooth classes, so that, for example, you can easily extract the name
46 | of the fitted AR model from \code{ar()} function from \code{stats} package.
47 | }
48 | \examples{
49 |
50 | x <- rnorm(100,0,1)
51 |
52 | # Just as example. orders and lags do not return anything for ces() and es(). But modelType() does.
53 | ourModel <- ces(x, h=10)
54 | orders(ourModel)
55 | lags(ourModel)
56 | modelType(ourModel)
57 | modelName(ourModel)
58 |
59 | # And as another example it does the opposite for gum() and ssarima()
60 | ourModel <- gum(x, h=10, orders=c(1,1), lags=c(1,4))
61 | orders(ourModel)
62 | lags(ourModel)
63 | modelType(ourModel)
64 | modelName(ourModel)
65 |
66 | # Finally these values can be used for simulate functions or original functions.
67 | ourModel <- auto.ssarima(x)
68 | ssarima(x, orders=orders(ourModel), lags=lags(ourModel), constant=ourModel$constant)
69 | sim.ssarima(orders=orders(ourModel), lags=lags(ourModel), constant=ourModel$constant)
70 |
71 | ourModel <- es(x)
72 | es(x, model=modelType(ourModel))
73 | sim.es(model=modelType(ourModel))
74 |
75 | }
76 | \seealso{
77 | \link[smooth]{ssarima}, \link[smooth]{msarima}
78 | }
79 | \author{
80 | Ivan Svetunkov, \email{ivan@svetunkov.com}
81 | }
82 | \keyword{models}
83 | \keyword{nonlinear}
84 | \keyword{regression}
85 | \keyword{smooth}
86 | \keyword{ts}
87 | \keyword{univar}
88 |
--------------------------------------------------------------------------------
/man/plot.smooth.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/adam.R, R/methods.R, R/msdecompose.R
3 | \name{plot.adam}
4 | \alias{plot.adam}
5 | \alias{plot.smooth}
6 | \alias{plot.msdecompose}
7 | \title{Plots for the fit and states}
8 | \usage{
9 | \method{plot}{adam}(x, which = c(1, 2, 4, 6), level = 0.95,
10 | legend = FALSE, ask = prod(par("mfcol")) < length(which) &&
11 | dev.interactive(), lowess = TRUE, ...)
12 |
13 | \method{plot}{smooth}(x, which = c(1, 2, 4, 6), level = 0.95,
14 | legend = FALSE, ask = prod(par("mfcol")) < length(which) &&
15 | dev.interactive(), lowess = TRUE, ...)
16 |
17 | \method{plot}{msdecompose}(x, which = c(1, 2, 4, 6), level = 0.95,
18 | legend = FALSE, ask = prod(par("mfcol")) < length(which) &&
19 | dev.interactive(), lowess = TRUE, ...)
20 | }
21 | \arguments{
22 | \item{x}{Estimated smooth model.}
23 |
24 | \item{which}{Which of the plots to produce. The possible options (see details for explanations):
25 | \enumerate{
26 | \item Actuals vs Fitted values;
27 | \item Standardised residuals vs Fitted;
28 | \item Studentised residuals vs Fitted;
29 | \item Absolute residuals vs Fitted;
30 | \item Squared residuals vs Fitted;
31 | \item Q-Q plot with the specified distribution;
32 | \item Fitted over time;
33 | \item Standardised residuals vs Time;
34 | \item Studentised residuals vs Time;
35 | \item ACF of the residuals;
36 | \item PACF of the residuals;
37 | \item Plot of states of the model;
38 | \item Absolute standardised residuals vs Fitted;
39 | \item Squared standardised residuals vs Fitted;
40 | \item ACF of the squared residuals;
41 | \item PACF of the squared residuals.
42 | }}
43 |
44 | \item{level}{Confidence level. Defines width of confidence interval. Used in plots (2), (3), (7), (8),
45 | (9), (10) and (11).}
46 |
47 | \item{legend}{If \code{TRUE}, then the legend is produced on plots (2), (3) and (7).}
48 |
49 | \item{ask}{Logical; if \code{TRUE}, the user is asked to press Enter before each plot.}
50 |
51 | \item{lowess}{Logical; if \code{TRUE}, LOWESS lines are drawn on scatterplots, see \link[stats]{lowess}.}
52 |
53 | \item{...}{The parameters passed to the plot functions. Recommended to use with separate plots.}
54 | }
55 | \value{
56 | The function produces the number of plots, specified in the parameter \code{which}.
57 | }
58 | \description{
59 | The function produces diagnostics plots for a \code{smooth} model
60 | }
61 | \details{
62 | The list of produced plots includes:
63 | \enumerate{
64 | \item Actuals vs Fitted values. Allows analysing, whether there are any issues in the fit.
65 | Does the variability of actuals increase with the increase of fitted values? Is the relation
66 | well captured? They grey line on the plot corresponds to the perfect fit of the model.
67 | \item Standardised residuals vs Fitted. Plots the points and the confidence bounds
68 | (red lines) for the specified confidence \code{level}. Useful for the analysis of outliers;
69 | \item Studentised residuals vs Fitted. This is similar to the previous plot, but with the
70 | residuals divided by the scales with the leave-one-out approach. Should be more sensitive
71 | to outliers;
72 | \item Absolute residuals vs Fitted. Useful for the analysis of heteroscedasticity;
73 | \item Squared residuals vs Fitted - similar to (3), but with squared values;
74 | \item Q-Q plot with the specified distribution. Can be used in order to see if the
75 | residuals follow the assumed distribution. The type of distribution depends on the one used
76 | in the estimation (see \code{distribution} parameter in \link[greybox]{alm});
77 | \item ACF of the residuals. Are the residuals autocorrelated? See \link[stats]{acf} for
78 | details;
79 | \item Fitted over time. Plots actuals (black line), fitted values (purple line), point forecast
80 | (blue line) and prediction interval (grey lines). Can be used in order to make sure that the model
81 | did not miss any important events over time;
82 | \item Standardised residuals vs Time. Useful if you want to see, if there is autocorrelation or
83 | if there is heteroscedasticity in time. This also shows, when the outliers happen;
84 | \item Studentised residuals vs Time. Similar to previous, but with studentised residuals;
85 | \item PACF of the residuals. No, really, are they autocorrelated? See pacf function from stats
86 | package for details;
87 | \item Plot of the states of the model. It is not recommended to produce this plot together with
88 | the others, because there might be several states, which would cause the creation of a different
89 | canvas. In case of "msdecompose", this will produce the decomposition of the series into states
90 | on a different canvas;
91 | \item Absolute standardised residuals vs Fitted. Similar to the previous, but with absolute
92 | values. This is more relevant to the models where scale is calculated as an absolute value of
93 | something (e.g. Laplace);
94 | \item Squared standardised residuals vs Fitted. This is an additional plot needed to diagnose
95 | heteroscedasticity in a model with varying scale. The variance on this plot will be constant if
96 | the adequate model for \code{scale} was constructed. This is more appropriate for normal and
97 | the related distributions.
98 | }
99 | Which of the plots to produce, is specified via the \code{which} parameter.
100 | }
101 | \examples{
102 |
103 | ourModel <- es(c(rnorm(50,100,10),rnorm(50,120,10)), "ANN", h=10)
104 | par(mfcol=c(3,4))
105 | plot(ourModel, c(1:11))
106 | plot(ourModel, 12)
107 |
108 | }
109 | \seealso{
110 | \link[greybox]{plot.greybox}
111 | }
112 | \author{
113 | Ivan Svetunkov, \email{ivan@svetunkov.com}
114 | }
115 | \keyword{ts}
116 | \keyword{univar}
117 |
--------------------------------------------------------------------------------
/man/pls.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/methods.R
3 | \name{pls}
4 | \alias{pls}
5 | \alias{pls.smooth}
6 | \title{Prediction Likelihood Score}
7 | \usage{
8 | pls(object, holdout = NULL, ...)
9 |
10 | \method{pls}{smooth}(object, holdout = NULL, ...)
11 | }
12 | \arguments{
13 | \item{object}{The model estimated using smooth functions. This thing also accepts
14 | other models (e.g. estimated using functions from forecast package), but may not always
15 | work properly with them.}
16 |
17 | \item{holdout}{The values for the holdout part of the sample. If the model was fitted
18 | on the data with the \code{holdout=TRUE}, then the parameter is not needed.}
19 |
20 | \item{...}{Parameters passed to multicov function. The function is called in order to get
21 | the covariance matrix of 1 to h steps ahead forecast errors.}
22 | }
23 | \value{
24 | A value of the log-likelihood.
25 | }
26 | \description{
27 | Function estimates Prediction Likelihood Score for the provided model
28 | }
29 | \details{
30 | Prediction likelihood score (PLS) is based on either normal or log-normal
31 | distribution of errors. This is extracted from the provided model. The likelihood
32 | based on the distribution of 1 to h steps ahead forecast errors is used in the process.
33 | }
34 | \examples{
35 |
36 | # Generate data, apply es() with the holdout parameter and calculate PLS
37 | x <- rnorm(100,0,1)
38 | ourModel <- es(x, h=10, holdout=TRUE)
39 | pls(ourModel, type="a")
40 | pls(ourModel, type="e")
41 | pls(ourModel, type="s", obs=100, nsim=100)
42 |
43 | }
44 | \references{
45 | \itemize{
46 | %\item Eltoft, T., Taesu, K., Te-Won, L. (2006). On the multivariate Laplace
47 | distribution. IEEE Signal Processing Letters. 13 (5): 300-303.
48 | \doi{10.1109/LSP.2006.870353} - this is not yet used in the function.
49 | \item Snyder, R. D., Ord, J. K., Beaumont, A., 2012. Forecasting the intermittent
50 | demand for slow-moving inventories: A modelling approach. International
51 | Journal of Forecasting 28 (2), 485-496.
52 | \item Kolassa, S., 2016. Evaluating predictive count data distributions in retail
53 | sales forecasting. International Journal of Forecasting 32 (3), 788-803..
54 | }
55 | }
56 | \author{
57 | Ivan Svetunkov, \email{ivan@svetunkov.com}
58 | }
59 | \keyword{models}
60 | \keyword{nonlinear}
61 | \keyword{regression}
62 | \keyword{smooth}
63 | \keyword{ts}
64 | \keyword{univar}
65 |
--------------------------------------------------------------------------------
/man/reapply.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/adam.R
3 | \name{reapply}
4 | \alias{reapply}
5 | \alias{reforecast}
6 | \title{Reapply the model with randomly generated initial parameters and produce forecasts}
7 | \usage{
8 | reapply(object, nsim = 1000, bootstrap = FALSE, heuristics = NULL, ...)
9 |
10 | reforecast(object, h = 10, newdata = NULL, occurrence = NULL,
11 | interval = c("prediction", "confidence", "none"), level = 0.95,
12 | side = c("both", "upper", "lower"), cumulative = FALSE, nsim = 100,
13 | ...)
14 | }
15 | \arguments{
16 | \item{object}{Model estimated using one of the functions of smooth package.}
17 |
18 | \item{nsim}{Number of paths to generate (number of simulations to do).}
19 |
20 | \item{bootstrap}{The logical, which determines, whether to use bootstrap for the
21 | covariance matrix of parameters or not.}
22 |
23 | \item{heuristics}{The value for proportion to use for heuristic estimation of the
24 | standard deviation of parameters. If \code{NULL}, it is not used.}
25 |
26 | \item{...}{Other parameters passed to \code{reapply()} and \code{mean()} functions in case of
27 | \code{reforecast} (\code{trim} parameter in \code{mean()} is set to
28 | 0.01 by default) and to \code{vcov} in case of \code{reapply}.}
29 |
30 | \item{h}{Forecast horizon.}
31 |
32 | \item{newdata}{The new data needed in order to produce forecasts.}
33 |
34 | \item{occurrence}{The vector containing the future occurrence variable
35 | (values in [0,1]), if it is known.}
36 |
37 | \item{interval}{What type of mechanism to use for interval construction. The options
38 | include \code{interval="none"}, \code{interval="prediction"} (prediction intervals)
39 | and \code{interval="confidence"} (intervals for the point forecast). The other options
40 | are not supported and do not make much sense for the refitted model.}
41 |
42 | \item{level}{Confidence level. Defines width of prediction interval.}
43 |
44 | \item{side}{Defines, whether to provide \code{"both"} sides of prediction
45 | interval or only \code{"upper"}, or \code{"lower"}.}
46 |
47 | \item{cumulative}{If \code{TRUE}, then the cumulative forecast and prediction
48 | interval are produced instead of the normal ones. This is useful for
49 | inventory control systems.}
50 | }
51 | \value{
52 | \code{reapply()} returns object of the class "reapply", which contains:
53 | \itemize{
54 | \item \code{timeElapsed} - Time elapsed for the code execution;
55 | \item \code{y} - The actual values;
56 | \item \code{states} - The array of states of the model;
57 | \item \code{refitted} - The matrix with fitted values, where columns correspond
58 | to different paths;
59 | \item \code{fitted} - The vector of fitted values (conditional mean);
60 | \item \code{model} - The name of the constructed model;
61 | \item \code{transition} - The array of transition matrices;
62 | \item \code{measurement} - The array of measurement matrices;
63 | \item \code{persistence} - The matrix of persistence vectors (paths in columns);
64 | \item \code{profile} - The array of profiles obtained by the end of each fit.
65 | }
66 |
67 | \code{reforecast()} returns the object of the class \link[smooth]{forecast.smooth},
68 | which contains in addition to the standard list the variable \code{paths} - all
69 | simulated trajectories with h in rows, simulated future paths for each state in
70 | columns and different states (obtained from \code{reapply()} function) in the
71 | third dimension.
72 | }
73 | \description{
74 | \code{reapply} function generates the parameters based on the values in the provided
75 | object and then reapplies the same model with those parameters to the data, getting
76 | the fitted paths and updated states. \code{reforecast} function uses those values
77 | in order to produce forecasts for the \code{h} steps ahead.
78 | }
79 | \details{
80 | The main motivation of the function is to take the randomness due to the in-sample
81 | estimation of parameters into account when fitting the model and to propagate
82 | this randomness to the forecasts. The methods can be considered as a special case
83 | of recursive bootstrap.
84 | }
85 | \examples{
86 |
87 | x <- rnorm(100,0,1)
88 |
89 | # Just as example. orders and lags do not return anything for ces() and es(). But modelType() does.
90 | ourModel <- adam(x, "ANN")
91 | refittedModel <- reapply(ourModel, nsim=50)
92 | plot(refittedModel)
93 |
94 | ourForecast <- reforecast(ourModel, nsim=50)
95 |
96 | }
97 | \seealso{
98 | \link[smooth]{forecast.smooth}
99 | }
100 | \author{
101 | Ivan Svetunkov, \email{ivan@svetunkov.com}
102 | }
103 | \keyword{models}
104 | \keyword{nonlinear}
105 | \keyword{regression}
106 | \keyword{smooth}
107 | \keyword{ts}
108 | \keyword{univar}
109 |
--------------------------------------------------------------------------------
/man/reexports.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/adam.R, R/methods.R
3 | \docType{import}
4 | \name{reexports}
5 | \alias{reexports}
6 | \alias{xtable}
7 | \alias{accuracy}
8 | \title{Objects exported from other packages}
9 | \keyword{internal}
10 | \description{
11 | These objects are imported from other packages. Follow the links
12 | below to see their documentation.
13 |
14 | \describe{
15 | \item{generics}{\code{\link[generics]{accuracy}}}
16 |
17 | \item{xtable}{\code{\link[xtable]{xtable}}}
18 | }}
19 |
20 |
--------------------------------------------------------------------------------
/man/rmultistep.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/adam.R
3 | \name{rmultistep}
4 | \alias{rmultistep}
5 | \title{Multiple steps ahead forecast errors}
6 | \usage{
7 | rmultistep(object, h = 10, ...)
8 | }
9 | \arguments{
10 | \item{object}{Model estimated using one of the forecasting functions.}
11 |
12 | \item{h}{The forecasting horizon to use.}
13 |
14 | \item{...}{Currently nothing is accepted via ellipsis.}
15 | }
16 | \value{
17 | The matrix with observations in rows and h steps ahead values in columns.
18 | So, the first row corresponds to the forecast produced from the 0th observation
19 | from 1 to h steps ahead.
20 | }
21 | \description{
22 | The function extracts 1 to h steps ahead forecast errors from the model.
23 | }
24 | \details{
25 | The errors correspond to the error term epsilon_t in the ETS models. Don't forget
26 | that different models make different assumptions about epsilon_t and / or 1+epsilon_t.
27 | }
28 | \examples{
29 |
30 | x <- rnorm(100,0,1)
31 | ourModel <- adam(x)
32 | rmultistep(ourModel, h=13)
33 |
34 | }
35 | \seealso{
36 | \link[stats]{residuals},
37 | }
38 | \author{
39 | Ivan Svetunkov, \email{ivan@svetunkov.com}
40 | }
41 | \keyword{models}
42 | \keyword{nonlinear}
43 | \keyword{regression}
44 | \keyword{smooth}
45 | \keyword{ts}
46 | \keyword{univar}
47 |
--------------------------------------------------------------------------------
/man/sim.ces.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/simces.R
3 | \name{sim.ces}
4 | \alias{sim.ces}
5 | \title{Simulate Complex Exponential Smoothing}
6 | \usage{
7 | sim.ces(seasonality = c("none", "simple", "partial", "full"), obs = 10,
8 | nsim = 1, frequency = 1, a = NULL, b = NULL, initial = NULL,
9 | randomizer = c("rnorm", "rt", "rlaplace", "rs"), probability = 1, ...)
10 | }
11 | \arguments{
12 | \item{seasonality}{The type of seasonality used in CES. Can be: \code{none}
13 | - No seasonality; \code{simple} - Simple seasonality, using lagged CES
14 | (based on \code{t-m} observation, where \code{m} is the seasonality lag);
15 | \code{partial} - Partial seasonality with real seasonal components
16 | (equivalent to additive seasonality); \code{full} - Full seasonality with
17 | complex seasonal components (can do both multiplicative and additive
18 | seasonality, depending on the data). First letter can be used instead of
19 | full words. Any seasonal CES can only be constructed for time series
20 | vectors.}
21 |
22 | \item{obs}{Number of observations in each generated time series.}
23 |
24 | \item{nsim}{Number of series to generate (number of simulations to do).}
25 |
26 | \item{frequency}{Frequency of generated data. In cases of seasonal models
27 | must be greater than 1.}
28 |
29 | \item{a}{First complex smoothing parameter. Should be a complex number.
30 |
31 | NOTE! CES is very sensitive to a and b values so it is advised to use values
32 | from previously estimated model.}
33 |
34 | \item{b}{Second complex smoothing parameter. Can be real if
35 | \code{seasonality="partial"}. In case of \code{seasonality="full"} must be
36 | complex number.}
37 |
38 | \item{initial}{A matrix with initial values for CES. In case with
39 | \code{seasonality="partial"} and \code{seasonality="full"} first two columns
40 | should contain initial values for non-seasonal components, repeated
41 | \code{frequency} times.}
42 |
43 | \item{randomizer}{Type of random number generator function used for error
44 | term. Defaults are: \code{rnorm}, \code{rt}, \code{rlaplace} and \code{rs}.
45 | \code{rlnorm} should be used for multiplicative models (e.g. ETS(M,N,N)).
46 | But any function from \link[stats]{Distributions} will do the trick if the
47 | appropriate parameters are passed. For example \code{rpois} with
48 | \code{lambda=2} can be used as well, but might result in weird values.}
49 |
50 | \item{probability}{Probability of occurrence, used for intermittent data
51 | generation. This can be a vector, implying that probability varies in time
52 | (in TSB or Croston style).}
53 |
54 | \item{...}{Additional parameters passed to the chosen randomizer. All the
55 | parameters should be passed in the order they are used in chosen randomizer.
56 | For example, passing just \code{sd=0.5} to \code{rnorm} function will lead
57 | to the call \code{rnorm(obs, mean=0.5, sd=1)}.}
58 | }
59 | \value{
60 | List of the following values is returned:
61 | \itemize{
62 | \item \code{model} - Name of CES model.
63 | \item \code{a} - Value of complex smoothing parameter a. If \code{nsim>1}, then
64 | this is a vector.
65 | \item \code{b} - Value of complex smoothing parameter b. If \code{seasonality="n"}
66 | or \code{seasonality="s"}, then this is equal to NULL. If \code{nsim>1},
67 | then this is a vector.
68 | \item \code{initial} - Initial values of CES in a form of matrix. If \code{nsim>1},
69 | then this is an array.
70 | \item \code{data} - Time series vector (or matrix if \code{nsim>1}) of the generated
71 | series.
72 | \item \code{states} - Matrix (or array if \code{nsim>1}) of states. States are in
73 | columns, time is in rows.
74 | \item \code{residuals} - Error terms used in the simulation. Either vector or matrix,
75 | depending on \code{nsim}.
76 | \item \code{occurrence} - Values of occurrence variable. Once again, can be either
77 | a vector or a matrix...
78 | \item \code{logLik} - Log-likelihood of the constructed model.
79 | }
80 | }
81 | \description{
82 | Function generates data using CES with Single Source of Error as a data
83 | generating process.
84 | }
85 | \details{
86 | For the information about the function, see the vignette:
87 | \code{vignette("simulate","smooth")}
88 | }
89 | \examples{
90 |
91 | # Create 120 observations from CES(n). Generate 100 time series of this kind.
92 | x <- sim.ces("n",obs=120,nsim=100)
93 |
94 | # Generate similar thing for seasonal series of CES(s)_4
95 | x <- sim.ces("s",frequency=4,obs=80,nsim=100)
96 |
97 | # Estimate model and then generate 10 time series from it
98 | ourModel <- ces(rnorm(100,100,5))
99 | simulate(ourModel,nsim=10)
100 |
101 | }
102 | \references{
103 | \itemize{
104 | \item Svetunkov, I., Kourentzes, N., & Ord, J. K. (2022).
105 | Complex exponential smoothing. Naval Research Logistics, 69(8),
106 | 1108–1123. https://doi.org/10.1002/nav.22074
107 | }
108 | }
109 | \seealso{
110 | \code{\link[smooth]{sim.es}, \link[smooth]{sim.ssarima},
111 | \link[smooth]{ces}, \link[stats]{Distributions}}
112 | }
113 | \author{
114 | Ivan Svetunkov, \email{ivan@svetunkov.com}
115 | }
116 | \keyword{models}
117 | \keyword{nonlinear}
118 | \keyword{regression}
119 | \keyword{smooth}
120 | \keyword{ts}
121 | \keyword{univar}
122 |
--------------------------------------------------------------------------------
/man/sim.gum.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/simgum.R
3 | \name{sim.gum}
4 | \alias{sim.gum}
5 | \title{Simulate Generalised Exponential Smoothing}
6 | \usage{
7 | sim.gum(orders = c(1), lags = c(1), obs = 10, nsim = 1,
8 | frequency = 1, measurement = NULL, transition = NULL,
9 | persistence = NULL, initial = NULL, randomizer = c("rnorm", "rt",
10 | "rlaplace", "rs"), probability = 1, ...)
11 | }
12 | \arguments{
13 | \item{orders}{Order of the model. Specified as vector of number of states
14 | with different lags. For example, \code{orders=c(1,1)} means that there are
15 | two states: one of the first lag type, the second of the second type.}
16 |
17 | \item{lags}{Defines lags for the corresponding orders. If, for example,
18 | \code{orders=c(1,1)} and lags are defined as \code{lags=c(1,12)}, then the
19 | model will have two states: the first will have lag 1 and the second will
20 | have lag 12. The length of \code{lags} must correspond to the length of
21 | \code{orders}.}
22 |
23 | \item{obs}{Number of observations in each generated time series.}
24 |
25 | \item{nsim}{Number of series to generate (number of simulations to do).}
26 |
27 | \item{frequency}{Frequency of generated data. In cases of seasonal models
28 | must be greater than 1.}
29 |
30 | \item{measurement}{Measurement vector \eqn{w}. If \code{NULL}, then
31 | estimated.}
32 |
33 | \item{transition}{Transition matrix \eqn{F}. Can be provided as a vector.
34 | Matrix will be formed using the default \code{matrix(transition,nc,nc)},
35 | where \code{nc} is the number of components in state vector. If \code{NULL},
36 | then estimated.}
37 |
38 | \item{persistence}{Persistence vector \eqn{g}, containing smoothing
39 | parameters. If \code{NULL}, then estimated.}
40 |
41 | \item{initial}{Vector of initial values for state matrix. If \code{NULL},
42 | then generated using advanced, sophisticated technique - uniform
43 | distribution.}
44 |
45 | \item{randomizer}{Type of random number generator function used for error
46 | term. Defaults are: \code{rnorm}, \code{rt}, \code{rlaplace} and \code{rs}.
47 | \code{rlnorm} should be used for multiplicative models (e.g. ETS(M,N,N)).
48 | But any function from \link[stats]{Distributions} will do the trick if the
49 | appropriate parameters are passed. For example \code{rpois} with
50 | \code{lambda=2} can be used as well, but might result in weird values.}
51 |
52 | \item{probability}{Probability of occurrence, used for intermittent data
53 | generation. This can be a vector, implying that probability varies in time
54 | (in TSB or Croston style).}
55 |
56 | \item{...}{Additional parameters passed to the chosen randomizer. All the
57 | parameters should be passed in the order they are used in chosen randomizer.
58 | For example, passing just \code{sd=0.5} to \code{rnorm} function will lead
59 | to the call \code{rnorm(obs, mean=0.5, sd=1)}.}
60 | }
61 | \value{
62 | List of the following values is returned:
63 | \itemize{
64 | \item \code{model} - Name of GUM model.
65 | \item \code{measurement} - Matrix w.
66 | \item \code{transition} - Matrix F.
67 | \item \code{persistence} - Persistence vector. This is the place, where
68 | smoothing parameters live.
69 | \item \code{initial} - Initial values of GUM in a form of matrix. If \code{nsim>1},
70 | then this is an array.
71 | \item \code{data} - Time series vector (or matrix if \code{nsim>1}) of the generated
72 | series.
73 | \item \code{states} - Matrix (or array if \code{nsim>1}) of states. States are in
74 | columns, time is in rows.
75 | \item \code{residuals} - Error terms used in the simulation. Either vector or matrix,
76 | depending on \code{nsim}.
77 | \item \code{occurrence} - Values of occurrence variable. Once again, can be either
78 | a vector or a matrix...
79 | \item \code{logLik} - Log-likelihood of the constructed model.
80 | }
81 | }
82 | \description{
83 | Function generates data using GUM with Single Source of Error as a data
84 | generating process.
85 | }
86 | \details{
87 | For the information about the function, see the vignette:
88 | \code{vignette("simulate","smooth")}
89 | }
90 | \examples{
91 |
92 | # Create 120 observations from GUM(1[1]). Generate 100 time series of this kind.
93 | x <- sim.gum(orders=c(1),lags=c(1),obs=120,nsim=100)
94 |
95 | # Generate similar thing for seasonal series of GUM(1[1],1[4]])
96 | x <- sim.gum(orders=c(1,1),lags=c(1,4),frequency=4,obs=80,nsim=100,transition=c(1,0,0.9,0.9))
97 |
98 | # Estimate model and then generate 10 time series from it
99 | ourModel <- gum(rnorm(100,100,5))
100 | simulate(ourModel,nsim=10)
101 |
102 | }
103 | \references{
104 | \itemize{
105 | \item Svetunkov I. (2023) Smooth forecasting with the smooth package in R. arXiv:2301.01790.
106 | \doi{10.48550/arXiv.2301.01790}.
107 | \item Svetunkov I. (2015 - Inf) "smooth" package for R - series of posts about the underlying
108 | models and how to use them: \url{https://openforecast.org/category/r-en/smooth/}.
109 | }
110 | }
111 | \seealso{
112 | \code{\link[smooth]{sim.es}, \link[smooth]{sim.ssarima},
113 | \link[smooth]{sim.ces}, \link[smooth]{gum}, \link[stats]{Distributions}}
114 | }
115 | \author{
116 | Ivan Svetunkov, \email{ivan@svetunkov.com}
117 | }
118 | \keyword{models}
119 | \keyword{nonlinear}
120 | \keyword{regression}
121 | \keyword{smooth}
122 | \keyword{ts}
123 | \keyword{univar}
124 |
--------------------------------------------------------------------------------
/man/sim.oes.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/simoes.R
3 | \name{sim.oes}
4 | \alias{sim.oes}
5 | \title{Simulate Occurrence Part of ETS model}
6 | \usage{
7 | sim.oes(model = "MNN", obs = 10, nsim = 1, frequency = 1,
8 | occurrence = c("odds-ratio", "inverse-odds-ratio", "direct", "general"),
9 | bounds = c("usual", "admissible", "restricted"), randomizer = c("rlnorm",
10 | "rinvgauss", "rgamma", "rnorm"), persistence = NULL, phi = 1,
11 | initial = NULL, initialSeason = NULL, modelB = model,
12 | persistenceB = persistence, phiB = phi, initialB = initial,
13 | initialSeasonB = initialSeason, ...)
14 | }
15 | \arguments{
16 | \item{model}{Type of ETS model according to [Hyndman et. al., 2008]
17 | taxonomy. Can consist of 3 or 4 chars: \code{ANN}, \code{AAN}, \code{AAdN},
18 | \code{AAA}, \code{AAdA}, \code{MAdM} etc. The conventional oETS model assumes
19 | that the error term is positive, so "MZZ" models are recommended for this.
20 | If you use additive error models, then the function will exponentiate the
21 | obtained values before transforming them and getting the probability. This
22 | is the type of model A.}
23 |
24 | \item{obs}{Number of observations in each generated time series.}
25 |
26 | \item{nsim}{Number of series to generate (number of simulations to do).}
27 |
28 | \item{frequency}{Frequency of generated data. In cases of seasonal models
29 | must be greater than 1.}
30 |
31 | \item{occurrence}{Type of occurrence model. See \code{vignette("oes","smooth")}
32 | for details.}
33 |
34 | \item{bounds}{Type of bounds to use for persistence vector if values are
35 | generated. \code{"usual"} - bounds from p.156 by Hyndman et. al., 2008.
36 | \code{"restricted"} - similar to \code{"usual"} but with upper bound equal
37 | to 0.3. \code{"admissible"} - bounds from tables 10.1 and 10.2 of Hyndman
38 | et. al., 2008. Using first letter of the type of bounds also works. These
39 | bounds are also used for multiplicative models, but the models are much
40 | more restrictive, so weird results might be obtained. Be careful!}
41 |
42 | \item{randomizer}{Type of random number generator function used for error
43 | term. It is advised to use \code{rlnorm()} or \code{rinvgauss()} in case of
44 | multiplicative error models. If a randomiser is used, it is advised to
45 | specify the parameters in the ellipsis.}
46 |
47 | \item{persistence}{Persistence vector, which includes all the smoothing
48 | parameters. Must correspond to the chosen model. The maximum length is 3:
49 | level, trend and seasonal smoothing parameters. If \code{NULL}, values are
50 | generated.}
51 |
52 | \item{phi}{Value of damping parameter. If trend is not chosen in the model,
53 | the parameter is ignored.}
54 |
55 | \item{initial}{Vector of initial states of level and trend. The maximum
56 | length is 2. If \code{NULL}, values are generated.}
57 |
58 | \item{initialSeason}{Vector of initial states for seasonal coefficients.
59 | Should have length equal to \code{frequency} parameter. If \code{NULL},
60 | values are generated.}
61 |
62 | \item{modelB}{Type of model B. This is used in \code{occurrence="general"}
63 | and \code{occurrence="inverse-odds-ratio"}.}
64 |
65 | \item{persistenceB}{The persistence vector for the model B.}
66 |
67 | \item{phiB}{Value of damping parameter for the model B.}
68 |
69 | \item{initialB}{Vector of initial states of level and trend for the model B.}
70 |
71 | \item{initialSeasonB}{Vector of initial states for seasonal coefficients for
72 | the model B.}
73 |
74 | \item{...}{Additional parameters passed to the chosen randomizer. All the
75 | parameters should be passed in the order they are used in chosen randomizer.
76 | Both model A and model B share the same parameters for the randomizer.}
77 | }
78 | \value{
79 | List of the following values is returned:
80 | \itemize{
81 | \item \code{model} - Name of ETS model.
82 | \item \code{modelA} - Model A, generated using \code{sim.es()} function;
83 | \item \code{modelB} - Model B, generated using \code{sim.es()} function;
84 | \item \code{probability} - The value of probability generated by the model;
85 | \item \code{occurrence} - Type of occurrence used in the model;
86 | \item \code{logLik} - Log-likelihood of the constructed model.
87 | }
88 | }
89 | \description{
90 | Function generates data using ETS with Single Source of Error as a data
91 | generating process for the demand occurrence. As the main output it produces
92 | probabilities of occurrence.
93 | }
94 | \details{
95 | For the information about the function, see the vignette:
96 | \code{vignette("simulate","smooth")}
97 | }
98 | \examples{
99 |
100 | # This example uses rinvgauss function from statmod package.
101 | \donttest{oETSMNNIG <- sim.oes(model="MNN",frequency=12,obs=60,
102 | randomizer="rinvgauss",mean=1,dispersion=0.5)}
103 |
104 | # A simpler example with log normal distribution
105 | oETSMNNlogN <- sim.oes(model="MNN",frequency=12,obs=60,initial=1,
106 | randomizer="rlnorm",meanlog=0,sdlog=0.1)
107 |
108 | }
109 | \references{
110 | \itemize{
111 | \item Svetunkov, I., 2023. Smooth Forecasting with the Smooth Package in R. arXiv.
112 | \doi{10.48550/arXiv.2301.01790}
113 | \item Snyder, R. D., 1985. Recursive Estimation of Dynamic Linear Models.
114 | Journal of the Royal Statistical Society, Series B (Methodological) 47 (2), 272-276.
115 | \item Hyndman, R.J., Koehler, A.B., Ord, J.K., and Snyder, R.D. (2008)
116 | Forecasting with exponential smoothing: the state space approach,
117 | Springer-Verlag. \doi{10.1007/978-3-540-71918-2}.
118 | }
119 | }
120 | \seealso{
121 | \code{\link[smooth]{oes}, \link[smooth]{sim.es}, \link[stats]{Distributions}}
122 | }
123 | \author{
124 | Ivan Svetunkov, \email{ivan@svetunkov.com}
125 | }
126 | \keyword{models}
127 | \keyword{nonlinear}
128 | \keyword{regression}
129 | \keyword{smooth}
130 | \keyword{ts}
131 | \keyword{univar}
132 |
--------------------------------------------------------------------------------
/man/sim.sma.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/simsma.R
3 | \name{sim.sma}
4 | \alias{sim.sma}
5 | \title{Simulate Simple Moving Average}
6 | \usage{
7 | sim.sma(order = NULL, obs = 10, nsim = 1, frequency = 1,
8 | initial = NULL, randomizer = c("rnorm", "rt", "rlaplace", "rs"),
9 | probability = 1, ...)
10 | }
11 | \arguments{
12 | \item{order}{Order of the modelled series. If omitted, then a random order from 1 to 100 is selected.}
13 |
14 | \item{obs}{Number of observations in each generated time series.}
15 |
16 | \item{nsim}{Number of series to generate (number of simulations to do).}
17 |
18 | \item{frequency}{Frequency of generated data. In cases of seasonal models
19 | must be greater than 1.}
20 |
21 | \item{initial}{Vector of initial states for the model. If \code{NULL},
22 | values are generated.}
23 |
24 | \item{randomizer}{Type of random number generator function used for error
25 | term. Defaults are: \code{rnorm}, \code{rt}, \code{rlaplace} and \code{rs}.
26 | \code{rlnorm} should be used for multiplicative models (e.g. ETS(M,N,N)).
27 | But any function from \link[stats]{Distributions} will do the trick if the
28 | appropriate parameters are passed. For example \code{rpois} with
29 | \code{lambda=2} can be used as well, but might result in weird values.}
30 |
31 | \item{probability}{Probability of occurrence, used for intermittent data
32 | generation. This can be a vector, implying that probability varies in time
33 | (in TSB or Croston style).}
34 |
35 | \item{...}{Additional parameters passed to the chosen randomizer. All the
36 | parameters should be passed in the order they are used in chosen randomizer.
37 | For example, passing just \code{sd=0.5} to \code{rnorm} function will lead
38 | to the call \code{rnorm(obs, mean=0.5, sd=1)}.}
39 | }
40 | \value{
41 | List of the following values is returned:
42 | \itemize{
43 | \item \code{model} - Name of SMA model.
44 | \item \code{data} - Time series vector (or matrix if \code{nsim>1}) of the generated
45 | series.
46 | \item \code{states} - Matrix (or array if \code{nsim>1}) of states. States are in
47 | columns, time is in rows.
48 | \item \code{initial} - Vector (or matrix) of initial values.
49 | \item \code{probability} - vector of probabilities used in the simulation.
50 | \item \code{intermittent} - type of the intermittent model used.
51 | \item \code{residuals} - Error terms used in the simulation. Either vector or matrix,
52 | depending on \code{nsim}.
53 | \item \code{occurrence} - Values of occurrence variable. Once again, can be either
54 | a vector or a matrix...
55 | \item \code{logLik} - Log-likelihood of the constructed model.
56 | }
57 | }
58 | \description{
59 | Function generates data using SMA in a Single Source of Error state space
60 | model as a data generating process.
61 | }
62 | \details{
63 | For the information about the function, see the vignette:
64 | \code{vignette("simulate","smooth")}
65 | }
66 | \examples{
67 |
68 | # Create 40 observations of quarterly data using AAA model with errors from normal distribution
69 | sma10 <- sim.sma(order=10,frequency=4,obs=40,randomizer="rnorm",mean=0,sd=100)
70 |
71 | }
72 | \references{
73 | \itemize{
74 | \item Svetunkov, I., 2023. Smooth Forecasting with the Smooth Package in R. arXiv.
75 | \doi{10.48550/arXiv.2301.01790}
76 | \item Snyder, R. D., 1985. Recursive Estimation of Dynamic Linear Models.
77 | Journal of the Royal Statistical Society, Series B (Methodological) 47 (2), 272-276.
78 | \item Hyndman, R.J., Koehler, A.B., Ord, J.K., and Snyder, R.D. (2008)
79 | Forecasting with exponential smoothing: the state space approach,
80 | Springer-Verlag. \doi{10.1007/978-3-540-71918-2}.
81 | }
82 | }
83 | \seealso{
84 | \code{\link[smooth]{es}, \link[stats]{ts}, \link[stats]{Distributions}}
85 | }
86 | \author{
87 | Ivan Svetunkov, \email{ivan@svetunkov.com}
88 | }
89 | \keyword{models}
90 | \keyword{nonlinear}
91 | \keyword{regression}
92 | \keyword{smooth}
93 | \keyword{ts}
94 | \keyword{univar}
95 |
--------------------------------------------------------------------------------
/man/smooth.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/smooth-package.R
3 | \name{smooth}
4 | \alias{smooth}
5 | \alias{smooth-package}
6 | \title{Smooth package}
7 | \description{
8 | Package contains functions implementing Single Source of Error state space models for
9 | purposes of time series analysis and forecasting.
10 | }
11 | \details{
12 | \tabular{ll}{ Package: \tab smooth\cr Type: \tab Package\cr Date: \tab
13 | 2016-01-27 - Inf\cr License: \tab GPL-2 \cr } The following functions are
14 | included in the package:
15 | \itemize{
16 | \item \link[smooth]{es} - Exponential Smoothing in Single Source of Errors State Space form.
17 | \item \link[smooth]{ces} - Complex Exponential Smoothing.
18 | \item \link[smooth]{gum} - Generalised Exponential Smoothing.
19 | \item \link[smooth]{ssarima} - SARIMA in state space framework.
20 | % \item \link[smooth]{nus} - Non-Uniform Smoothing.
21 | \item \link[smooth]{auto.ces} - Automatic selection between seasonal and non-seasonal CES.
22 | \item \link[smooth]{auto.ssarima} - Automatic selection of ARIMA orders.
23 | \item \link[smooth]{sma} - Simple Moving Average in state space form.
24 | \item \link[smooth]{smoothCombine} - the function that combines forecasts from es(),
25 | ces(), gum(), ssarima() and sma() functions.
26 | \item \link[smooth]{cma} - Centered Moving Average. This is for smoothing time series,
27 | not for forecasting.
28 | \item \link[smooth]{sim.es} - simulate time series using ETS as a model.
29 | \item \link[smooth]{sim.ces} - simulate time series using CES as a model.
30 | \item \link[smooth]{sim.ssarima} - simulate time series using SARIMA as a model.
31 | \item \link[smooth]{sim.gum} - simulate time series using GUM as a model.
32 | \item \link[smooth]{sim.sma} - simulate time series using SMA.
33 | \item \link[smooth]{sim.oes} - simulate time series based on occurrence part of ETS model.
34 | \item \link[smooth]{oes} - occurrence part of the intermittent state space model.
35 | }
36 | There are also several methods implemented in the package for the classes
37 | "smooth" and "smooth.sim":
38 | \itemize{
39 | \item \link[smooth]{orders} - extracts orders of the fitted model.
40 | \item lags - extracts lags of the fitted model.
41 | \item modelType - extracts type of the fitted model.
42 | \item forecast - produces forecast using provided model.
43 | \item \link[smooth]{multicov} - returns covariance matrix of multiple steps ahead forecast errors.
44 | \item \link[smooth]{pls} - returns Prediction Likelihood Score.
45 | \item \link[greybox]{nparam} - returns number of the estimated parameters.
46 | \item fitted - extracts fitted values from provided model.
47 | \item getResponse - returns actual values from the provided model.
48 | \item residuals - extracts residuals of provided model.
49 | \item plot - plots either states of the model or produced forecast (depending on what object
50 | is passed).
51 | \item simulate - uses sim functions (\link[smooth]{sim.es}, \link[smooth]{sim.ces},
52 | \link[smooth]{sim.ssarima}, \link[smooth]{sim.gum}, \link[smooth]{sim.sma} and
53 | \link[smooth]{sim.oes}) in order to simulate data using the provided object.
54 | \item summary - provides summary of the object.
55 | \item AICc, BICc - return, guess what...
56 | }
57 | }
58 | \examples{
59 |
60 | \donttest{y <- ts(rnorm(100,10,3), frequency=12)
61 |
62 | adam(y, h=20, holdout=TRUE)
63 | es(y, h=20, holdout=TRUE)
64 | gum(y, h=20, holdout=TRUE)
65 | auto.ces(y, h=20, holdout=TRUE)
66 | auto.ssarima(y, h=20, holdout=TRUE)}
67 |
68 | }
69 | \references{
70 | \itemize{
71 | \item Svetunkov, I., 2023. Smooth Forecasting with the Smooth Package in R. arXiv.
72 | \doi{10.48550/arXiv.2301.01790}
73 | \item Snyder, R. D., 1985. Recursive Estimation of Dynamic Linear Models.
74 | Journal of the Royal Statistical Society, Series B (Methodological) 47 (2), 272-276.
75 | \item Hyndman, R.J., Koehler, A.B., Ord, J.K., and Snyder, R.D. (2008)
76 | Forecasting with exponential smoothing: the state space approach,
77 | Springer-Verlag. \doi{10.1007/978-3-540-71918-2}.
78 | }
79 |
80 | \itemize{
81 | \item Svetunkov, I., Boylan, J.E., 2023a. iETS: State Space Model for
82 | Intermittent Demand Forecastings. International Journal of Production
83 | Economics. 109013. \doi{10.1016/j.ijpe.2023.109013}
84 | \item Teunter R., Syntetos A., Babai Z. (2011). Intermittent demand:
85 | Linking forecasting to inventory obsolescence. European Journal of
86 | Operational Research, 214, 606-615.
87 | \item Croston, J. (1972) Forecasting and stock control for intermittent
88 | demands. Operational Research Quarterly, 23(3), 289-303.
89 | }
90 |
91 | \itemize{
92 | \item Svetunkov, I., Kourentzes, N., & Ord, J. K. (2022).
93 | Complex exponential smoothing. Naval Research Logistics, 69(8),
94 | 1108–1123. https://doi.org/10.1002/nav.22074
95 | }
96 |
97 | \itemize{
98 | \item Svetunkov I. (2023) Smooth forecasting with the smooth package in R. arXiv:2301.01790.
99 | \doi{10.48550/arXiv.2301.01790}.
100 | \item Svetunkov I. (2015 - Inf) "smooth" package for R - series of posts about the underlying
101 | models and how to use them: \url{https://openforecast.org/category/r-en/smooth/}.
102 | }
103 |
104 | \itemize{
105 | \item Kolassa, S. (2011) Combining exponential smoothing forecasts using Akaike
106 | weights. International Journal of Forecasting, 27, pp 238 - 251.
107 | \item Svetunkov, I., Boylan, J.E., 2023b. Staying Positive: Challenges and
108 | Solutions in Using Pure Multiplicative ETS Models. IMA Journal of
109 | Management Mathematics. p. 403-425. \doi{10.1093/imaman/dpad028}
110 | }
111 |
112 | \itemize{
113 | \item Taylor, J.W. and Bunn, D.W. (1999) A Quantile Regression Approach to
114 | Generating Prediction Intervals. Management Science, Vol 45, No 2, pp
115 | 225-237.
116 | \item Lichtendahl Kenneth C., Jr., Grushka-Cockayne Yael, Winkler
117 | Robert L., (2013) Is It Better to Average Probabilities or
118 | Quantiles? Management Science 59(7):1594-1611. DOI:
119 | \doi{10.1287/mnsc.1120.1667}
120 | }
121 | }
122 | \seealso{
123 | \code{\link[greybox]{forecast}, \link[smooth]{es},
124 | \link[smooth]{ssarima}, \link[smooth]{ces}, \link[smooth]{gum}}
125 | }
126 | \author{
127 | Ivan Svetunkov, \email{ivan@svetunkov.com}
128 | }
129 | \keyword{models}
130 | \keyword{nonlinear}
131 | \keyword{regression}
132 | \keyword{smooth}
133 | \keyword{ts}
134 | \keyword{univar}
135 |
--------------------------------------------------------------------------------
/man/sowhat.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/sowhat.R
3 | \name{sowhat}
4 | \alias{sowhat}
5 | \title{Function returns the ultimate answer to any question}
6 | \usage{
7 | sowhat(...)
8 | }
9 | \arguments{
10 | \item{...}{Any number of variables or string with a question.}
11 | }
12 | \value{
13 | It doesn't return any value, only messages. So what?
14 | }
15 | \description{
16 | You need a description? So what?
17 | }
18 | \details{
19 | You need details? So what?
20 | }
21 | \examples{
22 |
23 | x <- rnorm(10000,0,1);
24 | sowhat(x);
25 |
26 | sowhat("What's the meaning of life?")
27 |
28 | sowhat("I don't have a girlfriend.")
29 |
30 | }
31 | \references{
32 | \itemize{
33 | \item\href{https://en.wiktionary.org/wiki/so_what}{Sowhat?}
34 | \item\href{https://www.youtube.com/watch?v=FJfFZqTlWrQ}{Sowhat?}
35 | \item\href{https://en.wikipedia.org/wiki/Douglas_Adams}{42}
36 | }
37 | }
38 | \seealso{
39 | Nowwhat (to be implemented),
40 | }
41 | \author{
42 | Ivan Svetunkov, \email{ivan@svetunkov.com}
43 | }
44 | \keyword{42}
45 | \keyword{sowhat}
46 |
--------------------------------------------------------------------------------
/python/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.16)
2 |
3 | set(CMAKE_CXX_STANDARD 17)
4 | set(CMAKE_CXX_STANDARD_REQUIRED True)
5 | set(CMAKE_CXX_EXTENSIONS OFF)
6 |
7 | project(smooth VERSION 0.0.1)
8 |
9 | if(SKBUILD)
10 | message(STATUS "The project is built using scikit-build")
11 | endif()
12 |
13 | # Pybind11
14 | find_package(pybind11 REQUIRED)
15 |
16 | # CARMA
17 | ADD_SUBDIRECTORY(../src/libs/carma carma)
18 |
19 | # BLAS and LAPACK. Needed by Armadillo
20 | find_package(BLAS)
21 | find_package(LAPACK)
22 | if(LAPACK_FOUND AND BLAS_FOUND)
23 | set(lapackblas_libraries ${BLAS_LIBRARIES} ${LAPACK_LIBRARIES})
24 | else()
25 | # IS: This is where they are on my system. This might change from one OS to another
26 | set(lapackblas_libraries "/usr/lib/x86_64-linux-gnu/")
27 | endif()
28 |
29 | # Armadillo
30 | find_package(armadillo)
31 | IF(NOT ARMADILLO_FOUND)
32 | set(ARMADILLO_INCLUDE_DIRS "/usr/lib/")
33 | ENDIF()
34 | include_directories(${ARMADILLO_INCLUDE_DIRS})
35 |
36 | # Adam General
37 | pybind11_add_module(_adam_general ../src/python_examples/adamGeneral.cpp)
38 | target_include_directories(_adam_general PRIVATE ../src/python_examples/.)
39 | target_link_libraries(_adam_general PRIVATE carma::carma ${ARMADILLO_LIBRARIES} ${lapackblas_libraries})
40 | install(TARGETS _adam_general DESTINATION smooth/adam_general)
41 |
42 |
43 | # Old experimental stuff by Leo
44 | # code to add the pybind11 cpp module, look at demo project
45 | # (https://github.com/ltsaprounis/python-cpp-experiments/tree/main) for details.
46 | #pybind11_add_module(_my_linalg ../src/python_examples/my_linalg.cpp)
47 |
48 | # add CARMA as a subdirectory
49 | #add_subdirectory(../src/libs/carma build)
50 | #target_link_libraries(_my_linalg
51 | # PRIVATE carma::carma
52 | # ${ARMADILLO_LIBRARIES}
53 | #)
54 |
55 | # install(TARGETS _my_linalg DESTINATION smooth/my_linalg)
56 |
57 |
--------------------------------------------------------------------------------
/python/Makefile:
--------------------------------------------------------------------------------
1 | .PHONY: all lint test install environment
2 |
3 | SRC_DIR = smooth
4 |
5 | lint:
6 | flake8 $(SRC_DIR)
7 | pydocstyle $(SRC_DIR)
8 |
9 | test:
10 | pytest $(SRC_DIR)
11 |
12 | install:
13 | pip install -e ".[dev]"
14 |
15 | environment:
16 | (\
17 | echo "> Creating venv"; \
18 | python -m venv .venv; \
19 | source .venv/bin/activate; \
20 | echo "> Installing local package in editable mode"; \
21 | pip install -e ".[dev]"; \
22 | echo "> Making venv available in jupyter notebooks"; \
23 | python -m ipykernel install --name=$(SRC_DIR); \
24 | jupyter kernelspec list; \
25 | echo "> Installing pre-commit"; \
26 | pre-commit install; \
27 | )
28 |
29 | clean:
30 | echo "> Removing virtual environment"
31 | rm -r .venv
32 | echo "> Uninstalling from jupyter"
33 | jupyter kernelspec uninstall $(SRC_DIR)
34 |
--------------------------------------------------------------------------------
/python/README.md:
--------------------------------------------------------------------------------
1 | # PY-SMOOTH
2 | Python version of smooth.
3 |
4 | **⚠️WORK IN PROGRESS⚠️**
5 |
6 | # Notes:
7 |
8 | 1. To build the project using [scikit-build-core](https://github.com/scikit-build/scikit-build-core) simply do `pip install -e .`
9 | 2. The files in python/smooth/mylinalg and src/my_linalg.cpp are example files for carma and pybind11 and will be removed later.
10 |
11 |
12 | # TODOs:
13 | - [X] use scikit-build-core to compile the C++ modules
14 | - [ ] (TBC) Refactor src code to use armadillo instead of rcpparmadillo in common Cpp code.
15 | - [ ] CI pipelines for tests
16 | - [ ] Add sphinx docs for python package
17 | - [ ] Check how to automate the Armadillo installation either as a github submodule or using [cmake's FetchContent](https://cmake.org/cmake/help/latest/module/FetchContent.html#fetchcontent) like in [carma](https://github.com/RUrlus/carma/blob/2fbc2e6faf2e40e41003c06cbb13744405732b5f/integration_test/CMakeLists.txt#L36)
18 |
--------------------------------------------------------------------------------
/python/pyproject.toml:
--------------------------------------------------------------------------------
1 | [build-system]
2 | requires = ["scikit-build-core>=0.3.3", "pybind11", "numpy>=1.14"]
3 | build-backend = "scikit_build_core.build"
4 |
5 | [project]
6 | name = "smooth"
7 | version = "0.0.1"
8 | description = "Python vesrion of the smooth forecasting library"
9 | readme = "README.md"
10 | requires-python = ">=3.8,<3.11"
11 | dependencies = ["pybind11[global]>=2.6.0", "numpy>=1.14"]
12 |
13 | [project.optional-dependencies]
14 | dev = ["pytest", "ruff", "pre-commit", "ipykernel"]
15 |
16 | [tool.scikit-build]
17 | # wheel.expand-macos-universal-tags = true
18 | build-dir = "build"
19 | logging.level = "INFO"
20 | ninja.make-fallback = true
21 | # This activates verbose builds
22 | cmake.verbose = true
23 | ninja.minimum-version = "1.5"
24 | cmake.minimum-version = "3.25"
25 |
26 | [tool.ruff]
27 | # Exclude a variety of commonly ignored directories.
28 | exclude = [
29 | ".bzr",
30 | ".direnv",
31 | ".eggs",
32 | ".git",
33 | ".git-rewrite",
34 | ".hg",
35 | ".mypy_cache",
36 | ".nox",
37 | ".pants.d",
38 | ".pytype",
39 | ".ruff_cache",
40 | ".svn",
41 | ".tox",
42 | ".venv",
43 | "__pypackages__",
44 | "_build",
45 | "buck-out",
46 | "build",
47 | "dist",
48 | "node_modules",
49 | "venv",
50 | "tools/cookiecutter_templates",
51 | ]
52 |
53 | # Same as Black.
54 | line-length = 88
55 | indent-width = 4
56 |
57 | # Assume Python 3.8
58 | target-version = "py38"
59 |
60 | [tool.ruff.lint]
61 | # Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default.
62 | # Unlike Flake8, Ruff doesn't enable pycodestyle warnings (`W`) or
63 | # McCabe complexity (`C901`) by default.
64 | # Rules for ruff are found here: https://docs.astral.sh/ruff/rules/
65 | select = [
66 | "E4",
67 | "E7",
68 | "E9",
69 | "E501",
70 | "F",
71 | "I", # isort rules
72 | "N", # PEP-8 naming rules
73 | ]
74 | ignore = [
75 | # uppercase names are used for matrices
76 | "N803", # allow uppercase argument names
77 | "N806", # allow uppercase variable names
78 | ]
79 |
80 | # Allow fix for all enabled rules (when `--fix`) is provided.
81 | fixable = ["ALL"]
82 | unfixable = []
83 |
84 | # Allow unused variables when underscore-prefixed.
85 | dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
86 |
87 | [tool.ruff.format]
88 | # Like Black, use double quotes for strings.
89 | quote-style = "double"
90 |
91 | # Like Black, indent with spaces, rather than tabs.
92 | indent-style = "space"
93 |
94 | # Like Black, respect magic trailing commas.
95 | skip-magic-trailing-comma = false
96 |
97 | # Like Black, automatically detect the appropriate line ending.
98 | line-ending = "auto"
99 |
--------------------------------------------------------------------------------
/python/setup.cfg:
--------------------------------------------------------------------------------
1 | [flake8]
2 | # inline with Black code formatter
3 | max-line-length = 88
4 |
5 | [pydocstyle]
6 | convention=numpy
7 | add-ignore =
8 | # First line should end with a period
9 | D400,
10 | # First line should be in imperative mood
11 | D401,
12 | # __init__.py can be empty
13 | D104
14 | # ignore test files and the init in the
15 | match = (?!test_).*\.py
16 |
--------------------------------------------------------------------------------
/python/smooth/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/config-i1/smooth/c529c51c1aa221fd49117f17e68064b57d2ae9ff/python/smooth/__init__.py
--------------------------------------------------------------------------------
/python/smooth/adam_general/__init__.py:
--------------------------------------------------------------------------------
1 | from ._adam_general import adam_fitter
2 |
3 | __all__ = ["adam_fitter"]
4 |
--------------------------------------------------------------------------------
/python/smooth/adam_general/adam_profile.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 |
3 |
4 | def adam_profile_creator(
5 | lags_model_all, lags_model_max, obs_all, lags=None, y_index=None, y_classes=None
6 | ):
7 | """
8 | Creates recent profile and the lookup table for adam.
9 | Parameters:
10 | lagsModelAll (list): All lags used in the model for ETS + ARIMA + xreg.
11 | lagsModelMax (int): The maximum lag used in the model.
12 | obsAll (int): Number of observations to create.
13 | lags (list): The original lags provided by user (optional).
14 | yIndex (list): The indices needed to get the specific dates (optional).
15 | yClasses (list): The class used for the actual data (optional).
16 | Returns:
17 | dict: A dictionary with 'recent' (profilesRecentTable) and 'lookup'
18 | (indexLookupTable) as keys.
19 | """
20 | # Initialize matrices
21 | profiles_recent_table = np.zeros((len(lags_model_all), lags_model_max))
22 | index_lookup_table = np.ones((len(lags_model_all), obs_all + lags_model_max))
23 | profile_indices = (
24 | np.arange(1, lags_model_max * len(lags_model_all) + 1)
25 | .reshape(-1, len(lags_model_all))
26 | .T
27 | )
28 |
29 | # Update matrices based on lagsModelAll
30 | for i, lag in enumerate(lags_model_all):
31 | # Create the matrix with profiles based on the provided lags.
32 | # For every row, fill the first 'lag' elements from 1 to lag
33 | profiles_recent_table[i, : lag[0]] = np.arange(1, lag[0] + 1)
34 |
35 | # For the i-th row in indexLookupTable, fill with a repeated sequence starting
36 | # from lagsModelMax to the end of the row.
37 | # The repeated sequence is the i-th row of profileIndices, repeated enough times
38 | # to cover 'obsAll' observations.
39 | # '- 1' at the end adjusts these values to Python's zero-based indexing.
40 | index_lookup_table[i, lags_model_max : (lags_model_max + obs_all)] = (
41 | np.tile(
42 | profile_indices[i, : lags_model_all[i][0]],
43 | int(np.ceil(obs_all / lags_model_all[i][0])),
44 | )[0:obs_all]
45 | - 1
46 | )
47 |
48 | # Extract unique values from from lagsModelMax to lagsModelMax + obsAll of
49 | # indexLookupTable
50 | unique_values = np.unique(
51 | index_lookup_table[i, lags_model_max : lags_model_max + obs_all] # noqa
52 | )
53 |
54 | # fix the head of teh data before the sample starts
55 | # Repeat the unique values lagsModelMax times and then trim the sequence to only
56 | # keep the first lagsModelMax elements
57 | index_lookup_table[i, :lags_model_max] = np.tile(unique_values, lags_model_max)[
58 | -lags_model_max:
59 | ]
60 |
61 | # Convert to int!
62 | index_lookup_table = index_lookup_table.astype(int)
63 |
64 | # Note: I skip andling of special cases (e.g., daylight saving time, leap years)
65 | return {
66 | "recent": np.array(profiles_recent_table, dtype="float64"),
67 | "lookup": np.array(index_lookup_table, dtype="int64"),
68 | }
69 |
--------------------------------------------------------------------------------
/python/smooth/adam_general/core/__init__.py:
--------------------------------------------------------------------------------
1 | # lol
--------------------------------------------------------------------------------
/python/smooth/adam_general/core/sma.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 |
3 | from smooth.adam_general._adam_general import adam_fitter, adam_forecaster
4 | from smooth.adam_general.adam_profile import adam_profile_creator
5 |
6 |
7 | def sma(y, order=1, h=10, holdout=False):
8 | """SMA"""
9 | y = y.astype(np.float64)
10 |
11 | # ic = lambda e: np.sum(e**2)
12 | obs_all = len(y) + h * (1 - holdout)
13 | obs_in_sample = len(y) - h * holdout
14 | y_in_sample = y
15 |
16 | E_type = "A"
17 | T_type = "N"
18 | S_type = "N"
19 |
20 | components_num_ETS = 0
21 | components_num_ETS_seasonal = 0
22 | xreg_number = 0
23 | constant_required = False
24 | ot = np.ones_like(y_in_sample)
25 |
26 | def creator_sma(order):
27 | # lags_model_all = np.ones(shape=(order, 1))
28 | # This needs to be a vector of values
29 | lags_model_all = np.arange(1, order + 1, dtype="int32").reshape(order, 1)
30 | lags_model_max = int(max(lags_model_all))
31 | obs_states = obs_in_sample + lags_model_max
32 |
33 | profiles_recent_table, index_lookup_table = adam_profile_creator(
34 | lags_model_all=lags_model_all,
35 | lags_model_max=lags_model_max,
36 | obs_all=obs_all,
37 | ).values()
38 |
39 | # # This needs to be generated by a profileCreator() function
40 | # profiles_recent_table = np.mean(y_in_sample[0 : (order - 1)]) * np.ones(
41 | # shape=(order, lags_model_max), dtype=np.float64
42 | # )
43 |
44 | # # This as well...
45 | # index_lookup_table = np.tile(
46 | # np.arange(order), (obs_all + lags_model_max, 1)
47 | # ).T
48 |
49 | mat_F = np.ones((order, order)) / order
50 | mat_Wt = np.ones((obs_in_sample, order))
51 |
52 | vec_G = np.ones(order) / order
53 | # matVt = np.zeros((order, obs_states))
54 | mat_Vt = np.empty((order, obs_states))
55 | # matVt.fill(np.nan)
56 |
57 | adam_fitted = adam_fitter(
58 | matrixVt=mat_Vt,
59 | matrixWt=mat_Wt,
60 | matrixF=mat_F,
61 | vectorG=vec_G,
62 | lags=lags_model_all,
63 | indexLookupTable=index_lookup_table,
64 | profilesRecent=profiles_recent_table,
65 | E=E_type,
66 | T=T_type,
67 | S=S_type,
68 | nNonSeasonal=components_num_ETS,
69 | nSeasonal=components_num_ETS_seasonal,
70 | nArima=order,
71 | nXreg=xreg_number,
72 | constant=constant_required,
73 | vectorYt=y_in_sample,
74 | vectorOt=ot,
75 | backcast=True,
76 | )
77 |
78 | fitted_args = dict(
79 | matrixVt=mat_Vt,
80 | matrixWt=mat_Wt,
81 | matrixF=mat_F,
82 | vectorG=vec_G,
83 | lags=lags_model_all,
84 | indexLookupTable=index_lookup_table,
85 | profilesRecent=profiles_recent_table,
86 | E=E_type,
87 | T=T_type,
88 | S=S_type,
89 | nNonSeasonal=components_num_ETS,
90 | nSeasonal=components_num_ETS_seasonal,
91 | nArima=order,
92 | nXreg=xreg_number,
93 | constant=constant_required,
94 | vectorYt=y_in_sample,
95 | vectorOt=ot,
96 | backcast=True,
97 | )
98 |
99 | return adam_fitted, fitted_args
100 |
101 | sma_fitted, fitted_args = creator_sma(order=order)
102 |
103 | # need to convert some inputs to the expected dtypes. This is a temporary fix.
104 | fitted_args["lags"] = np.array(fitted_args["lags"], dtype="uint64")
105 | fitted_args["indexLookupTable"] = np.array(
106 | fitted_args["indexLookupTable"], dtype="uint64"
107 | )
108 |
109 | sma_forecast = adam_forecaster(
110 | matrixWt=fitted_args["matrixWt"],
111 | matrixF=fitted_args["matrixF"],
112 | lags=fitted_args["lags"],
113 | indexLookupTable=fitted_args["indexLookupTable"],
114 | profilesRecent=sma_fitted["profile"],
115 | E=fitted_args["E"],
116 | T=fitted_args["T"],
117 | S=fitted_args["S"],
118 | nNonSeasonal=fitted_args["nNonSeasonal"],
119 | nSeasonal=fitted_args["nSeasonal"],
120 | nArima=fitted_args["nArima"],
121 | nXreg=fitted_args["nXreg"],
122 | constant=fitted_args["constant"],
123 | horizon=h,
124 | )
125 |
126 | return sma_forecast
127 |
--------------------------------------------------------------------------------
/python/smooth/adam_general/core/utils/dump.py:
--------------------------------------------------------------------------------
1 | # estimator commented out lines 2754 to 2821
2 | adam_created_arima = filler(
3 | b_values['B'],
4 | ets_model, e_type, t_type, s_type, model_is_trendy, model_is_seasonal,
5 | components_number_ets, components_number_ets_non_seasonal,
6 | components_number_ets_seasonal, components_number_arima,
7 | lags, lags_model, lags_model_max,
8 | adam_created['mat_vt'], adam_created['mat_wt'], adam_created['mat_f'], adam_created['vec_g'],
9 | persistence_estimate, persistence_level_estimate, persistence_trend_estimate,
10 | persistence_seasonal_estimate, persistence_xreg_estimate,
11 | phi_estimate,
12 | initial_type, initial_estimate,
13 | initial_level_estimate, initial_trend_estimate, initial_seasonal_estimate,
14 | initial_arima_estimate, initial_xreg_estimate,
15 | arima_model, ar_estimate, ma_estimate, ar_orders, i_orders, ma_orders,
16 | ar_required, ma_required, arma_parameters,
17 | non_zero_ari, non_zero_ma, adam_created['arima_polynomials'],
18 | xreg_model, xreg_number,
19 | xreg_parameters_missing, xreg_parameters_included,
20 | xreg_parameters_estimated, xreg_parameters_persistence, constant_estimate
21 | )
22 |
23 | # Write down the initials in the recent profile
24 | profiles_recent_table[:] = adam_created_arima['mat_vt'][:, :lags_model_max]
25 |
26 | # Do initial fit to get the state values from the backcasting
27 | adam_fitted = adam_fitter_wrap(
28 | adam_created_arima['mat_vt'], adam_created_arima['mat_wt'], adam_created_arima['mat_f'], adam_created_arima['vec_g'],
29 | lags_model_all, index_lookup_table, profiles_recent_table,
30 | e_type, t_type, s_type, components_number_ets, components_number_ets_seasonal,
31 | components_number_arima, xreg_number, constant_required,
32 | y_in_sample, ot, True
33 | )
34 |
35 | adam_created['mat_vt'][:, :lags_model_max] = adam_fitted['mat_vt'][:, :lags_model_max]
36 | # Produce new initials
37 | b_values_new = initialiser(
38 | ets_model, e_type, t_type, s_type, model_is_trendy, model_is_seasonal,
39 | components_number_ets_non_seasonal, components_number_ets_seasonal, components_number_ets,
40 | lags, lags_model, lags_model_seasonal, lags_model_arima, lags_model_max,
41 | adam_created['mat_vt'],
42 | persistence_estimate, persistence_level_estimate, persistence_trend_estimate,
43 | persistence_seasonal_estimate, persistence_xreg_estimate,
44 | phi_estimate, initial_type, initial_estimate,
45 | initial_level_estimate, initial_trend_estimate, initial_seasonal_estimate,
46 | initial_arima_estimate, initial_xreg_estimate,
47 | arima_model, ar_required, ma_required, ar_estimate, ma_estimate, ar_orders, ma_orders,
48 | components_number_arima, components_names_arima, initial_arima_number,
49 | xreg_model, xreg_number,
50 | xreg_parameters_estimated, xreg_parameters_persistence,
51 | constant_estimate, constant_name, other_parameter_estimate
52 | )
53 | B = b_values_new['B']
54 | # Failsafe, just in case if the initial values contain NA / NaN
55 | B[np.isnan(B)] = b_values['B'][np.isnan(B)]
56 |
57 |
58 |
59 | # Fix for mixed ETS models producing negative values
60 | if (e_type == "M" and any(t in ["A", "Ad"] for t in [t_type, s_type]) or
61 | t_type == "M" and any(t in ["A", "Ad"] for t in [e_type, s_type]) or
62 | s_type == "M" and any(t in ["A", "Ad"] for t in [e_type, t_type])):
63 | if e_type == "M" and ("level" in B) and (B["level"] <= 0):
64 | B["level"] = y_in_sample[0]
65 | if t_type == "M" and ("trend" in B) and (B["trend"] <= 0):
66 | B["trend"] = 1
67 | seasonal_params = [p for p in B.keys() if p.startswith("seasonal")]
68 | if s_type == "M" and any(B[p] <= 0 for p in seasonal_params):
69 | for p in seasonal_params:
70 | if B[p] <= 0:
71 | B[p] = 1
--------------------------------------------------------------------------------
/python/smooth/adam_general/core/utils/ic.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 |
3 | def AIC(loglik, nobs=None, df=None):
4 | """
5 | Calculate Akaike Information Criterion
6 |
7 | Parameters
8 | ----------
9 | loglik : float or object with loglik attribute
10 | Log-likelihood value
11 | nobs : int, optional
12 | Number of observations
13 | df : int, optional
14 | Degrees of freedom (number of parameters)
15 |
16 | Returns
17 | -------
18 | float
19 | AIC value
20 | """
21 | # Extract loglik value if object is passed
22 | if hasattr(loglik, 'loglik'):
23 | loglik = loglik.loglik
24 | if hasattr(loglik, 'nobs'):
25 | nobs = loglik.nobs
26 | if hasattr(loglik, 'df'):
27 | df = loglik.df
28 |
29 | return -2 * loglik + 2 * df
30 |
31 | def AICc(loglik, nobs=None, df=None):
32 | """
33 | Calculate corrected Akaike Information Criterion
34 |
35 | Parameters
36 | ----------
37 | loglik : float or object with loglik attribute
38 | Log-likelihood value
39 | nobs : int, optional
40 | Number of observations
41 | df : int, optional
42 | Degrees of freedom (number of parameters)
43 |
44 | Returns
45 | -------
46 | float
47 | AICc value
48 | """
49 | # Extract loglik value if object is passed
50 | if hasattr(loglik, 'loglik'):
51 | loglik = loglik.loglik
52 | if hasattr(loglik, 'nobs'):
53 | nobs = loglik.nobs
54 | if hasattr(loglik, 'df'):
55 | df = loglik.df
56 |
57 | aic = AIC(loglik, nobs, df)
58 | return aic + (2 * df * (df + 1)) / (nobs - df - 1)
59 |
60 | def BIC(loglik, nobs=None, df=None):
61 | """
62 | Calculate Bayesian Information Criterion
63 |
64 | Parameters
65 | ----------
66 | loglik : float or object with loglik attribute
67 | Log-likelihood value
68 | nobs : int, optional
69 | Number of observations
70 | df : int, optional
71 | Degrees of freedom (number of parameters)
72 |
73 | Returns
74 | -------
75 | float
76 | BIC value
77 | """
78 | # Extract loglik value if object is passed
79 | if hasattr(loglik, 'loglik'):
80 | loglik = loglik.loglik
81 | if hasattr(loglik, 'nobs'):
82 | nobs = loglik.nobs
83 | if hasattr(loglik, 'df'):
84 | df = loglik.df
85 |
86 | return -2 * loglik + np.log(nobs) * df
87 |
88 | def BICc(loglik, nobs=None, df=None):
89 | """
90 | Calculate corrected Bayesian Information Criterion
91 |
92 | Parameters
93 | ----------
94 | loglik : float or object with loglik attribute
95 | Log-likelihood value
96 | nobs : int, optional
97 | Number of observations
98 | df : int, optional
99 | Degrees of freedom (number of parameters)
100 |
101 | Returns
102 | -------
103 | float
104 | BICc value
105 | """
106 | # Extract loglik value if object is passed
107 | if hasattr(loglik, 'loglik'):
108 | loglik = loglik.loglik
109 | if hasattr(loglik, 'nobs'):
110 | nobs = loglik.nobs
111 | if hasattr(loglik, 'df'):
112 | df = loglik.df
113 |
114 | bic = BIC(loglik, nobs, df)
115 | return bic + (np.log(nobs) * df * (df + 1)) / (nobs - df - 1)
116 |
117 | def ic_function(ic_name, loglik):
118 | """
119 | Select information criterion function based on name
120 |
121 | Parameters
122 | ----------
123 | ic_name : str
124 | Name of information criterion ('AIC', 'AICc', 'BIC', or 'BICc')
125 |
126 | Returns
127 | -------
128 | function
129 | Selected information criterion function
130 | """
131 | value = loglik['value']
132 | nobs = loglik['nobs']
133 | df = loglik['df']
134 | ic_functions = {
135 | 'AIC': AIC(value, nobs, df),
136 | 'AICc': AICc(value, nobs, df),
137 | 'BIC': BIC(value, nobs, df),
138 | 'BICc': BICc(value, nobs, df)
139 | }
140 |
141 | if ic_name not in ic_functions:
142 | raise ValueError(f"Invalid information criterion: {ic_name}. Must be one of {list(ic_functions.keys())}")
143 |
144 | return ic_functions[ic_name]
--------------------------------------------------------------------------------
/python/smooth/adam_general/core/utils/likelihood.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/config-i1/smooth/c529c51c1aa221fd49117f17e68064b57d2ae9ff/python/smooth/adam_general/core/utils/likelihood.py
--------------------------------------------------------------------------------
/python/smooth/adam_general/core/utils/polynomials.py:
--------------------------------------------------------------------------------
1 | def adam_polynomialiser(parameters, ar_orders, i_orders, ma_orders,
2 | ar_estimate, ma_estimate, arma_parameters, lags):
3 | """
4 | Creates polynomials for ARIMA models.
5 | """
6 | # Implementation of adam_polynomialiser goes here
7 | # You'll need to move this function from wherever it's currently defined
8 | pass
--------------------------------------------------------------------------------
/python/smooth/adam_general/load_r_package.py:
--------------------------------------------------------------------------------
1 | import os
2 | import rpy2.robjects as robjects
3 |
4 | def load_smooth_package():
5 | """
6 | Load the smooth R package in development mode.
7 | This ensures that any changes to the R code are immediately reflected.
8 | """
9 | # Get the path to the root of the smooth package
10 | current_dir = os.path.dirname(os.path.abspath(__file__))
11 | # Navigate up to the root directory (assuming we're in python/smooth/adam_general)
12 | root_dir = os.path.abspath(os.path.join(current_dir, "../../../"))
13 |
14 | # Load devtools and use load_all to load the package in development mode
15 | r_command = f"""
16 | if (!requireNamespace("devtools", quietly = TRUE)) {{
17 | install.packages("devtools", repos = "https://cran.rstudio.com/")
18 | }}
19 | devtools::load_all("{root_dir}")
20 | """
21 |
22 | # Execute the R command
23 | robjects.r(r_command)
24 |
25 | print("smooth R package loaded in development mode")
26 | return True
27 |
28 | # If this script is run directly, load the package
29 | if __name__ == "__main__":
30 | load_smooth_package()
--------------------------------------------------------------------------------
/python/smooth/adam_general/sma.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 |
3 | from smooth.adam_general._adam_general import adam_fitter, adam_forecaster
4 | from smooth.adam_general.adam_profile import adam_profile_creator
5 |
6 |
7 | def sma(y, order=1, h=10, holdout=False):
8 | """SMA"""
9 | y = y.astype(np.float64)
10 |
11 | # ic = lambda e: np.sum(e**2)
12 | obs_all = len(y) + h * (1 - holdout)
13 | obs_in_sample = len(y) - h * holdout
14 | y_in_sample = y
15 |
16 | E_type = "A"
17 | T_type = "N"
18 | S_type = "N"
19 |
20 | components_num_ETS = 0
21 | components_num_ETS_seasonal = 0
22 | xreg_number = 0
23 | constant_required = False
24 | ot = np.ones_like(y_in_sample)
25 |
26 | def creator_sma(order):
27 | # lags_model_all = np.ones(shape=(order, 1))
28 | # This needs to be a vector of values
29 | lags_model_all = np.arange(1, order + 1, dtype="int32").reshape(order, 1)
30 | lags_model_max = int(max(lags_model_all))
31 | obs_states = obs_in_sample + lags_model_max
32 |
33 | profiles_recent_table, index_lookup_table = adam_profile_creator(
34 | lags_model_all=lags_model_all,
35 | lags_model_max=lags_model_max,
36 | obs_all=obs_all,
37 | ).values()
38 |
39 | # # This needs to be generated by a profileCreator() function
40 | # profiles_recent_table = np.mean(y_in_sample[0 : (order - 1)]) * np.ones(
41 | # shape=(order, lags_model_max), dtype=np.float64
42 | # )
43 |
44 | # # This as well...
45 | # index_lookup_table = np.tile(
46 | # np.arange(order), (obs_all + lags_model_max, 1)
47 | # ).T
48 |
49 | mat_F = np.ones((order, order)) / order
50 | mat_Wt = np.ones((obs_in_sample, order))
51 |
52 | vec_G = np.ones(order) / order
53 | # matVt = np.zeros((order, obs_states))
54 | mat_Vt = np.empty((order, obs_states))
55 | # matVt.fill(np.nan)
56 |
57 | adam_fitted = adam_fitter(
58 | matrixVt=mat_Vt,
59 | matrixWt=mat_Wt,
60 | matrixF=mat_F,
61 | vectorG=vec_G,
62 | lags=lags_model_all,
63 | indexLookupTable=index_lookup_table,
64 | profilesRecent=profiles_recent_table,
65 | E=E_type,
66 | T=T_type,
67 | S=S_type,
68 | nNonSeasonal=components_num_ETS,
69 | nSeasonal=components_num_ETS_seasonal,
70 | nArima=order,
71 | nXreg=xreg_number,
72 | constant=constant_required,
73 | vectorYt=y_in_sample,
74 | vectorOt=ot,
75 | backcast=True,
76 | )
77 |
78 | fitted_args = dict(
79 | matrixVt=mat_Vt,
80 | matrixWt=mat_Wt,
81 | matrixF=mat_F,
82 | vectorG=vec_G,
83 | lags=lags_model_all,
84 | indexLookupTable=index_lookup_table,
85 | profilesRecent=profiles_recent_table,
86 | E=E_type,
87 | T=T_type,
88 | S=S_type,
89 | nNonSeasonal=components_num_ETS,
90 | nSeasonal=components_num_ETS_seasonal,
91 | nArima=order,
92 | nXreg=xreg_number,
93 | constant=constant_required,
94 | vectorYt=y_in_sample,
95 | vectorOt=ot,
96 | backcast=True,
97 | )
98 |
99 | return adam_fitted, fitted_args
100 |
101 | sma_fitted, fitted_args = creator_sma(order=order)
102 |
103 | # need to convert some inputs to the expected dtypes. This is a temporary fix.
104 | fitted_args["lags"] = np.array(fitted_args["lags"], dtype="uint64")
105 | fitted_args["indexLookupTable"] = np.array(
106 | fitted_args["indexLookupTable"], dtype="uint64"
107 | )
108 |
109 | sma_forecast = adam_forecaster(
110 | matrixWt=fitted_args["matrixWt"],
111 | matrixF=fitted_args["matrixF"],
112 | lags=fitted_args["lags"],
113 | indexLookupTable=fitted_args["indexLookupTable"],
114 | profilesRecent=sma_fitted["profile"],
115 | E=fitted_args["E"],
116 | T=fitted_args["T"],
117 | S=fitted_args["S"],
118 | nNonSeasonal=fitted_args["nNonSeasonal"],
119 | nSeasonal=fitted_args["nSeasonal"],
120 | nArima=fitted_args["nArima"],
121 | nXreg=fitted_args["nXreg"],
122 | constant=fitted_args["constant"],
123 | horizon=h,
124 | )
125 |
126 | return sma_forecast
127 |
--------------------------------------------------------------------------------
/python/smooth/adam_general/test.py:
--------------------------------------------------------------------------------
1 |
2 | import pandas as pd
3 | import numpy as np
4 | from core.checker import parameters_checker
5 | from typing import List, Union, Dict, Any
6 | from smooth.adam_general._adam_general import adam_fitter, adam_forecaster
7 | from core.utils.utils import measurement_inverter, scaler, calculate_likelihood, calculate_entropy, calculate_multistep_loss
8 | from numpy.linalg import eigvals
9 | import nlopt
10 | from core.adam import Adam
11 |
12 |
13 | import pandas as pd
14 | import numpy as np
15 | # Create the AirPassengers dataset manually
16 | data = [
17 | 112, 118, 132, 129, 121, 135, 148, 148, 136, 119, 104, 118,
18 | 115, 126, 141, 135, 125, 149, 170, 170, 158, 133, 114, 140,
19 | 145, 150, 178, 163, 172, 178, 199, 199, 184, 162, 146, 166,
20 | 171, 180, 193, 181, 183, 218, 230, 242, 209, 191, 172, 194,
21 | 196, 196, 236, 235, 229, 243, 264, 272, 237, 211, 180, 201,
22 | 204, 188, 235, 227, 234, 264, 302, 293, 259, 229, 203, 229,
23 | 242, 233, 267, 269, 270, 315, 364, 347, 312, 274, 237, 278,
24 | 284, 277, 317, 313, 318, 374, 413, 405, 355, 306, 271, 306,
25 | 315, 301, 356, 348, 355, 422, 465, 467, 404, 347, 305, 336,
26 | 340, 318, 362, 348, 363, 435, 491, 505, 404, 359, 310, 337,
27 | 360, 342, 406, 396, 420, 472, 548, 559, 463, 407, 362, 405,
28 | 417, 391, 419, 461, 472, 535, 622, 606, 508, 461, 390, 432
29 | ]
30 |
31 | # Create a proper datetime index
32 | dates = pd.date_range(start='1949-01-01', periods=len(data), freq='MS')
33 |
34 | # Create a pandas Series with the data
35 | air_passengers_series = pd.Series(data, index=dates, name='AirPassengers')
36 |
37 | # Create a DataFrame with the time series
38 | ts_df = pd.DataFrame({'value': air_passengers_series})
39 |
40 | print("AirPassengers dataset loaded:")
41 | print(ts_df.head())
42 |
43 | import time
44 |
45 | start_time = time.time()
46 |
47 | model = "AAA"
48 | lags = [12]
49 | h = 12
50 |
51 | adam = Adam(model, lags)
52 | adam.fit(ts_df, h = h)
53 | fc = adam.predict()
54 | execution_time = time.time() - start_time
55 | print(f"Execution time: {execution_time:.4f} seconds")
56 | fc['forecast']
57 |
--------------------------------------------------------------------------------
/python/smooth/adam_general/test_script.py:
--------------------------------------------------------------------------------
1 | from core.adam import Adam
2 |
3 | import pandas as pd
4 | import numpy as np
5 | from core.checker import parameters_checker
6 | from typing import List, Union, Dict, Any
7 | from smooth.adam_general._adam_general import adam_fitter, adam_forecaster
8 | from core.utils.utils import measurement_inverter, scaler, calculate_likelihood, calculate_entropy, calculate_multistep_loss
9 | from numpy.linalg import eigvals
10 | import nlopt
11 |
12 | from core.estimator import estimator, selector
13 | from core.creator import creator, initialiser, architector, filler
14 | from core.utils.ic import ic_function
15 |
16 | from smooth.adam_general._adam_general import adam_fitter, adam_forecaster
17 |
18 | import warnings
19 |
20 | # Generate random monthly time series data
21 | np.random.seed(41) # For reproducibility
22 | n_points = 24 # 2 years of monthly data
23 | time_series = np.random.randint(1, 100, size=n_points).cumsum() # Random walk with strictly positive integers
24 | dates = pd.date_range(start='2023-01-01', periods=n_points, freq='M') # Monthly frequency
25 | ts_df = pd.DataFrame({'value': time_series}, index=dates)
26 |
27 | model = "ANN"
28 | lags = [12]
29 | multisteps = False,
30 | lb = None,
31 | ub = None,
32 | maxtime = None,
33 | print_level = 1, # 1 or 0
34 | maxeval = None,
35 | h = 12
36 |
37 |
38 |
39 | # Assume that the model is not provided
40 | # these will be default arguments
41 | profiles_recent_provided = False
42 | profiles_recent_table = None
43 |
44 | adam = Adam(model, lags)
45 | adam.fit(ts_df, h = h)
--------------------------------------------------------------------------------
/python/smooth/adam_general/tests_2.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 3,
6 | "metadata": {},
7 | "outputs": [],
8 | "source": [
9 | "import numpy as np\n",
10 | "import pandas as pd\n",
11 | "from statsmodels.tsa.stattools import acf, pacf"
12 | ]
13 | },
14 | {
15 | "cell_type": "code",
16 | "execution_count": 6,
17 | "metadata": {},
18 | "outputs": [],
19 | "source": [
20 | "def calculate_acf(data, nlags=40):\n",
21 | " \"\"\"\n",
22 | " Calculate Autocorrelation Function for numpy array or pandas Series.\n",
23 | " \n",
24 | " Parameters:\n",
25 | " data (np.array or pd.Series): Input time series data\n",
26 | " nlags (int): Number of lags to calculate ACF for\n",
27 | " \n",
28 | " Returns:\n",
29 | " np.array: ACF values\n",
30 | " \"\"\"\n",
31 | " if isinstance(data, pd.Series):\n",
32 | " data = data.values\n",
33 | " \n",
34 | " return acf(data, nlags=nlags, fft=False)\n",
35 | "\n",
36 | "def calculate_pacf(data, nlags=40):\n",
37 | " \"\"\"\n",
38 | " Calculate Partial Autocorrelation Function for numpy array or pandas Series.\n",
39 | " \n",
40 | " Parameters:\n",
41 | " data (np.array or pd.Series): Input time series data\n",
42 | " nlags (int): Number of lags to calculate PACF for\n",
43 | " \n",
44 | " Returns:\n",
45 | " np.array: PACF values\n",
46 | " \"\"\"\n",
47 | " if isinstance(data, pd.Series):\n",
48 | " data = data.values\n",
49 | " \n",
50 | " return pacf(data, nlags=nlags, method='ols')\n"
51 | ]
52 | },
53 | {
54 | "cell_type": "code",
55 | "execution_count": 7,
56 | "metadata": {},
57 | "outputs": [],
58 | "source": [
59 | "# Example usage\n",
60 | "np.random.seed(42)\n",
61 | "date_rng = pd.date_range(start='2023-01-01', end='2023-12-31', freq='D')\n",
62 | "data = np.random.randn(len(date_rng)).cumsum() + 100\n",
63 | "\n",
64 | "# Create both numpy array and pandas Series\n",
65 | "np_array = data\n",
66 | "pd_series = pd.Series(data, index=date_rng)\n",
67 | "\n",
68 | "# Calculate ACF and PACF for numpy array\n",
69 | "acf_values_np = calculate_acf(np_array)\n",
70 | "pacf_values_np = calculate_pacf(np_array)\n",
71 | "\n",
72 | "# Calculate ACF and PACF for pandas Series\n",
73 | "acf_values_pd = calculate_acf(pd_series)\n",
74 | "pacf_values_pd = calculate_pacf(pd_series)"
75 | ]
76 | },
77 | {
78 | "cell_type": "code",
79 | "execution_count": 8,
80 | "metadata": {},
81 | "outputs": [
82 | {
83 | "data": {
84 | "text/plain": [
85 | "array([1. , 0.98020447, 0.96291875, 0.9463405 , 0.92780577,\n",
86 | " 0.91353458, 0.89787089, 0.87908942, 0.85978813, 0.8416599 ,\n",
87 | " 0.82210143, 0.80328791, 0.78346136, 0.76302172, 0.74567016,\n",
88 | " 0.73017225, 0.71631451, 0.7022657 , 0.68757643, 0.67004954,\n",
89 | " 0.65347832, 0.6397477 , 0.6274798 , 0.61489008, 0.60059905,\n",
90 | " 0.5850292 , 0.57013909, 0.55543017, 0.54231908, 0.52999088,\n",
91 | " 0.51743239, 0.50457837, 0.49134351, 0.47703597, 0.46376578,\n",
92 | " 0.44944496, 0.43629551, 0.42195921, 0.41021392, 0.40102178,\n",
93 | " 0.39067492])"
94 | ]
95 | },
96 | "execution_count": 8,
97 | "metadata": {},
98 | "output_type": "execute_result"
99 | }
100 | ],
101 | "source": [
102 | "acf_values_np"
103 | ]
104 | }
105 | ],
106 | "metadata": {
107 | "kernelspec": {
108 | "display_name": ".venv",
109 | "language": "python",
110 | "name": "python3"
111 | },
112 | "language_info": {
113 | "codemirror_mode": {
114 | "name": "ipython",
115 | "version": 3
116 | },
117 | "file_extension": ".py",
118 | "mimetype": "text/x-python",
119 | "name": "python",
120 | "nbconvert_exporter": "python",
121 | "pygments_lexer": "ipython3",
122 | "version": "3.8.10"
123 | }
124 | },
125 | "nbformat": 4,
126 | "nbformat_minor": 2
127 | }
128 |
--------------------------------------------------------------------------------
/smooth.Rproj:
--------------------------------------------------------------------------------
1 | Version: 1.0
2 | ProjectId: f8f33844-318a-42de-9bed-71e43b9ac780
3 |
4 | RestoreWorkspace: Default
5 | SaveWorkspace: Default
6 | AlwaysSaveHistory: Default
7 |
8 | EnableCodeIndexing: Yes
9 | UseSpacesForTab: Yes
10 | NumSpacesForTab: 4
11 | Encoding: UTF-8
12 |
13 | RnwWeave: knitr
14 | LaTeX: pdfLaTeX
15 |
16 | AutoAppendNewline: Yes
17 | StripTrailingWhitespace: Yes
18 |
19 | BuildType: Package
20 | PackageUseDevtools: Yes
21 | PackageInstallArgs: --no-multiarch --with-keep.source
22 | PackageRoxygenize: rd,collate,namespace
23 |
--------------------------------------------------------------------------------
/src/Makevars:
--------------------------------------------------------------------------------
1 | ## Use the R_HOME indirection to support installations of multiple R version
2 | ##PKG_CXXFLAGS=`Rscript -e "Rcpp:::CxxFlags()"`
3 | ##PKG_LIBS=$(`Rscript -e "Rcpp:::LdFlags()"`)
4 | PKG_LIBS=$(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS)
5 | #CXX_STD = CXX11
6 |
--------------------------------------------------------------------------------
/src/Makevars.win:
--------------------------------------------------------------------------------
1 | #PKG_CXXFLAGS=$(shell $(R_HOME)/bin${R_ARCH_BIN}/Rscript.exe -e "Rcpp:::CxxFlags()")
2 | #PKG_LIBS = $(shell $(R_HOME)/bin${R_ARCH_BIN}/Rscript.exe -e "Rcpp:::LdFlags()") $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS)
3 | PKG_LIBS=$(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS)
4 | #CXX_STD = CXX11
5 |
--------------------------------------------------------------------------------
/src/adamSimulator.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include "adamGeneral.h"
5 | // [[Rcpp::depends(RcppArmadillo)]]
6 |
7 | using namespace Rcpp;
8 |
9 | // ##### Script for simulate functions
10 | List adamSimulator(arma::cube &arrayVt, arma::mat const &matrixErrors, arma::mat const &matrixOt,
11 | arma::cube const &arrayF, arma::mat const &matrixWt, arma::mat const &matrixG,
12 | char const &E, char const &T, char const &S, arma::uvec &lags,
13 | arma::umat const &indexLookupTable, arma::mat profilesRecent,
14 | unsigned int const &nNonSeasonal, unsigned int const &nSeasonal,
15 | unsigned int const &nArima, unsigned int const &nXreg, bool const &constant) {
16 |
17 | unsigned int obs = matrixErrors.n_rows;
18 | unsigned int nSeries = matrixErrors.n_cols;
19 |
20 | int lagsModelMax = max(lags);
21 | unsigned int nETS = nNonSeasonal + nSeasonal;
22 | int nComponents = lags.n_rows;
23 | int obsAll = obs + lagsModelMax;
24 | arma::mat profilesRecentOriginal = profilesRecent;
25 |
26 | arma::mat matrixVt(nComponents, obsAll, arma::fill::zeros);
27 | arma::mat matrixF(arrayF.n_rows, arrayF.n_cols, arma::fill::zeros);
28 |
29 | arma::mat matY(obs, nSeries);
30 |
31 | for(unsigned int i=0; i1e+100)){
72 | // matrixVt.col(j) = matrixVt(lagrows);
73 | // }
74 | matrixVt.col(j) = profilesRecent(indexLookupTable.col(j-lagsModelMax));
75 | }
76 | arrayVt.slice(i) = matrixVt;
77 | }
78 |
79 | return List::create(Named("arrayVt") = arrayVt, Named("matrixYt") = matY);
80 | }
81 |
82 | /* # Wrapper for simulator */
83 | // [[Rcpp::export]]
84 | RcppExport SEXP adamSimulatorWrap(arma::cube arrayVt, arma::mat matrixErrors, arma::mat matrixOt,
85 | arma::cube arrayF, arma::mat matrixWt, arma::mat matrixG,
86 | char const &E, char const &T, char const &S, arma::uvec lags,
87 | arma::umat indexLookupTable, arma::mat profilesRecent,
88 | unsigned int const &nSeasonal, unsigned int const &componentsNumber,
89 | unsigned int const &nArima, unsigned int const &nXreg, bool const &constant){
90 |
91 | unsigned int nNonSeasonal = componentsNumber - nSeasonal;
92 |
93 | return wrap(adamSimulator(arrayVt, matrixErrors, matrixOt, arrayF, matrixWt, matrixG,
94 | E, T, S, lags, indexLookupTable, profilesRecent,
95 | nNonSeasonal, nSeasonal, nArima, nXreg, constant));
96 | }
97 |
--------------------------------------------------------------------------------
/src/matrixPowerWrap.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include "ssGeneral.h"
3 |
4 | // [[Rcpp::export]]
5 | RcppExport SEXP matrixPowerWrap(SEXP matA, SEXP power){
6 | NumericMatrix matA_n(matA);
7 | arma::mat matrixA(matA_n.begin(), matA_n.nrow(), matA_n.ncol(), false);
8 |
9 | int pow = as(power);
10 |
11 | return wrap(matrixPower(matrixA, pow));
12 | }
13 |
--------------------------------------------------------------------------------
/src/python_examples/my_linalg.cpp:
--------------------------------------------------------------------------------
1 | // example.cpp: Leonidas Tsaprounis
2 | // Description: Example for pybind11 and carma. Adjusted from the example from https://pybind11.readthedocs.io/en/stable/basics.html#first-steps
3 |
4 | #include
5 | #include
6 |
7 | #include
8 | #include
9 | namespace py = pybind11;
10 |
11 | int add(int i, int j)
12 | {
13 | return i + j;
14 | }
15 |
16 | float dot_product(py::array_t arr1, py::array_t arr2)
17 | {
18 | float result = 0;
19 | py::buffer_info buff1 = arr1.request();
20 | py::buffer_info buff2 = arr2.request();
21 | int length = buff1.shape[0];
22 | double *ptr1 = (double *)buff1.ptr;
23 | double *ptr2 = (double *)buff2.ptr;
24 | for (int i = 0; i < length; i++)
25 | {
26 | result += ptr1[i] * ptr2[i];
27 | }
28 | return result;
29 | }
30 |
31 | py::array_t array_sum(py::array_t arr1, py::array_t arr2)
32 | {
33 | py::buffer_info buff1 = arr1.request();
34 | py::buffer_info buff2 = arr2.request();
35 | int length = buff1.shape[0];
36 | // define the result variable.
37 | py::array_t result = py::array_t(buff1.size);
38 | py::buffer_info buff_result = result.request();
39 | double *ptr1 = (double *)buff1.ptr;
40 | double *ptr2 = (double *)buff2.ptr;
41 | double *ptr3 = (double *)buff_result.ptr;
42 | #pragma omp parallel for simd
43 | for (int i = 0; i < length; i++)
44 | {
45 | ptr3[i] = ptr1[i] + ptr2[i];
46 | }
47 | return result;
48 | }
49 |
50 | // armadillo dot product with carma autoconversion
51 | double arma_dot_product(arma::Col arr1, arma::Col arr2)
52 | {
53 | double result = arma::dot(arr1, arr2);
54 | return result;
55 | }
56 |
57 | PYBIND11_MODULE(_my_linalg, m)
58 | {
59 | m.doc() = "pybind11 example plugin"; // module docstring
60 | m.attr("example_attr") = "An example attr";
61 | m.def("add", &add, "A function that adds two numbers", py::arg("i"), py::arg("j"));
62 | m.def(
63 | "dot_product",
64 | &dot_product,
65 | "dot product of 2 simple numpy arrays",
66 | py::arg("arr1"),
67 | py::arg("arr2"));
68 | m.def(
69 | "arma_dot_product",
70 | &arma_dot_product,
71 | "armadillo based dot product of 2 simple numpy arrays",
72 | py::arg("arr1"),
73 | py::arg("arr2"));
74 | m.def(
75 | "array_sum",
76 | &array_sum,
77 | "Sums 2 numpy arrays",
78 | py::arg("arr1"),
79 | py::arg("arr2"));
80 | }
81 |
--------------------------------------------------------------------------------
/src/registerDynamicSymbol.c:
--------------------------------------------------------------------------------
1 | // RegisteringDynamic Symbols
2 |
3 | #include
4 | #include
5 | #include
6 |
7 | void R_init_smooth(DllInfo* info) {
8 | R_registerRoutines(info, NULL, NULL, NULL, NULL);
9 | R_useDynamicSymbols(info, TRUE);
10 | }
11 |
--------------------------------------------------------------------------------
/src/ssSimulator.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include "ssGeneral.h"
5 | // [[Rcpp::depends(RcppArmadillo)]]
6 |
7 | using namespace Rcpp;
8 |
9 |
10 | // ##### Script for simulate functions
11 | List simulator(arma::cube &arrayVt, arma::mat const &matrixerrors, arma::mat const &matrixot,
12 | arma::cube const &arrayF, arma::rowvec const &rowvecW, arma::mat const &matrixG,
13 | unsigned int const &obs, unsigned int const &nseries,
14 | char const &E, char const &T, char const &S, arma::uvec &lags) {
15 |
16 | arma::mat matY(obs, nseries);
17 | arma::rowvec rowvecXt(1, arma::fill::zeros);
18 | arma::vec vecAt(1, arma::fill::zeros);
19 |
20 | int lagslength = lags.n_rows;
21 | unsigned int maxlag = max(lags);
22 | int obsall = obs + maxlag;
23 |
24 | lags = maxlag - lags;
25 |
26 | for(int i=1; i(Etype);
96 | char T = as(Ttype);
97 | char S = as(Stype);
98 |
99 | IntegerVector modellags_n(modellags);
100 | arma::uvec lags = as(modellags_n);
101 |
102 | return wrap(simulator(arrayVt, matrixerrors, matrixot, arrayF, rowvecW, matrixG,
103 | obs, nseries, E, T, S, lags));
104 | }
105 |
--------------------------------------------------------------------------------
/tests/testthat.R:
--------------------------------------------------------------------------------
1 | library(testthat)
2 | library(smooth)
3 |
4 | test_check("smooth")
5 |
--------------------------------------------------------------------------------
/tests/testthat/test_ces.R:
--------------------------------------------------------------------------------
1 | context("Tests for ces() function");
2 |
3 | # Basic CES selection
4 | testModel <- auto.ces(AirPassengers, silent=TRUE);
5 | test_that("Test CES selection on BJsales", {
6 | expect_match(testModel$seasonality, "partial");
7 | })
8 |
9 | # Reuse previous CES
10 | test_that("Test on AirPassengers, predefined CES", {
11 | expect_equal(ces(AirPassengers, model=testModel, silent=TRUE)$loss, testModel$loss);
12 | })
13 |
14 | # Test trace cost function for CES
15 | testModel <- ces(AirPassengers, seasonality="f", h=18, holdout=TRUE, silent=TRUE)
16 | test_that("Test AICc of CES based on MSTFE on AirPassengers", {
17 | expect_equal(as.numeric(logLik(testModel)), as.numeric(testModel$logLik));
18 | })
19 |
20 | # Test how different passed values are accepted by CES
21 | test_that("Test provided a and b of CES on AirPassengers", {
22 | expect_equal(ces(AirPassengers, seasonality="f", a=testModel$parameters$a, silent=TRUE)$parameters$a,
23 | testModel$parameters$a);
24 | expect_equal(ces(AirPassengers, seasonality="f", b=testModel$parameters$b, silent=TRUE)$parameters$b,
25 | testModel$parameters$b);
26 | })
27 |
28 | # Test selection of exogenous with CES
29 | test_that("Use exogenous variables for CESX on BJsales", {
30 | skip_on_cran()
31 | testModel <- ces(BJsales, h=18, holdout=TRUE, silent=TRUE, regressors="use", xreg=BJsales.lead)
32 | expect_equal(length(testModel$initial$xreg),1);
33 | })
34 |
--------------------------------------------------------------------------------
/tests/testthat/test_es.R:
--------------------------------------------------------------------------------
1 | context("Tests for es() function");
2 |
3 | # Basic ETS selection
4 | testModel <- es(BJsales, silent=TRUE);
5 | test_that("Test ETS selection on BJsales", {
6 | expect_equal(length(testModel$ICs), 9);
7 | })
8 |
9 | test_that("Test damped-trend ETS on BJsales", {
10 | expect_equal(es(BJsales,model="AAdN", silent=TRUE)$phi, 0.88, tolerance=0.1);
11 | })
12 |
13 | # Reuse previous ETS
14 | test_that("Test on BJsales, predefined ETS", {
15 | expect_equal(es(BJsales, model=testModel, silent=TRUE)$cf, testModel$cf);
16 | })
17 |
18 | # Test combinations of ETS
19 | test_that("Test ETS(CCC) with BIC on AirPassengers", {
20 | skip_on_cran
21 | testModel <- es(AirPassengers, "CCC", silent=TRUE, ic="BIC");
22 | expect_equal(testModel$scale^2, mean(residuals(testModel)^2));
23 | })
24 |
25 | # Test model selection of non-multiplicative trend ETS
26 | test_that("Test ETS(MXM) with AIC on AirPassengers", {
27 | skip_on_cran()
28 | testModel <- es(AirPassengers, "MXM", silent=TRUE, ic="AIC");
29 | expect_match(testModel$loss, "likelihood");
30 | })
31 |
32 | # Test trace cost function for ETS
33 | testModel <- es(AirPassengers, model="MAdM", h=18, holdout=TRUE, silent=TRUE)
34 | test_that("Test AIC of ETS on AirPassengers", {
35 | expect_equal(as.numeric(round(AICc(testModel),2)), as.numeric(round(testModel$ICs,2)));
36 | })
37 |
38 | # Test how different passed values are accepted by ETS
39 | test_that("Test initials, initialSeason and persistence of ETS on AirPassengers", {
40 | skip_on_cran()
41 | expect_equal(es(AirPassengers, model="MAdM", initial=testModel$initial, silent=TRUE)$initial, testModel$initial);
42 | expect_equal(es(AirPassengers, model="MAdM", persistence=testModel$persistence, silent=TRUE)$persistence, testModel$persistence);
43 | expect_equal(es(AirPassengers, model="MAdM", initialSeason=testModel$initialSeason, silent=TRUE)$initialSeason, testModel$initialSeason);
44 | expect_equal(es(AirPassengers, model="MAdM", phi=testModel$phi, silent=TRUE)$phi, testModel$phi);
45 | })
46 |
47 | x <- BJsales.lead;
48 | y <- BJsales;
49 | # Test selection of exogenous with ETS
50 | test_that("Use exogenous variables for ETS on BJsales", {
51 | skip_on_cran()
52 | testModel <- es(y, h=18, holdout=TRUE, xreg=xregExpander(x), silent=TRUE, regressors="use")
53 | expect_equal(length(testModel$initial$xreg),3);
54 | })
55 |
56 | # Test combination of ETS with exogenous selection
57 | test_that("Select exogenous variables for ETSX combined on BJsales", {
58 | skip_on_cran()
59 | testModel <- es(y, "CCC", h=18, holdout=TRUE, xreg=x, silent=TRUE, regressors="select")
60 | expect_match(modelType(testModel), "CCN");
61 | })
62 |
--------------------------------------------------------------------------------
/tests/testthat/test_gum.R:
--------------------------------------------------------------------------------
1 | context("Tests for gum() function")
2 |
3 | # Basic GUM selection
4 | testModel <- gum(BJsales, orders=c(2,1),lags=c(1,4), silent=TRUE, initial="optimal")
5 | test_that("Test if GUM worked on BJsales", {
6 | expect_equal(testModel$model, "GUM(2[1],1[4])")
7 | })
8 |
9 | # Reuse previous GUM
10 | test_that("Reuse previous GUM on BJsales", {
11 | expect_equal(gum(BJsales, model=testModel, silent=TRUE)$lossValue, testModel$lossValue)
12 | })
13 |
14 | # Test some crazy order of GUM
15 | test_that("Test if crazy order GUM was estimated on BJsales", {
16 | skip_on_cran()
17 | testModel <- gum(BJsales, orders=c(1,1,1), lags=c(1,3,5), h=18, holdout=TRUE, initial="o", silent=TRUE)
18 | expect_equal(testModel$model, "GUM(1[1],1[3],1[5])")
19 | })
20 |
21 | # Test how different passed values are accepted by GUM
22 | test_that("Test initials, measurement, transition and persistence of GUM on AirPassengers", {
23 | skip_on_cran()
24 | testModel <- gum(AirPassengers, orders=c(1,1,1), lags=c(1,3,5),
25 | h=18, holdout=TRUE, initial="o", silent=TRUE)
26 | expect_equal(gum(AirPassengers, orders=c(1,1,1), lags=c(1,3,5),
27 | initial=testModel$initial, h=18, holdout=TRUE, silent=TRUE)$initial, testModel$initial)
28 | expect_equal(gum(AirPassengers, orders=c(1,1,1), lags=c(1,3,5),
29 | measurement=testModel$measurement, h=18, holdout=TRUE, silent=TRUE)$measurement, testModel$measurement)
30 | expect_equal(gum(AirPassengers, orders=c(1,1,1), lags=c(1,3,5),
31 | transition=testModel$transition, h=18, holdout=TRUE, silent=TRUE)$transition, testModel$transition)
32 | expect_equal(gum(AirPassengers, orders=c(1,1,1), lags=c(1,3,5),
33 | persistence=testModel$persistence, h=18, holdout=TRUE, silent=TRUE)$persistence, testModel$persistence)
34 | })
35 |
36 | # Test selection of exogenous with GUM
37 | test_that("Select exogenous variables for GUMX on BJsales", {
38 | skip_on_cran()
39 | xregData <- cbind(y=BJsales, x=BJsales.lead)
40 | testModel <- gum(xregData, h=18, holdout=TRUE, silent=TRUE)
41 | expect_match(errorType(testModel),"A")
42 | })
43 |
44 | # Use automatic GUM
45 | test_that("Use automatic GUM on BJsales", {
46 | skip_on_cran()
47 | expect_equal(auto.gum(BJsales, silent=TRUE)$loss, "likelihood")
48 | })
49 |
--------------------------------------------------------------------------------
/tests/testthat/test_oes.R:
--------------------------------------------------------------------------------
1 | context("Tests for oes() function")
2 |
3 | # ISS with fixed probability
4 | testModel <- oes(rpois(100,0.2), occurrence="f")
5 | test_that("Test oes with fixed probability", {
6 | expect_equal(testModel$occurrence, "fixed")
7 | })
8 |
9 | # oes with Inverse odds ratio probability
10 | testModel <- oes(rpois(100,0.2), occurrence="i")
11 | test_that("Test oes with Iverse odds ratio probability", {
12 | expect_equal(testModel$occurrence, "inverse-odds-ratio")
13 | })
14 |
15 | # oes with odds ratio probability
16 | testModel <- oes(rpois(100,0.2), occurrence="o")
17 | test_that("Test oes with Odds ratio probability", {
18 | expect_equal(testModel$occurrence, "odds-ratio")
19 | })
20 |
21 | # oes with odds ratio probability and ETS(MMN)
22 | testModel <- oes(rpois(100,0.2), occurrence="o", model="MMN")
23 | test_that("Test oes with Odds ratio probability and ETS(MMN)", {
24 | expect_equal(length(testModel$persistence), 2)
25 | })
26 |
27 | # oes with automatically selected type of model and ETS(MMN)
28 | test_that("Test oes with auto probability selected", {
29 | skip_on_cran()
30 | testModel <- oes(rpois(100,0.2), occurrence="a")
31 | expect_equal(length(testModel$persistence), 1)
32 | })
33 |
--------------------------------------------------------------------------------
/tests/testthat/test_simulate.R:
--------------------------------------------------------------------------------
1 | context("Tests for simulate() functions")
2 |
3 | #### ETS ####
4 | testData <- sim.es("MNN", frequency=12, bounds="a", obs=100)
5 | test_that("ETS(MNN) simulated with admissible bounds", {
6 | expect_match(testData$model, "MNN")
7 | })
8 |
9 | testData <- sim.es("AAdM", frequency=12, phi=0.9, obs=120)
10 | test_that("ETS(AAdM) simulated with phi=0.9", {
11 | expect_match(testData$model, "AAdM")
12 | })
13 |
14 | testData <- sim.es("MNN", frequency=12, obs=120, nsim=100, probability=0.2)
15 | test_that("iETS(MNN) simulated with probability=0.2 and nsim=100", {
16 | expect_match(testData$model, "MNN")
17 | })
18 |
19 | testModel <- es(AirPassengers, "ANA", h=18, silent=TRUE)
20 | test_that("ETS(ANA) simulated from estimated model", {
21 | expect_match(simulate(testModel,nsim=10,seed=5,obs=100)$model, "ANA")
22 | })
23 |
24 | #### SSARIMA ####
25 | testModel <- auto.ssarima(BJsales, h=8, silent=TRUE)
26 | test_that("ARIMA(0,1,3) with drift simulated from estimated model", {
27 | expect_match(errorType(simulate(testModel,nsim=10,seed=5,obs=100)), "A")
28 | })
29 |
30 | test_that("ARIMA(0,1,1) with intermittent data", {
31 | expect_match(sim.ssarima(nsim=10,obs=100,probability=0.2)$model, "iARIMA")
32 | })
33 |
34 | #### CES ####
35 | testModel <- auto.ces(BJsales, h=8, silent=TRUE)
36 | test_that("CES(n) simulated from estimated model", {
37 | expect_match(simulate(testModel,nsim=10,seed=5,obs=100)$model, "(n)")
38 | })
39 |
40 | test_that("CES(s) with some random parameters", {
41 | expect_match(sim.ces(seasonality="s",frequency=4,nsim=1,obs=100)$model, "(s)")
42 | })
43 |
44 | test_that("CES(p) with some random A parameter and fixed b=0.1 ", {
45 | expect_equal(sim.ces(seasonality="p",frequency=4,b=0.1,nsim=1,obs=100)$b[1], 0.1)
46 | })
47 |
48 | test_that("CES(f) with intermittent data", {
49 | expect_match(sim.ces(seasonality="f",frequency=12,nsim=10,obs=100,probability=0.2)$model, "iCES")
50 | })
51 |
52 | #### GUM ####
53 | testModel <- gum(BJsales, orders=1, lags=1, h=8, silent=TRUE)
54 | test_that("GUM(1[1]) simulated from estimated model", {
55 | expect_match(simulate(testModel,nsim=10,seed=5,obs=100)$model, "GUM")
56 | })
57 |
58 | test_that("GUM(1[1]) with intermittent data", {
59 | expect_match(sim.gum(nsim=10,obs=100,probability=0.2)$model, "iGUM")
60 | })
61 |
62 | #### SMA ####
63 | test_that("SMA(10) with intermittent data", {
64 | expect_match(sim.sma(10,nsim=10,obs=100,probability=0.2)$model, "iSMA")
65 | })
66 |
--------------------------------------------------------------------------------
/tests/testthat/test_ssarima.R:
--------------------------------------------------------------------------------
1 | context("Tests for ssarima() function")
2 |
3 | # Basic SSARIMA selection
4 | testModel <- auto.ssarima(BJsales, silent=TRUE)
5 | test_that("Test if Auto SSARIMA selected correct model for BJsales", {
6 | expect_equal(testModel$model, ssarima(BJsales, model=testModel)$model)
7 | })
8 |
9 | # Reuse previous SSARIMA
10 | test_that("Reuse previous SSARIMA on BJsales", {
11 | expect_equal(ssarima(BJsales, model=testModel, silent=TRUE)$cf, testModel$cf)
12 | })
13 |
14 | # Test some crazy order of SSARIMA
15 | test_that("Test if crazy order SSARIMA was estimated on AirPassengers", {
16 | skip_on_cran()
17 | testModel <- ssarima(AirPassengers, orders=list(ar=c(1,1,0), i=c(1,0,1),ma=c(0,1,1)),
18 | lags=c(1,6,12), h=18, holdout=TRUE, initial="o", silent=TRUE, interval=TRUE)
19 | expect_equal(testModel$model, "SSARIMA(1,1,0)[1](1,0,1)[6](0,1,1)[12]")
20 | })
21 |
22 | # Test selection of exogenous with Auto.SSARIMA
23 | test_that("Use exogenous variables for auto SSARIMAX on BJsales with selection", {
24 | skip_on_cran()
25 | testModel <- auto.ssarima(BJsales, orders=list(ar=3,i=2,ma=3), lags=1, h=18, holdout=TRUE,
26 | regressors="use", silent=TRUE, xreg=xregExpander(BJsales.lead))
27 | expect_equal(length(testModel$initial$xreg),3)
28 | })
29 |
--------------------------------------------------------------------------------
/vignettes/.install_extras:
--------------------------------------------------------------------------------
1 | smooth-Documentation.pdf
2 |
--------------------------------------------------------------------------------
/vignettes/ces.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "ces() - Complex Exponential Smoothing"
3 | author: "Ivan Svetunkov"
4 | date: "`r Sys.Date()`"
5 | output: rmarkdown::html_vignette
6 | vignette: >
7 | %\VignetteIndexEntry{ces() - Complex Exponential Smoothing}
8 | %\VignetteEngine{knitr::rmarkdown}
9 | %\VignetteEncoding{UTF-8}
10 | ---
11 |
12 | ```{r global_options, include=FALSE}
13 | knitr::opts_chunk$set(fig.width=6, fig.height=4, fig.path='Figs/', fig.show='hold',
14 | warning=FALSE, message=FALSE)
15 | ```
16 |
17 | This vignette covers `ces()` and `auto.ces()` functions, which are part of [smooth package](smooth.html).
18 |
19 | Let's load the necessary packages:
20 |
21 | ```{r load_libraries, message=FALSE, warning=FALSE}
22 | require(smooth)
23 | ```
24 |
25 | `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:
26 |
27 | For the same series from M3 dataset `ces()` can be constructed using:
28 | ```{r ces_N2457}
29 | ces(BJsales, h=12, holdout=TRUE, silent=FALSE)
30 | ```
31 |
32 | 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()`.
33 |
34 | If we want automatic model selection, then we use `auto.ces()` function:
35 | ```{r auto_ces_N2457}
36 | auto.ces(AirPassengers, h=12, holdout=TRUE, silent=FALSE)
37 | ```
38 |
39 | By default, the function optimises the initial values, but other options ("backcasting" and "complete") are supported as well:
40 | ```{r auto_ces_N2457_optimal}
41 | ces(BJsales, h=12, holdout=TRUE, initial="back")
42 | ```
43 |
44 | The function also works with explanatory variables if the data frame or a matrix is provided instead of the vector of values:
45 | ```{r es_N2457_xreg_create}
46 | BJData <- cbind(y=BJsales, x=BJsales.lead)
47 | cesModel <- ces(BJData, h=12, holdout=TRUE, regressors="use")
48 | ```
49 |
50 | Finally, all the main methods for the [adam](adam.html) function are supported by `ces()` as well. For example, here how we can produce prediction interval:
51 | ```{r}
52 | forecast(cesModel, h=12, interval="pred") |> plot()
53 | ```
54 |
55 |
56 |
--------------------------------------------------------------------------------
/vignettes/es.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "es() - Exponential Smoothing"
3 | author: "Ivan Svetunkov"
4 | date: "`r Sys.Date()`"
5 | output: rmarkdown::html_vignette
6 | vignette: >
7 | %\VignetteIndexEntry{es() - Exponential Smoothing}
8 | %\VignetteEngine{knitr::rmarkdown}
9 | %\VignetteEncoding{UTF-8}
10 | ---
11 |
12 | ```{r global_options, include=FALSE}
13 | knitr::opts_chunk$set(fig.width=6, fig.height=4, fig.path='Figs/', fig.show='hold',
14 | warning=FALSE, message=FALSE)
15 | ```
16 |
17 | `es()` is a part of [smooth package](smooth.html) and is a wrapper for the [ADAM](adam.html) function with `distribution="dnorm"`. It implements Exponential Smoothing in the ETS form, selecting the most appropriate model among 30 possible ones.
18 |
19 | We will use some of the functions of the `greybox` package in this vignette for demonstrational purposes.
20 |
21 | Let's load the necessary packages:
22 | ```{r load_libraries, message=FALSE, warning=FALSE}
23 | require(smooth)
24 | require(greybox)
25 | ```
26 |
27 | The simplest call for the `es()` function is:
28 |
29 | ```{r es_N2457}
30 | ourModel <- es(BJsales, h=12, holdout=TRUE, silent=FALSE)
31 | ourModel
32 | ```
33 |
34 | In this case function uses branch and bound algorithm to form a pool of models to check and after that constructs a model with the lowest information criterion. As we can see, it also produces an output with brief information about the model, which contains:
35 |
36 | 1. How much time was elapsed for the model construction;
37 | 2. What type of ETS was selected;
38 | 3. Values of persistence vector (smoothing parameters);
39 | 4. What type of initialisation was used;
40 | 5. How many parameters were estimated (standard deviation is included);
41 | 6. Cost function type and the value of that cost function;
42 | 7. Information criteria for this model;
43 | 8. Forecast errors (because we have set `holdout=TRUE`).
44 |
45 | The function has also produced a graph with actual values, fitted values and point forecasts.
46 |
47 | If we need prediction interval, then we can use the `forecast()` method:
48 | ```{r es_N2457_with_interval}
49 | plot(forecast(ourModel, h=12, interval="prediction"))
50 | ```
51 |
52 | The same model can be reused for different purposes, for example to produce forecasts based on newly available data:
53 | ```{r es_N2457_reuse_model}
54 | es(BJsales, model=ourModel, h=12, holdout=FALSE)
55 | ```
56 |
57 | We can also extract the type of model in order to reuse it later:
58 | ```{r es_N2457_modelType}
59 | modelType(ourModel)
60 | ```
61 |
62 | This handy function also works with `ets()` from forecast package.
63 |
64 | If we need actual values from the model, we can use `actuals()` method from `greybox` package:
65 | ```{r es_N2457_actuals}
66 | actuals(ourModel)
67 | ```
68 |
69 | We can also use persistence or initials only from the model to construct the other one:
70 | ```{r es_N2457_reuse_model_parts}
71 | # Provided initials
72 | es(BJsales, model=modelType(ourModel),
73 | h=12, holdout=FALSE,
74 | initial=ourModel$initial)
75 | # Provided persistence
76 | es(BJsales, model=modelType(ourModel),
77 | h=12, holdout=FALSE,
78 | persistence=ourModel$persistence)
79 | ```
80 | or provide some arbitrary values:
81 | ```{r es_N2457_set_initial}
82 | es(BJsales, model=modelType(ourModel),
83 | h=12, holdout=FALSE,
84 | initial=200)
85 | ```
86 |
87 | Using some other parameters may lead to completely different model and forecasts (see discussion of the additional parameters in the [online textbook about ADAM](https://openforecast.org/adam/)):
88 | ```{r es_N2457_aMSTFE}
89 | es(BJsales, h=12, holdout=TRUE, loss="MSEh", bounds="a", ic="BIC")
90 | ```
91 |
92 | You can play around with all the available parameters to see what's their effect on the final model.
93 |
94 | In order to combine forecasts we need to use "C" letter:
95 | ```{r es_N2457_combine}
96 | es(BJsales, model="CCN", h=12, holdout=TRUE)
97 | ```
98 |
99 | Model selection from a specified pool and forecasts combination are called using respectively:
100 | ```{r es_N2457_pool}
101 | # Select the best model in the pool
102 | es(BJsales, model=c("ANN","AAN","AAdN","MNN","MAN","MAdN"),
103 | h=12, holdout=TRUE)
104 | # Combine the pool of models
105 | es(BJsales, model=c("CCC","ANN","AAN","AAdN","MNN","MAN","MAdN"),
106 | h=12, holdout=TRUE)
107 | ```
108 |
109 | Now we introduce explanatory variable in ETS:
110 | ```{r es_N2457_xreg_create}
111 | x <- BJsales.lead
112 | ```
113 |
114 | and fit an ETSX model with the exogenous variable first:
115 | ```{r es_N2457_xreg}
116 | es(BJsales, model="ZZZ", h=12, holdout=TRUE,
117 | xreg=x)
118 | ```
119 |
120 | If we want to check if lagged x can be used for forecasting purposes, we can use `xregExpander()` function from `greybox` package:
121 | ```{r es_N2457_xreg_expanded_select}
122 | es(BJsales, model="ZZZ", h=12, holdout=TRUE,
123 | xreg=xregExpander(x), regressors="use")
124 | ```
125 |
126 | We can also construct a model with selected exogenous (based on IC):
127 | ```{r es_N2457_xreg_select}
128 | es(BJsales, model="ZZZ", h=12, holdout=TRUE,
129 | xreg=xregExpander(x), regressors="select")
130 | ```
131 |
132 | Finally, if you work with M or M3 data, and need to test a function on a specific time series, you can use the following simplified call:
133 | ```{r es_N2457_M3, eval=FALSE}
134 | es(Mcomp::M3$N2457, silent=FALSE)
135 | ```
136 |
137 | This command has taken the data, split it into in-sample and holdout and produced the forecast of appropriate length to the holdout.
138 |
--------------------------------------------------------------------------------
/vignettes/gum.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "gum() - Generalised Univariate Model"
3 | author: "Ivan Svetunkov"
4 | date: "`r Sys.Date()`"
5 | output: rmarkdown::html_vignette
6 | vignette: >
7 | %\VignetteIndexEntry{gum() - Generalised Univariate Model}
8 | %\VignetteEngine{knitr::rmarkdown}
9 | %\VignetteEncoding{UTF-8}
10 | ---
11 |
12 | ```{r global_options, include=FALSE}
13 | knitr::opts_chunk$set(fig.width=6, fig.height=4, fig.path='Figs/', fig.show='hold',
14 | warning=FALSE, message=FALSE)
15 | ```
16 |
17 | `gum()` constructs Generalised Exponential Smoothing - pure additive state-space model. It is a part of [smooth package](smooth.html).
18 |
19 | Let's load the necessary packages:
20 | ```{r load_libraries, message=FALSE, warning=FALSE}
21 | require(smooth)
22 | ```
23 |
24 | Generalised Exponential Smoothing is a next step from CES. It is a state-space model in which all the matrices and vectors are estimated. It is very demanding in sample size, but is also insanely flexible.
25 |
26 | A simple call by default constructs GUM$(1^1,1^m)$, where $m$ is frequency of the data. So for our example with `AirPassengers` data, we will have GUM$(1^1,1^{12})$:
27 |
28 | ```{r gum_N2457}
29 | gum(AirPassengers, h=18, holdout=TRUE)
30 | ```
31 |
32 | But some different orders and lags can be specified. For example:
33 | ```{r gum_N2457_2[1]_1[12]}
34 | gum(AirPassengers, h=18, holdout=TRUE, orders=c(2,1), lags=c(1,12))
35 | ```
36 |
37 | Function `auto.gum()` is now implemented in `smooth`, but it works slowly as it needs to check a large number of models:
38 | ```{r Autogum_N2457_1[1]}
39 | auto.gum(AirPassengers, silent=FALSE)
40 | ```
41 |
42 | In addition to standard values that other functions accept, GUM accepts predefined values for transition matrix, measurement and persistence vectors. For example, something more common can be passed to the function:
43 | ```{r gum_N2457_predefined}
44 | transition <- matrix(c(1,0,0,1,1,0,0,0,1),3,3)
45 | measurement <- c(1,1,1)
46 | gum(AirPassengers, h=18, holdout=TRUE, orders=c(2,1), lags=c(1,12), transition=transition, measurement=measurement)
47 | ```
48 |
49 | The resulting model will be equivalent to ETS(A,A,A). However due to different initialisation of optimisers and different method of number of parameters calculation, `gum()` above and `es(y, "AAA", h=h, holdout=TRUE)` will lead to different models.
50 |
--------------------------------------------------------------------------------
/vignettes/library.bib:
--------------------------------------------------------------------------------
1 | @book{Lutkepohl2005,
2 | author = {L{\"{u}}tkepohl, Helmut},
3 | booktitle = {New introduction to Multiple Time Series Analysis},
4 | doi = {10.1007/978-3-540-27752-1},
5 | pages = {1--764},
6 | publisher = {Springer Berlin Heidelberg},
7 | title = {{New Introduction to Multiple Time Series Analysis}},
8 | year = {2005}
9 | }
10 |
11 | @article{Bedrick1994,
12 | author = {Bedrick, Edward J and Tsai, Chih-Ling},
13 | doi = {10.2307/2533213},
14 | journal = {Biometrics},
15 | month = {mar},
16 | number = {1},
17 | pages = {226},
18 | title = {{Model Selection for Multivariate Regression in Small Samples}},
19 | volume = {50},
20 | year = {1994}
21 | }
22 |
23 | @article{Tremblay2004,
24 | author = {Tremblay, Marie and Wallach, Daniel},
25 | doi = {10.1051/agro:2004033},
26 | journal = {Agronomie},
27 | month = {sep},
28 | number = {6-7},
29 | pages = {351--365},
30 | pmid = {647},
31 | title = {{Comparison of parameter estimation methods for crop models}},
32 | volume = {24},
33 | year = {2004}
34 | }
35 |
36 | @article{Silva2010,
37 | author = {de Silva, Ashton and Hyndman, Rob J and Snyder, Ralph},
38 | doi = {10.1177/1471082X0901000401},
39 | journal = {Statistical Modelling: An International Journal},
40 | month = {dec},
41 | number = {4},
42 | pages = {353--374},
43 | title = {{The vector innovations structural time series framework}},
44 | volume = {10},
45 | year = {2010}
46 | }
47 |
48 | @article{Gneiting2007,
49 | author = {Gneiting, Tilmann and Raftery, Adrian E.},
50 | doi = {10.1198/016214506000001437},
51 | journal = {Journal of the American Statistical Association},
52 | number = {477},
53 | pages = {359--378},
54 | title = {{Strictly proper scoring rules, prediction, and estimation}},
55 | volume = {102},
56 | year = {2007}
57 | }
58 |
59 | @unpublished{Svetunkov2017a,
60 | author = {Svetunkov, I. and Boylan, John E.},
61 | doi = {10.13140/RG.2.2.35897.06242},
62 | institution = {Department of Management Science, Lancaster University},
63 | number = {4},
64 | pages = {1--43},
65 | title = {{Multiplicative State-Space Models for Intermittent Time Series}},
66 | year = {2017}
67 | }
68 |
69 | @article{Svetunkov2019,
70 | author = {Svetunkov, Ivan and Boylan, John E.},
71 | doi = {10.1080/00207543.2019.1600764},
72 | issn = {0020-7543},
73 | journal = {International Journal of Production Research},
74 | number = {0},
75 | pages = {1--10},
76 | publisher = {Taylor {\&} Francis},
77 | title = {{State-space ARIMA for supply-chain forecasting}},
78 | volume = {0},
79 | year = {2019}
80 | }
81 |
82 | @book{Hyndman2008b,
83 | author = {Hyndman, Rob J and Koehler, Anne B and Ord, J Keith and Snyder, Ralph D},
84 | publisher = {Springer Berlin Heidelberg},
85 | title = {{Forecasting with Exponential Smoothing}},
86 | year = {2008}
87 | }
88 |
--------------------------------------------------------------------------------
/vignettes/sma.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "sma() - Simple Moving Average"
3 | author: "Ivan Svetunkov"
4 | date: "`r Sys.Date()`"
5 | output: rmarkdown::html_vignette
6 | vignette: >
7 | %\VignetteIndexEntry{sma() - Simple Moving Average}
8 | %\VignetteEngine{knitr::rmarkdown}
9 | %\VignetteEncoding{UTF-8}
10 | ---
11 |
12 | ```{r global_options, include=FALSE}
13 | knitr::opts_chunk$set(fig.width=6, fig.height=4, fig.path='Figs/', fig.show='hold',
14 | warning=FALSE, message=FALSE)
15 | ```
16 |
17 | Simple Moving Average is a method of time series smoothing and is actually a very basic forecasting technique. It does not need estimation of parameters, but rather is based on order selection. It is a part of [smooth package](smooth.html).
18 |
19 | Let's load the necessary packages:
20 | ```{r load_libraries, message=FALSE, warning=FALSE}
21 | require(smooth)
22 | ```
23 |
24 | By default SMA does order selection based on AICc and returns the model with the lowest value:
25 | ```{r sma_N2457}
26 | y <- structure(c(2158.1, 1086.4, 1154.7, 1125.6, 920, 2188.6, 829.2,
27 | 1353.1, 947.2, 1816.8, 1624.5, 868.5, 1783.3, 1713.1, 3479.7,
28 | 2429.4, 3074.3, 3427.4, 2783.7, 1968.7, 2045.6, 1471.3, 2763.7,
29 | 2328.4, 1821, 2409.8, 3485.8, 3289.2, 3048.3, 2914.1, 2173.9,
30 | 3018.4, 2200.1, 6844.3, 4160.4, 1548.8, 3238.9, 3252.2, 3278.8,
31 | 1766.8, 3572.8, 3467.6, 7464.7, 2748.4, 5126.7, 2870.8, 2170.2,
32 | 4326.8, 3220.7, 3586, 3249.5, 3222.5, 2488.5, 3332.4, 2036.1,
33 | 1968.2, 2967.2, 3151.6, 1610.5, 3985, 3894.1, 4625.5, 3291.7,
34 | 3065.6, 2316.5, 2453.4, 4582.8, 2291.2, 3555.5, 1785, 2020, 2026.8,
35 | 2102.9, 2307.7, 6242.1, 6170.5, 1863.5, 6318.9, 3992.8, 3435.1,
36 | 1585.8, 2106.8, 1892.1, 4310.6, 6168, 7247.4, 3579.7, 6365.2,
37 | 4658.9, 6911.8, 2143.7, 5973.9, 4017.2, 4473, 3591.9, 4676.5,
38 | 8749.1, 11931.2, 8572.3, 8257.7, 11930.5, 15757.6, 5920.5, 3064.3,
39 | 5472, 8634.7, 5032, 6236, 6356, 9857.8, 6322.2, 7907, 13842.4,
40 | 13665.1, 3272), .Tsp = c(1983, 1992.5, 12), class = "ts")
41 | sma(y, h=18, silent=FALSE)
42 | ```
43 |
44 | It appears that SMA(13) is the optimal model for this time series, which is not obvious. Note also that the forecast trajectory of SMA(13) is not just a straight line. This is because the actual values are used in construction of point forecasts up to h=13.
45 |
46 |
--------------------------------------------------------------------------------
/vignettes/smooth-Documentation.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/config-i1/smooth/c529c51c1aa221fd49117f17e68064b57d2ae9ff/vignettes/smooth-Documentation.pdf
--------------------------------------------------------------------------------
/vignettes/ssarima.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "ssarima() - State-Space ARIMA"
3 | author: "Ivan Svetunkov"
4 | date: "`r Sys.Date()`"
5 | output: rmarkdown::html_vignette
6 | vignette: >
7 | %\VignetteIndexEntry{ssarima() - State-Space ARIMA}
8 | %\VignetteEngine{knitr::rmarkdown}
9 | %\VignetteEncoding{UTF-8}
10 | bibliography: library.bib
11 | ---
12 |
13 | ```{r global_options, include=FALSE}
14 | knitr::opts_chunk$set(fig.width=6, fig.height=4, fig.path='Figs/', fig.show='hold',
15 | warning=FALSE, message=FALSE)
16 | ```
17 |
18 | SSARIMA stands for "State-space ARIMA" or "Several Seasonalities ARIMA". Both names show what happens in the heart of the function: it constructs ARIMA in a state-space form and allows to model several (actually more than several) seasonalities. `ssarima()` is a function included in [smooth package](smooth.html). This vignette covers `ssarima()` and `auto.ssarima()` functions. For more details about the underlying model, read [@Svetunkov2019].
19 |
20 | As usual, we will use data from `Mcomp` package, so it is advised to install it.
21 |
22 | Let's load the necessary packages:
23 |
24 | ```{r load_libraries, message=FALSE, warning=FALSE}
25 | require(smooth)
26 | ```
27 |
28 | The default call constructs ARIMA(0,1,1):
29 |
30 | ```{r ssarima_N2457}
31 | ssarima(AirPassengers, h=12, silent=FALSE)
32 | ```
33 |
34 | Some more complicated model can be defined using parameter `orders` the following way:
35 | ```{r ssarima_N2457_orders}
36 | ssarima(AirPassengers, orders=list(ar=c(0,1),i=c(1,0),ma=c(1,1)), lags=c(1,12), h=12)
37 | ```
38 |
39 | This would construct seasonal ARIMA(0,1,1)(1,0,1)$_{12}$.
40 |
41 | We could try selecting orders manually, but this can also be done automatically via `auto.ssarima()` function:
42 | ```{r auto_ssarima_N2457}
43 | auto.ssarima(AirPassengers, h=12)
44 | ```
45 |
46 | Automatic order selection in SSARIMA with optimised initials does not work well and in general is not recommended. This is partially because of the possible high number of parameters in some models and partially because of potential overfitting of first observations when non-zero order of AR is selected:
47 | ```{r auto_ssarima_N1683}
48 | auto.ssarima(AirPassengers, h=12, initial="backcasting")
49 | auto.ssarima(AirPassengers, h=12, initial="optimal")
50 | ```
51 |
52 | As can be seen from the example above the model with optimal initials takes more time and we end up with a different model than in the case of backcasting.
53 |
54 | A power of `ssarima()` function is that it can estimate SARIMA models with multiple seasonalities. For example, SARIMA(0,1,1)(0,0,1)_6(1,0,1)_12 model can be estimated the following way:
55 | ```{r ssarima_N2457_orders_multiple_seasonalities, eval=FALSE}
56 | ssarima(AirPassengers, orders=list(ar=c(0,0,1),i=c(1,0,0),ma=c(1,1,1)), lags=c(1,6,12), h=12, silent=FALSE)
57 | ```
58 | It probably does not make much sense for this type of data, it would make more sense on high frequency data (for example, `taylor` series from `forecast` package). However, keep in mind that multiple seasonal ARIMAs are very slow in estimation and are very capricious. So it is really hard to obtain an appropriate and efficient multiple seasonal ARIMA model. To tackle this issue, I've developed an alternative ARIMA model for multiple seasonalities, called `msarima()`.
59 |
60 | Now let's introduce some artificial exogenous variables:
61 | ```{r es_N2457_xreg_create}
62 | x <- cbind(rnorm(length(AirPassengers),50,3),rnorm(length(AirPassengers),100,7))
63 | ```
64 |
65 | If we save model:
66 | ```{r auto_ssarima_N2457_xreg}
67 | ourModel <- auto.ssarima(AirPassengers, h=12, holdout=TRUE, xreg=x)
68 | ```
69 |
70 | we can then reuse it:
71 | ```{r auto_ssarima_N2457_xreg_update}
72 | ssarima(AirPassengers, model=ourModel, h=12, holdout=FALSE, xreg=x, interval=TRUE)
73 | ```
74 |
75 | Finally, we can combine several SARIMA models:
76 | ```{r auto_ssarima_N2457_combination}
77 | ssarima(AirPassengers, h=12, holdout=FALSE, interval=TRUE, combine=TRUE)
78 | ```
79 |
80 | # MSARIMA
81 | While SSARIMA is flexible, it is not fast. In fact, it cannot handle high frequency data well and most probably will take ages to estimate the parameter and produce forecasts. This is because of the transition matrix, which becomes huge in case of multiple seasonalities. The MSARIMA model (Multiple Seasonal ARIMA) is formulated in a different state-space form, which reduces the size of transition matrix, significantly reducing the computational time for cases with high frequency data.
82 |
83 | There are `auto.msarima()` and `msarima()` function in the package, that do things similar to `auto.ssarima()` and `ssarima()`. Here's just one example of what can be done with it:
84 | ```{r mssarima_N2457_orders_multiple_seasonalities}
85 | msarima(AirPassengers, orders=list(ar=c(0,0,1),i=c(1,0,0),ma=c(1,1,1)),lags=c(1,6,12),h=12, silent=FALSE)
86 | ```
87 |
88 | The forecasts of the two models might differ due to the different state space form. The detailed explanation of MSARIMA is given in Chapter 9 of [ADAM textbook](https://openforecast.org/adam/).
89 |
90 | ## References
91 |
--------------------------------------------------------------------------------