Created
June 10, 2019 06:23
-
-
Save nsdevaraj/990c1acc76a024f8515ea249494676bf to your computer and use it in GitHub Desktop.
arima pending
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function assertNotEmpty(list) { | |
if (list.length === 0) | |
throw new Error("List length is zero"); | |
} | |
function simple_exponential_smoothing(series, alpha) { | |
assertNotEmpty(series); | |
var prev = 0.0; | |
var ses_series = []; | |
for (var i = 0; i < series.length; i++) { | |
if (i === 0) { | |
ses_series.push(series[i]); | |
} else { | |
ses_series.push(alpha * series[i] + (1.0 - alpha) * prev); | |
} | |
prev = ses_series[i]; | |
} | |
return ses_series; | |
} | |
/** | |
* Calculates the simple moving average with (2*range + 1) points | |
* @param {Array.<Number>} series | |
* @param {Number} order | |
* @return {Array.<Number>} moving average series | |
*/ | |
function simple_moving_average(series, range) { | |
assertNotEmpty(series); | |
var slen = series.length; | |
var window = 2 * range + 1; | |
var sma_series = []; | |
for (var i = 0; i < (slen - window) + 1; i++) { | |
var average = 0; | |
for (var j = i; j < i + window; j++) { | |
average = average + series[j]; | |
} | |
sma_series.push(average / window); | |
} | |
return sma_series; | |
} | |
function computeMeanSquaredError(series, sma_series) { | |
var SSE = 0.0; | |
var n = 0; | |
for (var i = 0; i < series.length; ++i) { | |
if (series[i] != null && sma_series[i] != null) { | |
SSE += Math.pow(series[i] - sma_series[i], 2); | |
n++; | |
} | |
} | |
return 1 / (n - 1) * SSE; | |
}; | |
function simple_moving_average_optimizeParameter(iter, series, sma_series) { | |
var incr = 1 / iter; | |
var bestAlpha = 0.0; | |
var bestError = -1; | |
var alpha = bestAlpha; | |
while (alpha < 1) { | |
var forecast = sma_series; | |
var error = computeMeanSquaredError(series, forecast); | |
if (error < bestError || bestError == -1) { | |
bestAlpha = alpha; | |
bestError = error; | |
} | |
alpha += incr; | |
} | |
alpha = bestAlpha; | |
return alpha; | |
} | |
function holtSmoothing(horizon, alpha, gamma, data) { | |
var A = []; | |
var B = []; | |
A[0] = 0; | |
B[0] = data[0]; | |
for (var i = 1; i < data.length; ++i) { | |
B[i] = alpha * data[i] + (1 - alpha) * (B[i - 1] + A[i - 1]); | |
A[i] = gamma * (B[i] - B[i - 1]) + (1 - gamma) * A[i - 1]; | |
} | |
var forecast = []; | |
forecast[0] = null; | |
for (var i = 1; i <= data.length; ++i) { | |
forecast[i] = A[i - 1] + B[i - 1]; | |
} | |
for (var i = data.length + 1; i < data.length + horizon; ++i) { | |
forecast[i] = forecast[i - 1] + A[data.length - 1]; | |
} | |
return forecast; | |
} | |
function HoltWintersSmoothingAdd(alpha, gamma, delta, seasonLength, data) { | |
var A = []; | |
var B = []; | |
var S = []; | |
A[seasonLength - 1] = 0; | |
var averageFirstSeason = 0; | |
for (var i = 0; i < seasonLength; ++i) { | |
averageFirstSeason += data[i]; | |
} | |
B[seasonLength - 1] = averageFirstSeason / seasonLength; | |
for (var i = 0; i < seasonLength; ++i) { | |
S[i] = data[i] - averageFirstSeason / seasonLength; | |
} | |
for (var i = seasonLength; i < data.length; ++i) { | |
B[i] = alpha * (data[i] - S[i - seasonLength]) + (1 - alpha) * (B[i - 1] + A[i - 1]); | |
A[i] = gamma * (B[i] - B[i - 1]) + (1 - gamma) * A[i - 1]; | |
S[i] = delta * (data[i] - B[i]) + (1 - delta) * S[i - seasonLength]; | |
} | |
var forecast = Array(); | |
for (var i = 0; i < seasonLength; ++i) { | |
forecast[i] = null; | |
} | |
for (var i = seasonLength; i < data.length; ++i) { | |
forecast[i] = A[i - 1] + B[i - 1] + S[i - seasonLength]; | |
} | |
for (var i = data.length; i < data.length + seasonLength; ++i) { | |
forecast[i] = B[data.length - 1] + (i - data.length + 1) * A[data.length - 1] + S[i - seasonLength]; | |
} | |
return forecast; | |
} | |
function HoltWintersSmoothingMult(alpha, gamma, delta, seasonLength, data) { | |
var A = []; | |
var B = []; | |
var S = []; | |
A[seasonLength - 1] = 0; | |
var averageFirstSeason = 0; | |
for (var i = 0; i < seasonLength; ++i) { | |
averageFirstSeason += data[i]; | |
} | |
B[seasonLength - 1] = averageFirstSeason / seasonLength; | |
for (var i = 0; i < seasonLength; ++i) { | |
S[i] = (data[i]) / (averageFirstSeason / seasonLength); | |
} | |
for (var i = seasonLength; i < data.length; ++i) { | |
B[i] = alpha * (data[i] / S[i - seasonLength]) + (1 - alpha) * (B[i - 1] + A[i - 1]); | |
A[i] = gamma * (B[i] - B[i - 1]) + (1 - gamma) * A[i - 1]; | |
S[i] = delta * (data[i] / B[i]) + (1 - delta) * S[i - seasonLength]; | |
} | |
var forecast = Array(); | |
for (var i = 0; i < seasonLength; ++i) { | |
forecast[i] = null; | |
} | |
for (var i = seasonLength; i < data.length; ++i) { | |
forecast[i] = (A[i - 1] + B[i - 1]) * S[i - seasonLength]; | |
} | |
for (var i = data.length; i < data.length + seasonLength; ++i) { | |
forecast[i] = (B[data.length - 1] + (i - data.length + 1) * A[data.length - 1]) * S[i - seasonLength]; | |
} | |
return forecast; | |
} | |
/** | |
* Low pass filter: dampen high frequencies | |
* @param {Array.<Number>} series | |
* @return {Array.<Number>} low pass series | |
*/ | |
function low_pass(series) { | |
return simple_moving_average(series, 3); | |
} | |
/** | |
* High pass filter: dampen low frequencies | |
* @param {Array.<Number>} series | |
* @return {Array.<Number>} high pass series | |
*/ | |
function high_pass(series) { | |
var low = low_pass(series); | |
var high = []; | |
for (var i = 0; i < low.length; i++) { | |
high.push(series[i] - low[i]); | |
} | |
return high; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment