package ru.ulstu.tsMethods.exponential; import ru.ulstu.models.TimeSeries; import ru.ulstu.models.exceptions.ModelingException; import ru.ulstu.models.exceptions.TimeSeriesValidateException; import ru.ulstu.tsMethods.TimeSeriesMethod; import ru.ulstu.tsMethods.exponential.param.*; import java.util.ArrayList; import java.util.List; public class AddTrendAddSeason extends TimeSeriesMethod { private final TimeSeriesMethodParamValue alpha; private final TimeSeriesMethodParamValue beta; private final TimeSeriesMethodParamValue gamma; private final TimeSeriesMethodParamValue season; private final List sComponent = new ArrayList<>(); private final List tComponent = new ArrayList<>(); private final List iComponent = new ArrayList<>(); public AddTrendAddSeason(TimeSeries timeSeries, TimeSeriesMethodParamValue alpha, TimeSeriesMethodParamValue beta, TimeSeriesMethodParamValue gamma, TimeSeriesMethodParamValue season) throws ModelingException { super(timeSeries); this.alpha = alpha; this.beta = beta; this.gamma = gamma; this.season = season; } @Override protected TimeSeries getModelOfValidTimeSeries() throws ModelingException { sComponent.clear(); tComponent.clear(); iComponent.clear(); iComponent.add(1.0); sComponent.add(originalTimeSeries.getFirstValue().getValue()); tComponent.add(0.0); TimeSeries model = new TimeSeries("Model of " + originalTimeSeries.getName()); model.addValue(originalTimeSeries.getFirstValue()); //выполняется проход модели по сглаживанию for (int t = 1; t < season.getValue().intValue(); t++) { sComponent.add(alpha.getDoubleValue() * originalTimeSeries.getNumericValue(t) + (1 - alpha.getDoubleValue()) * (sComponent.get(t - 1) + tComponent.get(t - 1))); tComponent.add(beta.getDoubleValue() * (sComponent.get(t) - sComponent.get(t - 1)) + (1 - beta.getDoubleValue()) * tComponent.get(t - 1)); iComponent.add(gamma.getDoubleValue() * originalTimeSeries.getNumericValue(t) / sComponent.get(sComponent.size() - 1) + (1 - gamma.getDoubleValue()) * iComponent.get(0)); model.addValue(originalTimeSeries.getValues().get(t), sComponent.get(sComponent.size() - 1)); } for (int t = season.getIntValue(); t < originalTimeSeries.getValues().size(); t++) { sComponent.add(alpha.getDoubleValue() * originalTimeSeries.getNumericValue(t) / iComponent.get(t - season.getIntValue()) + (1 - alpha.getDoubleValue()) * (sComponent.get(t - 1) + tComponent.get(t - 1))); tComponent.add(beta.getDoubleValue() * (sComponent.get(t) - sComponent.get(t - 1)) + (1 - beta.getDoubleValue()) * tComponent.get(t - 1)); iComponent.add(gamma.getDoubleValue() * originalTimeSeries.getNumericValue(t) / sComponent.get(sComponent.size() - 1) + (1 - gamma.getDoubleValue()) * iComponent.get(t - season.getIntValue())); model.addValue(originalTimeSeries.getValues().get(t), sComponent.get(sComponent.size() - 1)); } return model; } @Override protected void validateAdditionalParams() throws ModelingException { if (originalTimeSeries.getLength() < season.getIntValue()) { throw new TimeSeriesValidateException("Период больше чем длина ряда"); } } @Override protected TimeSeries makeForecast(TimeSeries forecast) throws ModelingException { for (int t = 1; t < forecast.getLength(); t++) { iComponent.add(gamma.getDoubleValue() * forecast.getNumericValue(t - 1) / sComponent.get(sComponent.size() - 1) + (1 - gamma.getDoubleValue()) * iComponent.get(t + getModel().getLength() - season.getIntValue())); forecast.getValues().get(t).setValue((sComponent.get(sComponent.size() - 1) + tComponent.get(tComponent.size() - 1) * t) * iComponent.get(t + getModel().getLength() - season.getIntValue())); } return forecast; } }