ctsa
Version:
Univariate ARIMA model
169 lines (158 loc) • 4.45 kB
JavaScript
const ctsa = require('./ctsa.js')
const seq = n => Array(n).fill(null)
const _arima = ctsa.cwrap('calc_arima', 'number', [
'array',
'number', 'number', 'number',
'number', 'number', 'number', 'number', 'boolean'])
const _sarima = ctsa.cwrap('calc_sarima', 'number', [
'array',
'number', 'number', 'number',
'number', 'number', 'number', 'number',
'number', 'number', 'number', 'number', 'boolean'])
const _acf = ctsa.cwrap('calc_acf', 'number', [
'array',
'number', 'number', 'number'])
const _pacf = ctsa.cwrap('calc_pacf', 'number', [
'array',
'number', 'number', 'number'])
const writedoublearray = arr => {
const farr = arr.flat()
for (let i = 0; i < farr.length - 2; i++)
if (isNaN(farr[i + 1]))
farr[i + 1] = farr[i]
return new Uint8Array(Float64Array.from(farr).buffer)
}
const readdoublearray = (addr, length) => {
const res = [[], []]
for (let i = 0; i < length * 2; i++)
res[i < length ? 0 : 1].push(ctsa.HEAPF64[addr / Float64Array.BYTES_PER_ELEMENT + i])
return res
}
const readarray = (addr, length) => {
const res = []
for (let i = 0; i < length * 2; i++)
res.push(ctsa.HEAPF64[addr / Float64Array.BYTES_PER_ELEMENT + i])
return res
}
// method = 0 - Exact Maximum Likelihood Method (Default)
// method = 1 - Conditional Method - Sum Of Squares
// method = 2 - Box-Jenkins Method
// optimizer = 0 - Nelder-Mead
// optimizer = 1 - Newton Line Search
// optimizer = 2 - Newton Trust Region - Hook Step
// optimizer = 3 - Newton Trust Region - Double Dog-Leg
// optimizer = 4 - Conjugate Gradient
// optimizer = 5 - BFGS
// optimizer = 6 - Limited Memory BFGS
// optimizer = 7 - BFGS Using More Thuente Method (Default)
const arima_defaults = {
method: 0,
optimizer: 6,
p: 1,
d: 0,
q: 1,
verbose: true
}
// method = 0 - Exact Maximum Likelihood Method (Default)
// method = 1 - Conditional Method - Sum Of Squares
// method = 2 - Box-Jenkins Method
// optimizer = 0 - Nelder-Mead
// optimizer = 1 - Newton Line Search
// optimizer = 2 - Newton Trust Region - Hook Step
// optimizer = 3 - Newton Trust Region - Double Dog-Leg
// optimizer = 4 - Conjugate Gradient
// optimizer = 5 - BFGS
// optimizer = 6 - Limited Memory BFGS
// optimizer = 7 - BFGS Using More Thuente Method (Default)
const sarima_defaults = {
method: 0,
optimizer: 7,
p: 0,
d: 1,
q: 1,
s: 12,
P: 0,
D: 1,
Q: 1,
verbose: true
}
// method = 0 - Default Method
// method = 1 - FFT Based method.
const acf_defaults = {
method: 0
}
// method = 0 - Yule-Walker
// method = 1 - Burg
// method = 2 - Conditional MLE (Box-Jenkins)
const pacf_defaults = {
method: 0
}
module.exports = {
arima(input, length, opts) {
const options = Object.assign({}, arima_defaults, opts)
const ts = writedoublearray(input)
const addr = _arima(
ts,
options.p,
options.d,
options.q,
input.length,
length,
options.method,
options.optimizer,
options.verbose
)
return readdoublearray(addr, length)
},
sarima(input, length, opts) {
const options = Object.assign({}, sarima_defaults, opts)
const ts = writedoublearray(input)
const addr = _sarima(
ts,
options.p,
options.d,
options.q,
options.s,
options.P,
options.D,
options.Q,
input.length,
length,
options.method,
options.optimizer,
options.verbose
)
return readdoublearray(addr, length)
},
acf(input, length, opts) {
const options = Object.assign({}, acf_defaults, opts)
const ts = writedoublearray(input)
const addr = _acf(
ts,
input.length,
length,
options.method
)
return readarray(addr, length)
},
pacf(input, length, opts) {
const options = Object.assign({}, pacf_defaults, opts)
const ts = writedoublearray(input)
const addr = _pacf(
ts,
input.length,
length,
options.method
)
return readarray(addr, length)
},
// https://www.rdocumentation.org/packages/base/versions/3.6.2/topics/diff
// https://github.com/wch/r-source/blob/5a156a0865362bb8381dcd69ac335f5174a4f60c/src/library/base/R/diff.R
diff(ts, lag = 1, differences = 1) {
if (lag < 1 || differences < 1) return ts
if (lag * differences >= ts.length) return []
return seq(differences).reduce(result =>
seq(result.length - lag).map((d, i) => result[i + lag] - result[i]),
ts)
}
}