92 lines
4.4 KiB
Java

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> alpha;
private final TimeSeriesMethodParamValue<Beta> beta;
private final TimeSeriesMethodParamValue<Gamma> gamma;
private final TimeSeriesMethodParamValue<Season> season;
private final List<Double> sComponent = new ArrayList<>();
private final List<Double> tComponent = new ArrayList<>();
private final List<Double> iComponent = new ArrayList<>();
public AddTrendAddSeason(TimeSeries timeSeries,
TimeSeriesMethodParamValue<Alpha> alpha,
TimeSeriesMethodParamValue<Beta> beta,
TimeSeriesMethodParamValue<Gamma> gamma,
TimeSeriesMethodParamValue<Season> 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;
}
}