diff --git a/src/main/java/ru/ulstu/TimeSeriesUtils.java b/src/main/java/ru/ulstu/TimeSeriesUtils.java index 901179c..b375b30 100644 --- a/src/main/java/ru/ulstu/TimeSeriesUtils.java +++ b/src/main/java/ru/ulstu/TimeSeriesUtils.java @@ -1,6 +1,12 @@ +/* + * Copyright (C) 2021 Anton Romanov - All Rights Reserved + * You may use, distribute and modify this code, please write to: romanov73@gmail.com. + * + */ + package ru.ulstu; -import ru.ulstu.models.TimeSeries; +import ru.ulstu.datamodel.ts.TimeSeries; import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; diff --git a/src/main/java/ru/ulstu/controllers/AdviceController.java b/src/main/java/ru/ulstu/controller/AdviceController.java similarity index 65% rename from src/main/java/ru/ulstu/controllers/AdviceController.java rename to src/main/java/ru/ulstu/controller/AdviceController.java index de504d1..2597320 100644 --- a/src/main/java/ru/ulstu/controllers/AdviceController.java +++ b/src/main/java/ru/ulstu/controller/AdviceController.java @@ -1,19 +1,10 @@ /* - * Copyright (c) 2020. Anton Romanov - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Copyright (C) 2021 Anton Romanov - All Rights Reserved + * You may use, distribute and modify this code, please write to: romanov73@gmail.com. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. */ -package ru.ulstu.controllers; +package ru.ulstu.controller; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -21,10 +12,10 @@ import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.HttpServerErrorException; -import ru.ulstu.models.exceptions.ForecastValidateException; -import ru.ulstu.models.exceptions.TimeSeriesValidateException; -import ru.ulstu.models.response.ErrorConstants; -import ru.ulstu.models.response.ResponseExtended; +import ru.ulstu.datamodel.exception.ForecastValidateException; +import ru.ulstu.datamodel.exception.TimeSeriesValidateException; +import ru.ulstu.datamodel.response.ErrorConstants; +import ru.ulstu.datamodel.response.ResponseExtended; @RestController @ControllerAdvice diff --git a/src/main/java/ru/ulstu/controllers/TimeSeriesController.java b/src/main/java/ru/ulstu/controller/TimeSeriesController.java similarity index 79% rename from src/main/java/ru/ulstu/controllers/TimeSeriesController.java rename to src/main/java/ru/ulstu/controller/TimeSeriesController.java index a8defd5..154e5d2 100644 --- a/src/main/java/ru/ulstu/controllers/TimeSeriesController.java +++ b/src/main/java/ru/ulstu/controller/TimeSeriesController.java @@ -1,12 +1,10 @@ /* - * - * * Copyright (C) 2021 Anton Romanov - All Rights Reserved - * * You may use, distribute and modify this code, please write to: romanov73@gmail.com. - * + * Copyright (C) 2021 Anton Romanov - All Rights Reserved + * You may use, distribute and modify this code, please write to: romanov73@gmail.com. * */ -package ru.ulstu.controllers; +package ru.ulstu.controller; import io.swagger.annotations.ApiOperation; import org.springframework.http.HttpStatus; @@ -16,12 +14,12 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import ru.ulstu.configuration.ApiConfiguration; -import ru.ulstu.models.ForecastParams; -import ru.ulstu.models.ModelingResult; -import ru.ulstu.models.TimeSeries; -import ru.ulstu.models.exceptions.ModelingException; -import ru.ulstu.services.MethodParamBruteForce; -import ru.ulstu.services.TimeSeriesService; +import ru.ulstu.datamodel.ForecastParams; +import ru.ulstu.datamodel.ModelingResult; +import ru.ulstu.datamodel.exception.ModelingException; +import ru.ulstu.datamodel.ts.TimeSeries; +import ru.ulstu.service.MethodParamBruteForce; +import ru.ulstu.service.TimeSeriesService; @RestController @RequestMapping(ApiConfiguration.API_1_0) diff --git a/src/main/java/ru/ulstu/controllers/UtilController.java b/src/main/java/ru/ulstu/controller/UtilController.java similarity index 88% rename from src/main/java/ru/ulstu/controllers/UtilController.java rename to src/main/java/ru/ulstu/controller/UtilController.java index 3be9f09..01a8831 100644 --- a/src/main/java/ru/ulstu/controllers/UtilController.java +++ b/src/main/java/ru/ulstu/controller/UtilController.java @@ -1,4 +1,10 @@ -package ru.ulstu.controllers; +/* + * Copyright (C) 2021 Anton Romanov - All Rights Reserved + * You may use, distribute and modify this code, please write to: romanov73@gmail.com. + * + */ + +package ru.ulstu.controller; import io.swagger.annotations.ApiOperation; import org.springframework.http.HttpStatus; @@ -10,8 +16,8 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import ru.ulstu.configuration.ApiConfiguration; -import ru.ulstu.models.TimeSeries; -import ru.ulstu.services.UtilService; +import ru.ulstu.datamodel.ts.TimeSeries; +import ru.ulstu.service.UtilService; @RestController @RequestMapping(ApiConfiguration.API_1_0) diff --git a/src/main/java/ru/ulstu/models/ForecastParams.java b/src/main/java/ru/ulstu/datamodel/ForecastParams.java similarity index 69% rename from src/main/java/ru/ulstu/models/ForecastParams.java rename to src/main/java/ru/ulstu/datamodel/ForecastParams.java index 2375ac6..d042cca 100644 --- a/src/main/java/ru/ulstu/models/ForecastParams.java +++ b/src/main/java/ru/ulstu/datamodel/ForecastParams.java @@ -1,4 +1,12 @@ -package ru.ulstu.models; +/* + * Copyright (C) 2021 Anton Romanov - All Rights Reserved + * You may use, distribute and modify this code, please write to: romanov73@gmail.com. + * + */ + +package ru.ulstu.datamodel; + +import ru.ulstu.datamodel.ts.TimeSeries; public class ForecastParams { private TimeSeries originalTimeSeries; diff --git a/src/main/java/ru/ulstu/datamodel/Model.java b/src/main/java/ru/ulstu/datamodel/Model.java new file mode 100644 index 0000000..7f912fb --- /dev/null +++ b/src/main/java/ru/ulstu/datamodel/Model.java @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2021 Anton Romanov - All Rights Reserved + * You may use, distribute and modify this code, please write to: romanov73@gmail.com. + * + */ + +package ru.ulstu.datamodel; + +import ru.ulstu.datamodel.ts.TimeSeries; + +public abstract class Model { + protected final TimeSeries timeSeriesModel; + + protected Model(TimeSeries ts) { + timeSeriesModel = new TimeSeries("Model of", ts.getName()); + } + + public TimeSeries getTimeSeriesModel() { + return timeSeriesModel; + } +} diff --git a/src/main/java/ru/ulstu/datamodel/ModelingResult.java b/src/main/java/ru/ulstu/datamodel/ModelingResult.java new file mode 100644 index 0000000..79a8940 --- /dev/null +++ b/src/main/java/ru/ulstu/datamodel/ModelingResult.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2021 Anton Romanov - All Rights Reserved + * You may use, distribute and modify this code, please write to: romanov73@gmail.com. + * + */ + +package ru.ulstu.datamodel; + +import ru.ulstu.datamodel.ts.TimeSeries; +import ru.ulstu.method.Method; +import ru.ulstu.method.MethodParamValue; + +import java.util.List; + +public class ModelingResult { + private final TimeSeries timeSeries; + private final List paramValues; + private final Score score; + private final Method method; + + public ModelingResult(TimeSeries timeSeries, + List paramValues, + Score score, + Method method) { + this.timeSeries = timeSeries; + this.paramValues = paramValues; + this.score = score; + this.method = method; + } + + public TimeSeries getTimeSeries() { + return timeSeries; + } + + public List getParamValues() { + return paramValues; + } + + public Score getScore() { + return score; + } + + public Method getTimeSeriesMethod() { + return method; + } +} diff --git a/src/main/java/ru/ulstu/models/Score.java b/src/main/java/ru/ulstu/datamodel/Score.java similarity index 75% rename from src/main/java/ru/ulstu/models/Score.java rename to src/main/java/ru/ulstu/datamodel/Score.java index 2c95769..aedf724 100644 --- a/src/main/java/ru/ulstu/models/Score.java +++ b/src/main/java/ru/ulstu/datamodel/Score.java @@ -1,12 +1,10 @@ /* - * - * * Copyright (C) 2021 Anton Romanov - All Rights Reserved - * * You may use, distribute and modify this code, please write to: romanov73@gmail.com. - * + * Copyright (C) 2021 Anton Romanov - All Rights Reserved + * You may use, distribute and modify this code, please write to: romanov73@gmail.com. * */ -package ru.ulstu.models; +package ru.ulstu.datamodel; import com.fasterxml.jackson.annotation.JsonIgnore; import ru.ulstu.score.ScoreMethod; diff --git a/src/main/java/ru/ulstu/datamodel/exception/ForecastValidateException.java b/src/main/java/ru/ulstu/datamodel/exception/ForecastValidateException.java new file mode 100644 index 0000000..da42fbe --- /dev/null +++ b/src/main/java/ru/ulstu/datamodel/exception/ForecastValidateException.java @@ -0,0 +1,13 @@ +/* + * Copyright (C) 2021 Anton Romanov - All Rights Reserved + * You may use, distribute and modify this code, please write to: romanov73@gmail.com. + * + */ + +package ru.ulstu.datamodel.exception; + +public class ForecastValidateException extends ModelingException { + public ForecastValidateException(String message) { + super(message); + } +} diff --git a/src/main/java/ru/ulstu/datamodel/exception/ModelingException.java b/src/main/java/ru/ulstu/datamodel/exception/ModelingException.java new file mode 100644 index 0000000..f39d0ea --- /dev/null +++ b/src/main/java/ru/ulstu/datamodel/exception/ModelingException.java @@ -0,0 +1,13 @@ +/* + * Copyright (C) 2021 Anton Romanov - All Rights Reserved + * You may use, distribute and modify this code, please write to: romanov73@gmail.com. + * + */ + +package ru.ulstu.datamodel.exception; + +public class ModelingException extends Exception { + public ModelingException(String message) { + super(message); + } +} diff --git a/src/main/java/ru/ulstu/datamodel/exception/TimeSeriesValidateException.java b/src/main/java/ru/ulstu/datamodel/exception/TimeSeriesValidateException.java new file mode 100644 index 0000000..5c09c21 --- /dev/null +++ b/src/main/java/ru/ulstu/datamodel/exception/TimeSeriesValidateException.java @@ -0,0 +1,13 @@ +/* + * Copyright (C) 2021 Anton Romanov - All Rights Reserved + * You may use, distribute and modify this code, please write to: romanov73@gmail.com. + * + */ + +package ru.ulstu.datamodel.exception; + +public class TimeSeriesValidateException extends ModelingException { + public TimeSeriesValidateException(String message) { + super(message); + } +} diff --git a/src/main/java/ru/ulstu/models/response/ControllerResponse.java b/src/main/java/ru/ulstu/datamodel/response/ControllerResponse.java similarity index 70% rename from src/main/java/ru/ulstu/models/response/ControllerResponse.java rename to src/main/java/ru/ulstu/datamodel/response/ControllerResponse.java index fa3d13a..da37d89 100644 --- a/src/main/java/ru/ulstu/models/response/ControllerResponse.java +++ b/src/main/java/ru/ulstu/datamodel/response/ControllerResponse.java @@ -1,4 +1,10 @@ -package ru.ulstu.models.response; +/* + * Copyright (C) 2021 Anton Romanov - All Rights Reserved + * You may use, distribute and modify this code, please write to: romanov73@gmail.com. + * + */ + +package ru.ulstu.datamodel.response; class ControllerResponse { private final D data; diff --git a/src/main/java/ru/ulstu/models/response/ControllerResponseError.java b/src/main/java/ru/ulstu/datamodel/response/ControllerResponseError.java similarity index 70% rename from src/main/java/ru/ulstu/models/response/ControllerResponseError.java rename to src/main/java/ru/ulstu/datamodel/response/ControllerResponseError.java index b4fa31c..742c487 100644 --- a/src/main/java/ru/ulstu/models/response/ControllerResponseError.java +++ b/src/main/java/ru/ulstu/datamodel/response/ControllerResponseError.java @@ -1,4 +1,10 @@ -package ru.ulstu.models.response; +/* + * Copyright (C) 2021 Anton Romanov - All Rights Reserved + * You may use, distribute and modify this code, please write to: romanov73@gmail.com. + * + */ + +package ru.ulstu.datamodel.response; class ControllerResponseError { private final ErrorConstants description; diff --git a/src/main/java/ru/ulstu/models/response/ErrorConstants.java b/src/main/java/ru/ulstu/datamodel/response/ErrorConstants.java similarity index 78% rename from src/main/java/ru/ulstu/models/response/ErrorConstants.java rename to src/main/java/ru/ulstu/datamodel/response/ErrorConstants.java index 44c6bdf..4b58be9 100644 --- a/src/main/java/ru/ulstu/models/response/ErrorConstants.java +++ b/src/main/java/ru/ulstu/datamodel/response/ErrorConstants.java @@ -1,4 +1,10 @@ -package ru.ulstu.models.response; +/* + * Copyright (C) 2021 Anton Romanov - All Rights Reserved + * You may use, distribute and modify this code, please write to: romanov73@gmail.com. + * + */ + +package ru.ulstu.datamodel.response; public enum ErrorConstants { UNKNOWN(0, "Unknown error"), diff --git a/src/main/java/ru/ulstu/models/response/Response.java b/src/main/java/ru/ulstu/datamodel/response/Response.java similarity index 68% rename from src/main/java/ru/ulstu/models/response/Response.java rename to src/main/java/ru/ulstu/datamodel/response/Response.java index fa5ba67..db6d18f 100644 --- a/src/main/java/ru/ulstu/models/response/Response.java +++ b/src/main/java/ru/ulstu/datamodel/response/Response.java @@ -1,4 +1,10 @@ -package ru.ulstu.models.response; +/* + * Copyright (C) 2021 Anton Romanov - All Rights Reserved + * You may use, distribute and modify this code, please write to: romanov73@gmail.com. + * + */ + +package ru.ulstu.datamodel.response; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/src/main/java/ru/ulstu/models/response/ResponseExtended.java b/src/main/java/ru/ulstu/datamodel/response/ResponseExtended.java similarity index 64% rename from src/main/java/ru/ulstu/models/response/ResponseExtended.java rename to src/main/java/ru/ulstu/datamodel/response/ResponseExtended.java index c79be44..f6647c6 100644 --- a/src/main/java/ru/ulstu/models/response/ResponseExtended.java +++ b/src/main/java/ru/ulstu/datamodel/response/ResponseExtended.java @@ -1,4 +1,10 @@ -package ru.ulstu.models.response; +/* + * Copyright (C) 2021 Anton Romanov - All Rights Reserved + * You may use, distribute and modify this code, please write to: romanov73@gmail.com. + * + */ + +package ru.ulstu.datamodel.response; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/src/main/java/ru/ulstu/models/TimeSeries.java b/src/main/java/ru/ulstu/datamodel/ts/TimeSeries.java similarity index 78% rename from src/main/java/ru/ulstu/models/TimeSeries.java rename to src/main/java/ru/ulstu/datamodel/ts/TimeSeries.java index 4659225..1e5ee54 100644 --- a/src/main/java/ru/ulstu/models/TimeSeries.java +++ b/src/main/java/ru/ulstu/datamodel/ts/TimeSeries.java @@ -1,4 +1,10 @@ -package ru.ulstu.models; +/* + * Copyright (C) 2021 Anton Romanov - All Rights Reserved + * You may use, distribute and modify this code, please write to: romanov73@gmail.com. + * + */ + +package ru.ulstu.datamodel.ts; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; @@ -14,6 +20,10 @@ public class TimeSeries { this.name = name; } + public TimeSeries(String prefix, String suffix) { + this.name = String.format("%s %s", prefix, suffix); + } + @JsonCreator public TimeSeries(@JsonProperty(value = "values") List values, @JsonProperty(value = "name") String name) { this.values = values; @@ -78,6 +88,13 @@ public class TimeSeries { throw new RuntimeException("Индекс выходит за границы временного ряда"); } + public TimeSeriesValue getValue(int t) { + if ((values.size() > t) && (t >= 0)) { + return values.get(t); + } + throw new RuntimeException("Индекс выходит за границы временного ряда"); + } + @Override public String toString() { return "TimeSeries{" + diff --git a/src/main/java/ru/ulstu/models/TimeSeriesValue.java b/src/main/java/ru/ulstu/datamodel/ts/TimeSeriesValue.java similarity index 88% rename from src/main/java/ru/ulstu/models/TimeSeriesValue.java rename to src/main/java/ru/ulstu/datamodel/ts/TimeSeriesValue.java index 838a925..fef77f9 100644 --- a/src/main/java/ru/ulstu/models/TimeSeriesValue.java +++ b/src/main/java/ru/ulstu/datamodel/ts/TimeSeriesValue.java @@ -1,4 +1,10 @@ -package ru.ulstu.models; +/* + * Copyright (C) 2021 Anton Romanov - All Rights Reserved + * You may use, distribute and modify this code, please write to: romanov73@gmail.com. + * + */ + +package ru.ulstu.datamodel.ts; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/src/main/java/ru/ulstu/tsMethods/TimeSeriesMethod.java b/src/main/java/ru/ulstu/method/Method.java similarity index 54% rename from src/main/java/ru/ulstu/tsMethods/TimeSeriesMethod.java rename to src/main/java/ru/ulstu/method/Method.java index 9dc5164..7422c9e 100644 --- a/src/main/java/ru/ulstu/tsMethods/TimeSeriesMethod.java +++ b/src/main/java/ru/ulstu/method/Method.java @@ -1,20 +1,19 @@ /* - * - * * Copyright (C) 2021 Anton Romanov - All Rights Reserved - * * You may use, distribute and modify this code, please write to: romanov73@gmail.com. - * + * Copyright (C) 2021 Anton Romanov - All Rights Reserved + * You may use, distribute and modify this code, please write to: romanov73@gmail.com. * */ -package ru.ulstu.tsMethods; +package ru.ulstu.method; import com.fasterxml.jackson.annotation.JsonIgnore; import ru.ulstu.TimeSeriesUtils; -import ru.ulstu.models.TimeSeries; -import ru.ulstu.models.TimeSeriesValue; -import ru.ulstu.models.exceptions.ForecastValidateException; -import ru.ulstu.models.exceptions.ModelingException; -import ru.ulstu.models.exceptions.TimeSeriesValidateException; +import ru.ulstu.datamodel.Model; +import ru.ulstu.datamodel.exception.ForecastValidateException; +import ru.ulstu.datamodel.exception.ModelingException; +import ru.ulstu.datamodel.exception.TimeSeriesValidateException; +import ru.ulstu.datamodel.ts.TimeSeries; +import ru.ulstu.datamodel.ts.TimeSeriesValue; import java.time.temporal.ChronoUnit; import java.util.List; @@ -22,69 +21,51 @@ import java.util.List; /** * Наиболее общая логика моделировании и прогнозирования временных рядов */ -public abstract class TimeSeriesMethod { - @JsonIgnore - protected TimeSeries originalTimeSeries; - @JsonIgnore - private TimeSeries model; - - public abstract TimeSeriesMethod createFor(TimeSeries originalTimeSeries); - +public abstract class Method { @JsonIgnore public abstract List getAvailableParameters(); - public abstract TimeSeriesMethod setAvailableParameters(List parameters); - - /** - * Возвращает модельное представление временного ряда: для тех же точек времени что и в параметре timeSeries - * строится модель. Количество точек может быть изменено: сокращено при сжатии ряда, увеличено при интерполяции. - * Метод является шаблонным, выполняет операции валидации исходного ряда и потом его моделирование - * - * @throws ModelingException генерируется, если есть проблемы моделирования при задании параметров - */ - protected void makeModel() throws ModelingException { - validateTimeSeries(); - model = getModelOfValidTimeSeries(); - } - /** * Возвращает модельное представление валидного временного ряда: для тех же точек времени что и в параметре timeSeries * строится модель. Количество точек может быть изменено: сокращено при сжатии ряда, увеличено при интерполяции. * - * @return модельное представление временного ряда + * @return модель временного ряда */ - protected abstract TimeSeries getModelOfValidTimeSeries() throws ModelingException; + protected abstract Model getModelOfValidTimeSeries(TimeSeries timeSeries, + List parameters) throws ModelingException; + + /** + * Возвращает модельное представление временного ряда: для тех же точек времени что и в параметре timeSeries + * строится модель. Количество точек может быть изменено: сокращено при сжатии ряда, увеличено при интерполяции. + * Метод является шаблонным, выполняет операции валидации исходного ряда и потом его моделирование + *

+ * return модельное представление временного ряда + * + * @throws ModelingException генерируется, если есть проблемы моделирования при задании параметров + */ + public Model getModel(TimeSeries timeSeries, List parameters) throws ModelingException { + validateTimeSeries(timeSeries); + validateAdditionalParams(timeSeries, parameters); + return getModelOfValidTimeSeries(timeSeries, parameters); + } /** * Выполняет построение прогноза временного ряда. Даты спрогнозированных точек будут сгенерированы по модельным точкам. * - * @param countPoints количество точек для прогнозирования + * @param model модель временного ряда, включающая все нужные компоненты + * @param forecast заготовка временного ряда для прогноза с датами и нужным количеством точек для прогнозирования * @return прогноз временного ряда */ - public TimeSeries getForecastWithValidParams(int countPoints) throws ModelingException { - TimeSeries forecast = generateEmptyForecastPoints(originalTimeSeries, countPoints); - getModel(); - forecast.getFirstValue().setValue(originalTimeSeries.getLastValue().getValue()); - forecast = makeForecast(forecast); - return forecast; - } + protected abstract TimeSeries getForecastWithValidParams(Model model, TimeSeries forecast) throws ModelingException; - /** - * Выполняет построение прогноза для уже сгенерированных будущих точек временного ряда. - * - * @param forecast Заготовка прогноза временного ряда с пустыми значениями - * @return временной ряд прогноза - */ - protected abstract TimeSeries makeForecast(TimeSeries forecast) throws ModelingException; - - protected TimeSeries generateEmptyForecastPoints(TimeSeries modelTimeSeries, int countPointForecast) { - long diffMilliseconds = TimeSeriesUtils.getTimeDifferenceInMilliseconds(originalTimeSeries); - TimeSeries forecast = new TimeSeries("Forecast of " + originalTimeSeries.getName()); - forecast.addValue(new TimeSeriesValue(modelTimeSeries.getLastValue().getDate())); - for (int i = 1; i < countPointForecast + 1; i++) { - forecast.addValue(new TimeSeriesValue(forecast.getValues().get(i - 1).getDate().plus(diffMilliseconds, ChronoUnit.MILLIS))); + public boolean canMakeForecast(TimeSeries timeSeries, int countPoints) { + try { + validateTimeSeries(timeSeries); + validateForecastParams(countPoints); + } catch (ModelingException ex) { + return false; } - return forecast; + return true; } /** @@ -94,9 +75,24 @@ public abstract class TimeSeriesMethod { * @param countPoints количество точек для прогнозирования * @return прогноз временного ряда */ - public TimeSeries getForecast(int countPoints) throws ModelingException { + public TimeSeries getForecast(TimeSeries timeSeries, + List parameters, + int countPoints) throws ModelingException { validateForecastParams(countPoints); - return getForecastWithValidParams(countPoints); + Model model = getModel(timeSeries, parameters); + TimeSeries forecast = generateEmptyForecastPoints(model.getTimeSeriesModel(), countPoints); + forecast.getFirstValue().setValue(model.getTimeSeriesModel().getLastValue().getValue()); + return getForecastWithValidParams(model, forecast); + } + + protected TimeSeries generateEmptyForecastPoints(TimeSeries model, int countPointForecast) { + long diffMilliseconds = TimeSeriesUtils.getTimeDifferenceInMilliseconds(model); + TimeSeries forecast = new TimeSeries("Forecast of " + model.getName()); + forecast.addValue(new TimeSeriesValue(model.getLastValue().getDate())); + for (int i = 1; i < countPointForecast + 1; i++) { + forecast.addValue(new TimeSeriesValue(forecast.getValues().get(i - 1).getDate().plus(diffMilliseconds, ChronoUnit.MILLIS))); + } + return forecast; } private void validateForecastParams(int countPoints) throws ForecastValidateException { @@ -105,41 +101,22 @@ public abstract class TimeSeriesMethod { } } - protected void validateTimeSeries() throws ModelingException { - if (originalTimeSeries == null || originalTimeSeries.isEmpty()) { + protected void validateTimeSeries(TimeSeries timeSeries) throws ModelingException { + if (timeSeries == null || timeSeries.isEmpty()) { throw new TimeSeriesValidateException("Временной ряд должен быть не пустым"); } - if (originalTimeSeries.getLength() < 2) { + if (timeSeries.getLength() < 2) { throw new TimeSeriesValidateException("Временной ряд должен содержать хотя бы 2 точки"); } - if (originalTimeSeries.getValues().stream().anyMatch(val -> val == null || val.getValue() == null)) { + if (timeSeries.getValues().stream().anyMatch(val -> val == null || val.getValue() == null)) { throw new TimeSeriesValidateException("Временной ряд содержит пустые значения"); } - if (originalTimeSeries.getValues().stream().anyMatch(val -> val.getDate() == null)) { + if (timeSeries.getValues().stream().anyMatch(val -> val.getDate() == null)) { throw new TimeSeriesValidateException("Временной ряд должен иметь отметки времени"); } - validateAdditionalParams(); } - protected void validateAdditionalParams() throws ModelingException { + protected void validateAdditionalParams(TimeSeries timeSeries, List parameters) throws ModelingException { } - - public TimeSeries getModel() throws ModelingException { - //TODO: what if always run? - //if (model == null) { - makeModel(); - //} - return model; - } - - public boolean canMakeForecast(int countPoints) { - try { - validateTimeSeries(); - validateForecastParams(countPoints); - } catch (ModelingException ex) { - return false; - } - return true; - } } diff --git a/src/main/java/ru/ulstu/method/MethodParamValue.java b/src/main/java/ru/ulstu/method/MethodParamValue.java new file mode 100644 index 0000000..74be6f7 --- /dev/null +++ b/src/main/java/ru/ulstu/method/MethodParamValue.java @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2021 Anton Romanov - All Rights Reserved + * You may use, distribute and modify this code, please write to: romanov73@gmail.com. + * + */ + +package ru.ulstu.method; + +public class MethodParamValue { + protected MethodParameter parameter; + protected Number value; + + public MethodParamValue(MethodParameter parameter, Number value) { + this.parameter = parameter; + this.value = value; + } + + public MethodParameter getParameter() { + return parameter; + } + + public Number getValue() { + return value; + } +} diff --git a/src/main/java/ru/ulstu/tsMethods/MethodParameter.java b/src/main/java/ru/ulstu/method/MethodParameter.java similarity index 70% rename from src/main/java/ru/ulstu/tsMethods/MethodParameter.java rename to src/main/java/ru/ulstu/method/MethodParameter.java index 874637f..f598fd7 100644 --- a/src/main/java/ru/ulstu/tsMethods/MethodParameter.java +++ b/src/main/java/ru/ulstu/method/MethodParameter.java @@ -1,12 +1,10 @@ /* - * - * * Copyright (C) 2021 Anton Romanov - All Rights Reserved - * * You may use, distribute and modify this code, please write to: romanov73@gmail.com. - * + * Copyright (C) 2021 Anton Romanov - All Rights Reserved + * You may use, distribute and modify this code, please write to: romanov73@gmail.com. * */ -package ru.ulstu.tsMethods; +package ru.ulstu.method; import java.util.List; diff --git a/src/main/java/ru/ulstu/method/exponential/addtrendaddseason/AddTrendAddSeason.java b/src/main/java/ru/ulstu/method/exponential/addtrendaddseason/AddTrendAddSeason.java new file mode 100644 index 0000000..1cbcdb5 --- /dev/null +++ b/src/main/java/ru/ulstu/method/exponential/addtrendaddseason/AddTrendAddSeason.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2021 Anton Romanov - All Rights Reserved + * You may use, distribute and modify this code, please write to: romanov73@gmail.com. + * + */ + +package ru.ulstu.method.exponential.addtrendaddseason; + +import org.springframework.stereotype.Component; +import ru.ulstu.datamodel.Model; +import ru.ulstu.datamodel.exception.ModelingException; +import ru.ulstu.datamodel.exception.TimeSeriesValidateException; +import ru.ulstu.datamodel.ts.TimeSeries; +import ru.ulstu.method.Method; +import ru.ulstu.method.MethodParamValue; +import ru.ulstu.method.MethodParameter; +import ru.ulstu.method.exponential.parameter.Season; + +import java.util.List; + +@Component +public class AddTrendAddSeason extends Method { + + @Override + protected Model getModelOfValidTimeSeries(TimeSeries ts, List parameters) { + AddTrendAddSeasonModel model = new AddTrendAddSeasonModel(ts, parameters); + List sComponent = model.getSmoothedComponent(); + List tComponent = model.getTrendComponent(); + List iComponent = model.getSeasonComponent(); + sComponent.add(ts.getFirstValue().getValue()); + TimeSeries tsModel = model.getTimeSeriesModel(); + + iComponent.add(1.0); + tComponent.add(0.0); + tsModel.addValue(ts.getFirstValue()); + //выполняется проход модели по сглаживанию + for (int t = 1; t < model.getSeason().getValue().intValue(); t++) { + sComponent.add(model.getAlpha().getDoubleValue() * ts.getNumericValue(t) + + (1 - model.getAlpha().getDoubleValue()) + * (sComponent.get(t - 1) + tComponent.get(t - 1))); + tComponent.add(model.getBeta().getDoubleValue() + * (sComponent.get(t) - sComponent.get(t - 1)) + + (1 - model.getBeta().getDoubleValue()) * tComponent.get(t - 1)); + iComponent.add(model.getGamma().getDoubleValue() * ts.getNumericValue(t) / sComponent.get(sComponent.size() - 1) + + (1 - model.getGamma().getDoubleValue()) * iComponent.get(0)); + tsModel.addValue(ts.getValues().get(t), sComponent.get(sComponent.size() - 1)); + } + for (int t = model.getSeason().getIntValue(); t < ts.getValues().size(); t++) { + sComponent.add(model.getAlpha().getDoubleValue() * ts.getNumericValue(t) + / iComponent.get(t - model.getSeason().getIntValue()) + + (1 - model.getAlpha().getDoubleValue()) + * (sComponent.get(t - 1) + tComponent.get(t - 1))); + + tComponent.add(model.getBeta().getDoubleValue() + * (sComponent.get(t) - sComponent.get(t - 1)) + + (1 - model.getBeta().getDoubleValue()) * tComponent.get(t - 1)); + + iComponent.add(model.getGamma().getDoubleValue() * ts.getNumericValue(t) / sComponent.get(sComponent.size() - 1) + + (1 - model.getGamma().getDoubleValue()) * iComponent.get(t - model.getSeason().getIntValue())); + tsModel.addValue(ts.getValue(t), sComponent.get(sComponent.size() - 1)); + } + return model; + } + + @Override + protected void validateAdditionalParams(TimeSeries ts, List parameters) throws ModelingException { + for (MethodParamValue parameter : parameters) { + if (parameter.getParameter() instanceof Season) { + if (ts.getLength() < parameter.getValue().intValue()) { + throw new TimeSeriesValidateException("Период больше чем длина ряда"); + } + } + } + + } + + @Override + protected TimeSeries getForecastWithValidParams(Model model, TimeSeries forecast) { + AddTrendAddSeasonModel currentModel = (AddTrendAddSeasonModel) model; + List sComponent = currentModel.getSmoothedComponent(); + List tComponent = currentModel.getTrendComponent(); + List iComponent = currentModel.getSeasonComponent(); + for (int t = 1; t < forecast.getLength(); t++) { + iComponent.add(currentModel.getGamma().getDoubleValue() * forecast.getNumericValue(t - 1) / sComponent.get(sComponent.size() - 1) + + (1 - currentModel.getGamma().getDoubleValue()) * iComponent.get(t + model.getTimeSeriesModel().getLength() - currentModel.getSeason().getIntValue())); + + forecast.getValues().get(t).setValue((sComponent.get(sComponent.size() - 1) + tComponent.get(tComponent.size() - 1) * t) + * iComponent.get(t + model.getTimeSeriesModel().getLength() - currentModel.getSeason().getIntValue())); + } + return forecast; + } + + @Override + public List getAvailableParameters() { + return AddTrendAddSeasonModel.getAvailableParameters(); + } +} diff --git a/src/main/java/ru/ulstu/method/exponential/addtrendaddseason/AddTrendAddSeasonModel.java b/src/main/java/ru/ulstu/method/exponential/addtrendaddseason/AddTrendAddSeasonModel.java new file mode 100644 index 0000000..075311c --- /dev/null +++ b/src/main/java/ru/ulstu/method/exponential/addtrendaddseason/AddTrendAddSeasonModel.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2021 Anton Romanov - All Rights Reserved + * You may use, distribute and modify this code, please write to: romanov73@gmail.com. + * + */ + +package ru.ulstu.method.exponential.addtrendaddseason; + +import ru.ulstu.datamodel.ts.TimeSeries; +import ru.ulstu.method.MethodParamValue; +import ru.ulstu.method.MethodParameter; +import ru.ulstu.method.exponential.parameter.Alpha; +import ru.ulstu.method.exponential.parameter.Beta; +import ru.ulstu.method.exponential.parameter.ExponentialMethodParamValue; +import ru.ulstu.method.exponential.parameter.Gamma; +import ru.ulstu.method.exponential.parameter.Season; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class AddTrendAddSeasonModel extends ru.ulstu.datamodel.Model { + private final ExponentialMethodParamValue alpha = new ExponentialMethodParamValue<>(Alpha.getInstance(), 0.5); + private final ExponentialMethodParamValue beta = new ExponentialMethodParamValue<>(Beta.getInstance(), 0.5); + private final ExponentialMethodParamValue gamma = new ExponentialMethodParamValue<>(Gamma.getInstance(), 0.5); + private final ExponentialMethodParamValue season = new ExponentialMethodParamValue<>(Season.getInstance(), 12); + private final List smoothedComponent = new ArrayList<>(); + private final List trendComponent = new ArrayList<>(); + private final List seasonComponent = new ArrayList<>(); + + public AddTrendAddSeasonModel(TimeSeries ts, List parameters) { + super(ts); + for (MethodParamValue parameter : parameters) { + if (parameter.getParameter() instanceof Alpha) { + alpha.setValue(parameter.getValue()); + } + if (parameter.getParameter() instanceof Beta) { + beta.setValue(parameter.getValue()); + } + if (parameter.getParameter() instanceof Gamma) { + gamma.setValue(parameter.getValue()); + } + if (parameter.getParameter() instanceof Season) { + season.setValue(parameter.getValue()); + } + } + } + + public List getSmoothedComponent() { + return smoothedComponent; + } + + public List getTrendComponent() { + return trendComponent; + } + + public List getSeasonComponent() { + return seasonComponent; + } + + public ExponentialMethodParamValue getAlpha() { + return alpha; + } + + public ExponentialMethodParamValue getBeta() { + return beta; + } + + public ExponentialMethodParamValue getGamma() { + return gamma; + } + + public ExponentialMethodParamValue getSeason() { + return season; + } + + public static List getAvailableParameters() { + return Arrays.asList(Alpha.getInstance(), Beta.getInstance(), Gamma.getInstance(), Season.getInstance()); + } +} diff --git a/src/main/java/ru/ulstu/method/exponential/addtrendnoseason/AddTrendNoSeason.java b/src/main/java/ru/ulstu/method/exponential/addtrendnoseason/AddTrendNoSeason.java new file mode 100644 index 0000000..bbe28ce --- /dev/null +++ b/src/main/java/ru/ulstu/method/exponential/addtrendnoseason/AddTrendNoSeason.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2021 Anton Romanov - All Rights Reserved + * You may use, distribute and modify this code, please write to: romanov73@gmail.com. + * + */ + +package ru.ulstu.method.exponential.addtrendnoseason; + +import org.springframework.stereotype.Component; +import ru.ulstu.datamodel.Model; +import ru.ulstu.datamodel.ts.TimeSeries; +import ru.ulstu.method.Method; +import ru.ulstu.method.MethodParamValue; +import ru.ulstu.method.MethodParameter; + +import java.util.List; + +@Component +public class AddTrendNoSeason extends Method { + + @Override + protected Model getModelOfValidTimeSeries(TimeSeries ts, List parameters) { + AddTrendNoSeasonModel model = new AddTrendNoSeasonModel(ts, parameters); + List sComponent = model.getSmoothedComponent(); + List tComponent = model.getTrendComponent(); + sComponent.add(ts.getFirstValue().getValue()); + TimeSeries tsModel = model.getTimeSeriesModel(); + + sComponent.add(ts.getFirstValue().getValue()); + tComponent.add(ts.getValue(1).getValue() - ts.getValue(0).getValue()); + tsModel.addValue(ts.getFirstValue()); + //выполняется проход модели по сглаживанию + for (int t = 1; t < ts.getValues().size(); t++) { + sComponent.add(model.getAlpha().getDoubleValue() * ts.getNumericValue(t) + + (1 - model.getAlpha().getDoubleValue()) + * (sComponent.get(t - 1) - tComponent.get(t - 1))); + + tComponent.add(model.getBeta().getDoubleValue() + * (sComponent.get(t) - sComponent.get(t - 1)) + + (1 - model.getBeta().getDoubleValue()) * tComponent.get(t - 1)); + tsModel.addValue(ts.getValues().get(t), sComponent.get(sComponent.size() - 1)); + } + return model; + } + + @Override + protected TimeSeries getForecastWithValidParams(Model model, TimeSeries forecast) { + AddTrendNoSeasonModel currentModel = (AddTrendNoSeasonModel) model; + List sComponent = currentModel.getSmoothedComponent(); + List tComponent = currentModel.getTrendComponent(); + for (int t = 1; t < forecast.getLength(); t++) { + forecast.getValues().get(t).setValue(sComponent.get(sComponent.size() - 1) + tComponent.get(tComponent.size() - 1) * t); + } + return forecast; + } + + @Override + public List getAvailableParameters() { + return AddTrendNoSeasonModel.getAvailableParameters(); + } +} diff --git a/src/main/java/ru/ulstu/method/exponential/addtrendnoseason/AddTrendNoSeasonModel.java b/src/main/java/ru/ulstu/method/exponential/addtrendnoseason/AddTrendNoSeasonModel.java new file mode 100644 index 0000000..a384abe --- /dev/null +++ b/src/main/java/ru/ulstu/method/exponential/addtrendnoseason/AddTrendNoSeasonModel.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2021 Anton Romanov - All Rights Reserved + * You may use, distribute and modify this code, please write to: romanov73@gmail.com. + * + */ + +package ru.ulstu.method.exponential.addtrendnoseason; + +import ru.ulstu.datamodel.ts.TimeSeries; +import ru.ulstu.method.MethodParamValue; +import ru.ulstu.method.MethodParameter; +import ru.ulstu.method.exponential.parameter.Alpha; +import ru.ulstu.method.exponential.parameter.Beta; +import ru.ulstu.method.exponential.parameter.ExponentialMethodParamValue; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class AddTrendNoSeasonModel extends ru.ulstu.datamodel.Model { + private final ExponentialMethodParamValue alpha = new ExponentialMethodParamValue<>(Alpha.getInstance(), 0.5); + private final ExponentialMethodParamValue beta = new ExponentialMethodParamValue<>(Beta.getInstance(), 0.5); + private final List smoothedComponent = new ArrayList<>(); + private final List trendComponent = new ArrayList<>(); + + public AddTrendNoSeasonModel(TimeSeries ts, List parameters) { + super(ts); + for (MethodParamValue parameter : parameters) { + if (parameter.getParameter() instanceof Alpha) { + alpha.setValue(parameter.getValue()); + } + if (parameter.getParameter() instanceof Beta) { + beta.setValue(parameter.getValue()); + } + } + } + + public List getSmoothedComponent() { + return smoothedComponent; + } + + public List getTrendComponent() { + return trendComponent; + } + + public ExponentialMethodParamValue getAlpha() { + return alpha; + } + + public ExponentialMethodParamValue getBeta() { + return beta; + } + + public static List getAvailableParameters() { + return Arrays.asList(Alpha.getInstance(), Beta.getInstance()); + } +} diff --git a/src/main/java/ru/ulstu/method/exponential/notrendnoseason/NoTrendNoSeason.java b/src/main/java/ru/ulstu/method/exponential/notrendnoseason/NoTrendNoSeason.java new file mode 100644 index 0000000..f4918da --- /dev/null +++ b/src/main/java/ru/ulstu/method/exponential/notrendnoseason/NoTrendNoSeason.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2021 Anton Romanov - All Rights Reserved + * You may use, distribute and modify this code, please write to: romanov73@gmail.com. + * + */ + +package ru.ulstu.method.exponential.notrendnoseason; + +import org.springframework.stereotype.Component; +import ru.ulstu.datamodel.Model; +import ru.ulstu.datamodel.ts.TimeSeries; +import ru.ulstu.method.Method; +import ru.ulstu.method.MethodParamValue; +import ru.ulstu.method.MethodParameter; + +import java.util.List; + +@Component +public class NoTrendNoSeason extends Method { + + @Override + protected NoTrendNoSeasonModel getModelOfValidTimeSeries(TimeSeries ts, + List parameters) { + NoTrendNoSeasonModel model = new NoTrendNoSeasonModel(ts, parameters); + List sComponent = model.getSmoothedComponent(); + sComponent.add(ts.getFirstValue().getValue()); + TimeSeries tsModel = model.getTimeSeriesModel(); + tsModel.addValue(ts.getFirstValue()); + //выполняется проход модели по сглаживанию + for (int t = 1; t < ts.getValues().size(); t++) { + sComponent.add(sComponent.get(t - 1) + + model.getAlpha().getDoubleValue() + * (ts.getNumericValue(t) - sComponent.get(t - 1))); + tsModel.addValue(ts.getValue(t), sComponent.get(sComponent.size() - 1)); + } + return model; + } + + @Override + protected TimeSeries getForecastWithValidParams(Model model, TimeSeries forecast) { + for (int t = 1; t < forecast.getLength(); t++) { + forecast.getValues().get(t).setValue(forecast.getValues().get(t - 1).getValue()); + } + return forecast; + } + + @Override + public List getAvailableParameters() { + return NoTrendNoSeasonModel.getAvailableParameters(); + } +} diff --git a/src/main/java/ru/ulstu/method/exponential/notrendnoseason/NoTrendNoSeasonModel.java b/src/main/java/ru/ulstu/method/exponential/notrendnoseason/NoTrendNoSeasonModel.java new file mode 100644 index 0000000..fae41fc --- /dev/null +++ b/src/main/java/ru/ulstu/method/exponential/notrendnoseason/NoTrendNoSeasonModel.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2021 Anton Romanov - All Rights Reserved + * You may use, distribute and modify this code, please write to: romanov73@gmail.com. + * + */ + +package ru.ulstu.method.exponential.notrendnoseason; + +import ru.ulstu.datamodel.ts.TimeSeries; +import ru.ulstu.method.MethodParamValue; +import ru.ulstu.method.MethodParameter; +import ru.ulstu.method.exponential.parameter.Alpha; +import ru.ulstu.method.exponential.parameter.ExponentialMethodParamValue; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class NoTrendNoSeasonModel extends ru.ulstu.datamodel.Model { + private final ExponentialMethodParamValue alpha = new ExponentialMethodParamValue<>(Alpha.getInstance(), 0.5); + private final List smoothedComponent = new ArrayList<>(); + + public NoTrendNoSeasonModel(TimeSeries ts, List parameters) { + super(ts); + for (MethodParamValue parameter : parameters) { + if (parameter.getParameter() instanceof Alpha) { + alpha.setValue(parameter.getValue()); + } + } + } + + public List getSmoothedComponent() { + return smoothedComponent; + } + + public ExponentialMethodParamValue getAlpha() { + return alpha; + } + + public static List getAvailableParameters() { + return Collections.singletonList(Alpha.getInstance()); + } +} diff --git a/src/main/java/ru/ulstu/tsMethods/exponential/parameter/Alpha.java b/src/main/java/ru/ulstu/method/exponential/parameter/Alpha.java similarity index 89% rename from src/main/java/ru/ulstu/tsMethods/exponential/parameter/Alpha.java rename to src/main/java/ru/ulstu/method/exponential/parameter/Alpha.java index 264a113..5349824 100644 --- a/src/main/java/ru/ulstu/tsMethods/exponential/parameter/Alpha.java +++ b/src/main/java/ru/ulstu/method/exponential/parameter/Alpha.java @@ -4,7 +4,7 @@ * */ -package ru.ulstu.tsMethods.exponential.parameter; +package ru.ulstu.method.exponential.parameter; public class Alpha extends ExponentialMethodParameter { public Alpha() { diff --git a/src/main/java/ru/ulstu/tsMethods/exponential/parameter/Beta.java b/src/main/java/ru/ulstu/method/exponential/parameter/Beta.java similarity index 88% rename from src/main/java/ru/ulstu/tsMethods/exponential/parameter/Beta.java rename to src/main/java/ru/ulstu/method/exponential/parameter/Beta.java index aa58665..3599221 100644 --- a/src/main/java/ru/ulstu/tsMethods/exponential/parameter/Beta.java +++ b/src/main/java/ru/ulstu/method/exponential/parameter/Beta.java @@ -4,7 +4,7 @@ * */ -package ru.ulstu.tsMethods.exponential.parameter; +package ru.ulstu.method.exponential.parameter; public class Beta extends ExponentialMethodParameter { public Beta() { diff --git a/src/main/java/ru/ulstu/tsMethods/exponential/parameter/ExponentialMethodParamValue.java b/src/main/java/ru/ulstu/method/exponential/parameter/ExponentialMethodParamValue.java similarity index 74% rename from src/main/java/ru/ulstu/tsMethods/exponential/parameter/ExponentialMethodParamValue.java rename to src/main/java/ru/ulstu/method/exponential/parameter/ExponentialMethodParamValue.java index 813a5ad..0498795 100644 --- a/src/main/java/ru/ulstu/tsMethods/exponential/parameter/ExponentialMethodParamValue.java +++ b/src/main/java/ru/ulstu/method/exponential/parameter/ExponentialMethodParamValue.java @@ -1,12 +1,10 @@ /* - * - * * Copyright (C) 2021 Anton Romanov - All Rights Reserved - * * You may use, distribute and modify this code, please write to: romanov73@gmail.com. - * + * Copyright (C) 2021 Anton Romanov - All Rights Reserved + * You may use, distribute and modify this code, please write to: romanov73@gmail.com. * */ -package ru.ulstu.tsMethods.exponential.parameter; +package ru.ulstu.method.exponential.parameter; public class ExponentialMethodParamValue { private final T param; diff --git a/src/main/java/ru/ulstu/tsMethods/exponential/parameter/ExponentialMethodParameter.java b/src/main/java/ru/ulstu/method/exponential/parameter/ExponentialMethodParameter.java similarity index 94% rename from src/main/java/ru/ulstu/tsMethods/exponential/parameter/ExponentialMethodParameter.java rename to src/main/java/ru/ulstu/method/exponential/parameter/ExponentialMethodParameter.java index 61e1c8f..cea22c5 100644 --- a/src/main/java/ru/ulstu/tsMethods/exponential/parameter/ExponentialMethodParameter.java +++ b/src/main/java/ru/ulstu/method/exponential/parameter/ExponentialMethodParameter.java @@ -4,10 +4,10 @@ * */ -package ru.ulstu.tsMethods.exponential.parameter; +package ru.ulstu.method.exponential.parameter; import com.fasterxml.jackson.annotation.JsonIgnore; -import ru.ulstu.tsMethods.MethodParameter; +import ru.ulstu.method.MethodParameter; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/ru/ulstu/tsMethods/exponential/parameter/Gamma.java b/src/main/java/ru/ulstu/method/exponential/parameter/Gamma.java similarity index 89% rename from src/main/java/ru/ulstu/tsMethods/exponential/parameter/Gamma.java rename to src/main/java/ru/ulstu/method/exponential/parameter/Gamma.java index 95a3bc3..8ebf87c 100644 --- a/src/main/java/ru/ulstu/tsMethods/exponential/parameter/Gamma.java +++ b/src/main/java/ru/ulstu/method/exponential/parameter/Gamma.java @@ -4,7 +4,7 @@ * */ -package ru.ulstu.tsMethods.exponential.parameter; +package ru.ulstu.method.exponential.parameter; public class Gamma extends ExponentialMethodParameter { public Gamma() { diff --git a/src/main/java/ru/ulstu/tsMethods/exponential/parameter/Season.java b/src/main/java/ru/ulstu/method/exponential/parameter/Season.java similarity index 90% rename from src/main/java/ru/ulstu/tsMethods/exponential/parameter/Season.java rename to src/main/java/ru/ulstu/method/exponential/parameter/Season.java index 0297431..4aae2f5 100644 --- a/src/main/java/ru/ulstu/tsMethods/exponential/parameter/Season.java +++ b/src/main/java/ru/ulstu/method/exponential/parameter/Season.java @@ -4,7 +4,7 @@ * */ -package ru.ulstu.tsMethods.exponential.parameter; +package ru.ulstu.method.exponential.parameter; public class Season extends ExponentialMethodParameter { private final static int DEFAULT_SEASON_OPTIMIZATION_STEP = 1; diff --git a/src/main/java/ru/ulstu/models/ModelingResult.java b/src/main/java/ru/ulstu/models/ModelingResult.java deleted file mode 100644 index 0b7de01..0000000 --- a/src/main/java/ru/ulstu/models/ModelingResult.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * - * * Copyright (C) 2021 Anton Romanov - All Rights Reserved - * * You may use, distribute and modify this code, please write to: romanov73@gmail.com. - * - * - */ - -package ru.ulstu.models; - -import ru.ulstu.tsMethods.TimeSeriesMethod; -import ru.ulstu.tsMethods.TimeSeriesMethodParamValue; - -import java.util.List; - -public class ModelingResult { - private final TimeSeries timeSeries; - private final List paramValues; - private final Score score; - private final TimeSeriesMethod timeSeriesMethod; - - public ModelingResult(TimeSeries timeSeries, - List paramValues, - Score score, - TimeSeriesMethod timeSeriesMethod) { - this.timeSeries = timeSeries; - this.paramValues = paramValues; - this.score = score; - this.timeSeriesMethod = timeSeriesMethod; - } - - public TimeSeries getTimeSeries() { - return timeSeries; - } - - public List getParamValues() { - return paramValues; - } - - public Score getScore() { - return score; - } - - public TimeSeriesMethod getTimeSeriesMethod() { - return timeSeriesMethod; - } -} diff --git a/src/main/java/ru/ulstu/models/exceptions/ForecastValidateException.java b/src/main/java/ru/ulstu/models/exceptions/ForecastValidateException.java deleted file mode 100644 index 083ef0e..0000000 --- a/src/main/java/ru/ulstu/models/exceptions/ForecastValidateException.java +++ /dev/null @@ -1,7 +0,0 @@ -package ru.ulstu.models.exceptions; - -public class ForecastValidateException extends ModelingException { - public ForecastValidateException(String message) { - super(message); - } -} diff --git a/src/main/java/ru/ulstu/models/exceptions/ModelingException.java b/src/main/java/ru/ulstu/models/exceptions/ModelingException.java deleted file mode 100644 index 4bebd12..0000000 --- a/src/main/java/ru/ulstu/models/exceptions/ModelingException.java +++ /dev/null @@ -1,7 +0,0 @@ -package ru.ulstu.models.exceptions; - -public class ModelingException extends Exception { - public ModelingException(String message) { - super(message); - } -} diff --git a/src/main/java/ru/ulstu/models/exceptions/TimeSeriesValidateException.java b/src/main/java/ru/ulstu/models/exceptions/TimeSeriesValidateException.java deleted file mode 100644 index 1137ed7..0000000 --- a/src/main/java/ru/ulstu/models/exceptions/TimeSeriesValidateException.java +++ /dev/null @@ -1,7 +0,0 @@ -package ru.ulstu.models.exceptions; - -public class TimeSeriesValidateException extends ModelingException { - public TimeSeriesValidateException(String message) { - super(message); - } -} diff --git a/src/main/java/ru/ulstu/pages/IndexView.java b/src/main/java/ru/ulstu/page/IndexView.java similarity index 93% rename from src/main/java/ru/ulstu/pages/IndexView.java rename to src/main/java/ru/ulstu/page/IndexView.java index 98bba42..539c06c 100644 --- a/src/main/java/ru/ulstu/pages/IndexView.java +++ b/src/main/java/ru/ulstu/page/IndexView.java @@ -4,7 +4,7 @@ * */ -package ru.ulstu.pages; +package ru.ulstu.page; import org.primefaces.model.chart.AxisType; import org.primefaces.model.chart.DateAxis; @@ -14,11 +14,11 @@ import org.primefaces.model.chart.LineChartSeries; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import ru.ulstu.models.TimeSeries; -import ru.ulstu.models.TimeSeriesValue; -import ru.ulstu.models.exceptions.ModelingException; -import ru.ulstu.services.TimeSeriesService; -import ru.ulstu.services.UtilService; +import ru.ulstu.datamodel.exception.ModelingException; +import ru.ulstu.datamodel.ts.TimeSeries; +import ru.ulstu.datamodel.ts.TimeSeriesValue; +import ru.ulstu.service.TimeSeriesService; +import ru.ulstu.service.UtilService; import javax.annotation.PostConstruct; import javax.faces.view.ViewScoped; diff --git a/src/main/java/ru/ulstu/score/ScoreMethod.java b/src/main/java/ru/ulstu/score/ScoreMethod.java index 69301d3..5c227f2 100644 --- a/src/main/java/ru/ulstu/score/ScoreMethod.java +++ b/src/main/java/ru/ulstu/score/ScoreMethod.java @@ -1,17 +1,15 @@ /* - * - * * Copyright (C) 2021 Anton Romanov - All Rights Reserved - * * You may use, distribute and modify this code, please write to: romanov73@gmail.com. - * + * Copyright (C) 2021 Anton Romanov - All Rights Reserved + * You may use, distribute and modify this code, please write to: romanov73@gmail.com. * */ package ru.ulstu.score; -import ru.ulstu.models.Score; -import ru.ulstu.models.TimeSeries; -import ru.ulstu.models.TimeSeriesValue; -import ru.ulstu.models.exceptions.ModelingException; +import ru.ulstu.datamodel.Score; +import ru.ulstu.datamodel.exception.ModelingException; +import ru.ulstu.datamodel.ts.TimeSeries; +import ru.ulstu.datamodel.ts.TimeSeriesValue; public abstract class ScoreMethod { private final String name; diff --git a/src/main/java/ru/ulstu/score/Smape.java b/src/main/java/ru/ulstu/score/Smape.java index cf8eb24..17a8b2c 100644 --- a/src/main/java/ru/ulstu/score/Smape.java +++ b/src/main/java/ru/ulstu/score/Smape.java @@ -1,16 +1,14 @@ /* - * - * * Copyright (C) 2021 Anton Romanov - All Rights Reserved - * * You may use, distribute and modify this code, please write to: romanov73@gmail.com. - * + * Copyright (C) 2021 Anton Romanov - All Rights Reserved + * You may use, distribute and modify this code, please write to: romanov73@gmail.com. * */ package ru.ulstu.score; -import ru.ulstu.models.TimeSeries; -import ru.ulstu.models.TimeSeriesValue; -import ru.ulstu.models.exceptions.ModelingException; +import ru.ulstu.datamodel.exception.ModelingException; +import ru.ulstu.datamodel.ts.TimeSeries; +import ru.ulstu.datamodel.ts.TimeSeriesValue; import static java.lang.Math.abs; diff --git a/src/main/java/ru/ulstu/services/MethodParamBruteForce.java b/src/main/java/ru/ulstu/service/MethodParamBruteForce.java similarity index 71% rename from src/main/java/ru/ulstu/services/MethodParamBruteForce.java rename to src/main/java/ru/ulstu/service/MethodParamBruteForce.java index 41b3e64..0f1e6ad 100644 --- a/src/main/java/ru/ulstu/services/MethodParamBruteForce.java +++ b/src/main/java/ru/ulstu/service/MethodParamBruteForce.java @@ -4,17 +4,18 @@ * */ -package ru.ulstu.services; +package ru.ulstu.service; import org.springframework.stereotype.Service; -import ru.ulstu.models.ModelingResult; -import ru.ulstu.models.TimeSeries; -import ru.ulstu.models.exceptions.ModelingException; +import ru.ulstu.datamodel.Model; +import ru.ulstu.datamodel.ModelingResult; +import ru.ulstu.datamodel.exception.ModelingException; +import ru.ulstu.datamodel.ts.TimeSeries; +import ru.ulstu.method.Method; +import ru.ulstu.method.MethodParamValue; +import ru.ulstu.method.MethodParameter; import ru.ulstu.score.ScoreMethod; import ru.ulstu.score.Smape; -import ru.ulstu.tsMethods.MethodParameter; -import ru.ulstu.tsMethods.TimeSeriesMethod; -import ru.ulstu.tsMethods.TimeSeriesMethodParamValue; import java.util.ArrayList; import java.util.Comparator; @@ -29,11 +30,11 @@ import java.util.concurrent.Future; @Service public class MethodParamBruteForce { private final int DEFAULT_THREAD_COUNT = 50; - private final List methods; + private final List methods; private final ScoreMethod scoreMethod = new Smape(); private final ExecutorService executors = Executors.newFixedThreadPool(DEFAULT_THREAD_COUNT); - public MethodParamBruteForce(List methods) { + public MethodParamBruteForce(List methods) { this.methods = methods; } @@ -49,15 +50,21 @@ public class MethodParamBruteForce { List> results = new ArrayList<>(); List results2 = new CopyOnWriteArrayList<>(); try { - for (TimeSeriesMethod method : methods) { - List> availableParametersValues = getAvailableParametersValues(method.getAvailableParameters()); - for (List parametersValues : availableParametersValues) { + for (Method method : methods) { + List> availableParametersValues = getAvailableParametersValues(method.getAvailableParameters()); + for (List parametersValues : availableParametersValues) { results.add(executors.submit(() -> { - TimeSeriesMethod methodInstance = method.getClass().getDeclaredConstructor().newInstance(); - TimeSeries model = methodInstance.createFor(timeSeries) - .setAvailableParameters(parametersValues) - .getModel(); - return new ModelingResult(model, parametersValues, scoreMethod.getScore(timeSeries, model), methodInstance); + Method methodInstance = method.getClass().getDeclaredConstructor().newInstance(); + try { + Model model = methodInstance.getModel(timeSeries, parametersValues); + return new ModelingResult(model.getTimeSeriesModel(), + parametersValues, + scoreMethod.getScore(timeSeries, model.getTimeSeriesModel()), + methodInstance); + } catch (ModelingException ex) { + ex.printStackTrace(); + return null; + } })); } } @@ -79,8 +86,8 @@ public class MethodParamBruteForce { } } - private List> getAvailableParametersValues(List availableParameters) { - List> result = new ArrayList<>(); + private List> getAvailableParametersValues(List availableParameters) { + List> result = new ArrayList<>(); Map parameterOffset = new TreeMap<>(); Map> parameterValues = new TreeMap<>(); for (MethodParameter methodParameter : availableParameters) { @@ -88,9 +95,9 @@ public class MethodParamBruteForce { parameterValues.put(methodParameter, methodParameter.getAvailableValues()); } while (!isAllValuesUsed(parameterOffset, parameterValues)) { - List resultRow = new ArrayList<>(); + List resultRow = new ArrayList<>(); for (MethodParameter methodParameter : parameterOffset.keySet()) { - resultRow.add(new TimeSeriesMethodParamValue(methodParameter, + resultRow.add(new MethodParamValue(methodParameter, parameterValues.get(methodParameter).get(parameterOffset.get(methodParameter)))); } incrementOffset(parameterOffset, parameterValues); diff --git a/src/main/java/ru/ulstu/services/TimeSeriesService.java b/src/main/java/ru/ulstu/service/TimeSeriesService.java similarity index 57% rename from src/main/java/ru/ulstu/services/TimeSeriesService.java rename to src/main/java/ru/ulstu/service/TimeSeriesService.java index 168332a..1758f21 100644 --- a/src/main/java/ru/ulstu/services/TimeSeriesService.java +++ b/src/main/java/ru/ulstu/service/TimeSeriesService.java @@ -4,18 +4,17 @@ * */ -package ru.ulstu.services; +package ru.ulstu.service; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; -import ru.ulstu.models.TimeSeries; -import ru.ulstu.models.exceptions.ModelingException; -import ru.ulstu.tsMethods.TimeSeriesMethod; -import ru.ulstu.tsMethods.exponential.AddTrendAddSeason; -import ru.ulstu.tsMethods.exponential.NoTrendNoSeason; -import ru.ulstu.tsMethods.exponential.parameter.Alpha; -import ru.ulstu.tsMethods.exponential.parameter.ExponentialMethodParamValue; +import ru.ulstu.datamodel.exception.ModelingException; +import ru.ulstu.datamodel.ts.TimeSeries; +import ru.ulstu.method.Method; +import ru.ulstu.method.exponential.addtrendaddseason.AddTrendAddSeason; + +import java.util.Collections; @Service @@ -28,10 +27,9 @@ public class TimeSeriesService { } public TimeSeries getForecast(TimeSeries timeSeries, int countPoints) throws ModelingException { - TimeSeriesMethod method; - method = new NoTrendNoSeason().createFor(timeSeries).setAlpha(new ExponentialMethodParamValue<>(new Alpha(), 0.8)); - method = new AddTrendAddSeason().createFor(timeSeries); - return method.getForecast(countPoints); + Method method; + method = new AddTrendAddSeason(); + return method.getForecast(timeSeries, Collections.emptyList(), countPoints); } public TimeSeries smoothTimeSeries(TimeSeries timeSeries) throws ModelingException { diff --git a/src/main/java/ru/ulstu/services/UtilService.java b/src/main/java/ru/ulstu/service/UtilService.java similarity index 87% rename from src/main/java/ru/ulstu/services/UtilService.java rename to src/main/java/ru/ulstu/service/UtilService.java index df78e69..7351583 100644 --- a/src/main/java/ru/ulstu/services/UtilService.java +++ b/src/main/java/ru/ulstu/service/UtilService.java @@ -1,11 +1,17 @@ -package ru.ulstu.services; +/* + * Copyright (C) 2021 Anton Romanov - All Rights Reserved + * You may use, distribute and modify this code, please write to: romanov73@gmail.com. + * + */ + +package ru.ulstu.service; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import ru.ulstu.TimeSeriesUtils; -import ru.ulstu.models.TimeSeries; -import ru.ulstu.models.TimeSeriesValue; +import ru.ulstu.datamodel.ts.TimeSeries; +import ru.ulstu.datamodel.ts.TimeSeriesValue; import java.time.LocalDateTime; import java.util.Arrays; diff --git a/src/main/java/ru/ulstu/tsMethods/TimeSeriesMethodParamValue.java b/src/main/java/ru/ulstu/tsMethods/TimeSeriesMethodParamValue.java deleted file mode 100644 index f5c9e76..0000000 --- a/src/main/java/ru/ulstu/tsMethods/TimeSeriesMethodParamValue.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * - * * Copyright (C) 2021 Anton Romanov - All Rights Reserved - * * You may use, distribute and modify this code, please write to: romanov73@gmail.com. - * - * - */ - -package ru.ulstu.tsMethods; - -public class TimeSeriesMethodParamValue { - protected MethodParameter parameter; - protected Number value; - - public TimeSeriesMethodParamValue(MethodParameter parameter, Number value) { - this.parameter = parameter; - this.value = value; - } - - public MethodParameter getParameter() { - return parameter; - } - - public Number getValue() { - return value; - } -} diff --git a/src/main/java/ru/ulstu/tsMethods/exponential/AddTrendAddSeason.java b/src/main/java/ru/ulstu/tsMethods/exponential/AddTrendAddSeason.java deleted file mode 100644 index 0f18d35..0000000 --- a/src/main/java/ru/ulstu/tsMethods/exponential/AddTrendAddSeason.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (C) 2021 Anton Romanov - All Rights Reserved - * You may use, distribute and modify this code, please write to: romanov73@gmail.com. - * - */ - -package ru.ulstu.tsMethods.exponential; - -import org.springframework.stereotype.Component; -import ru.ulstu.models.TimeSeries; -import ru.ulstu.models.exceptions.ModelingException; -import ru.ulstu.models.exceptions.TimeSeriesValidateException; -import ru.ulstu.tsMethods.MethodParameter; -import ru.ulstu.tsMethods.TimeSeriesMethod; -import ru.ulstu.tsMethods.TimeSeriesMethodParamValue; -import ru.ulstu.tsMethods.exponential.parameter.Alpha; -import ru.ulstu.tsMethods.exponential.parameter.Beta; -import ru.ulstu.tsMethods.exponential.parameter.ExponentialMethodParamValue; -import ru.ulstu.tsMethods.exponential.parameter.Gamma; -import ru.ulstu.tsMethods.exponential.parameter.Season; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -@Component -public class AddTrendAddSeason extends TimeSeriesMethod { - private ExponentialMethodParamValue alpha = new ExponentialMethodParamValue<>(Alpha.getInstance(), 0.5); - private ExponentialMethodParamValue beta = new ExponentialMethodParamValue<>(Beta.getInstance(), 0.5); - private ExponentialMethodParamValue gamma = new ExponentialMethodParamValue<>(Gamma.getInstance(), 0.5); - private ExponentialMethodParamValue season = new ExponentialMethodParamValue<>(Season.getInstance(), 12); - private final List sComponent = new ArrayList<>(); - private final List tComponent = new ArrayList<>(); - private final List iComponent = new ArrayList<>(); - - public AddTrendAddSeason createFor(TimeSeries timeSeries) { - this.originalTimeSeries = timeSeries; - return this; - } - - public AddTrendAddSeason setAlpha(ExponentialMethodParamValue alpha) { - this.alpha = alpha; - return this; - } - - public AddTrendAddSeason setBeta(ExponentialMethodParamValue beta) { - this.beta = beta; - return this; - } - - public AddTrendAddSeason setGamma(ExponentialMethodParamValue gamma) { - this.gamma = gamma; - return this; - } - - public AddTrendAddSeason setSeason(ExponentialMethodParamValue season) { - this.season = season; - return this; - } - - @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 { - TimeSeries model = getModel(); - 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 + model.getLength() - season.getIntValue())); - - forecast.getValues().get(t).setValue((sComponent.get(sComponent.size() - 1) + tComponent.get(tComponent.size() - 1) * t) - * iComponent.get(t + model.getLength() - season.getIntValue())); - } - return forecast; - } - - @Override - public List getAvailableParameters() { - return Arrays.asList(alpha.getParam(), beta.getParam(), gamma.getParam(), season.getParam()); - } - - @Override - public TimeSeriesMethod setAvailableParameters(List parameters) { - for (TimeSeriesMethodParamValue parameter : parameters) { - if (parameter.getParameter() instanceof Alpha) { - alpha.setValue(parameter.getValue()); - } - if (parameter.getParameter() instanceof Beta) { - beta.setValue(parameter.getValue()); - } - if (parameter.getParameter() instanceof Gamma) { - gamma.setValue(parameter.getValue()); - } - if (parameter.getParameter() instanceof Season) { - season.setValue(parameter.getValue()); - } - } - return this; - } -} diff --git a/src/main/java/ru/ulstu/tsMethods/exponential/AddTrendNoSeason.java b/src/main/java/ru/ulstu/tsMethods/exponential/AddTrendNoSeason.java deleted file mode 100644 index 84856fe..0000000 --- a/src/main/java/ru/ulstu/tsMethods/exponential/AddTrendNoSeason.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * - * * Copyright (C) 2021 Anton Romanov - All Rights Reserved - * * You may use, distribute and modify this code, please write to: romanov73@gmail.com. - * - * - */ - -package ru.ulstu.tsMethods.exponential; - -import org.springframework.stereotype.Component; -import ru.ulstu.models.TimeSeries; -import ru.ulstu.tsMethods.MethodParameter; -import ru.ulstu.tsMethods.TimeSeriesMethod; -import ru.ulstu.tsMethods.TimeSeriesMethodParamValue; -import ru.ulstu.tsMethods.exponential.parameter.Alpha; -import ru.ulstu.tsMethods.exponential.parameter.Beta; -import ru.ulstu.tsMethods.exponential.parameter.ExponentialMethodParamValue; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -@Component -public class AddTrendNoSeason extends TimeSeriesMethod { - private ExponentialMethodParamValue alpha = new ExponentialMethodParamValue<>(Alpha.getInstance(), 0.5); - private ExponentialMethodParamValue beta = new ExponentialMethodParamValue<>(Beta.getInstance(), 0.5); - private final List sComponent = new ArrayList<>(); - private final List tComponent = new ArrayList<>(); - - public AddTrendNoSeason createFor(TimeSeries timeSeries) { - this.originalTimeSeries = timeSeries; - return this; - } - - public AddTrendNoSeason setAlpha(ExponentialMethodParamValue alpha) { - this.alpha = alpha; - return this; - } - - public AddTrendNoSeason setBeta(ExponentialMethodParamValue beta) { - this.beta = beta; - return this; - } - - @Override - protected TimeSeries getModelOfValidTimeSeries() { - sComponent.clear(); - tComponent.clear(); - sComponent.add(originalTimeSeries.getFirstValue().getValue()); - tComponent.add(originalTimeSeries.getValues().get(1).getValue() - originalTimeSeries.getValues().get(0).getValue()); - TimeSeries model = new TimeSeries("Model of " + originalTimeSeries.getName()); - model.addValue(originalTimeSeries.getFirstValue()); - //выполняется проход модели по сглаживанию - for (int t = 1; t < originalTimeSeries.getValues().size(); 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)); - model.addValue(originalTimeSeries.getValues().get(t), sComponent.get(sComponent.size() - 1)); - } - return model; - } - - @Override - protected TimeSeries makeForecast(TimeSeries forecast) { - for (int t = 1; t < forecast.getLength(); t++) { - forecast.getValues().get(t).setValue(sComponent.get(sComponent.size() - 1) + tComponent.get(tComponent.size() - 1) * t); - } - return forecast; - } - - @Override - public List getAvailableParameters() { - return Arrays.asList(alpha.getParam(), beta.getParam()); - } - - @Override - public TimeSeriesMethod setAvailableParameters(List parameters) { - for (TimeSeriesMethodParamValue parameter : parameters) { - if (parameter.getParameter() instanceof Alpha) { - alpha.setValue(parameter.getValue()); - } - if (parameter.getParameter() instanceof Beta) { - beta.setValue(parameter.getValue()); - } - } - return this; - } -} diff --git a/src/main/java/ru/ulstu/tsMethods/exponential/NoTrendNoSeason.java b/src/main/java/ru/ulstu/tsMethods/exponential/NoTrendNoSeason.java deleted file mode 100644 index 9e6a4c4..0000000 --- a/src/main/java/ru/ulstu/tsMethods/exponential/NoTrendNoSeason.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2021 Anton Romanov - All Rights Reserved - * You may use, distribute and modify this code, please write to: romanov73@gmail.com. - * - */ - -package ru.ulstu.tsMethods.exponential; - -import org.springframework.stereotype.Component; -import ru.ulstu.models.TimeSeries; -import ru.ulstu.tsMethods.MethodParameter; -import ru.ulstu.tsMethods.TimeSeriesMethod; -import ru.ulstu.tsMethods.TimeSeriesMethodParamValue; -import ru.ulstu.tsMethods.exponential.parameter.Alpha; -import ru.ulstu.tsMethods.exponential.parameter.ExponentialMethodParamValue; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -@Component -public class NoTrendNoSeason extends TimeSeriesMethod { - private ExponentialMethodParamValue alpha = new ExponentialMethodParamValue<>(Alpha.getInstance(), 0.5); - private final List sComponent = new ArrayList<>(); - - public NoTrendNoSeason createFor(TimeSeries timeSeries) { - this.originalTimeSeries = timeSeries; - return this; - } - - public NoTrendNoSeason setAlpha(ExponentialMethodParamValue alpha) { - this.alpha = alpha; - return this; - } - - @Override - protected TimeSeries getModelOfValidTimeSeries() { - sComponent.clear(); - sComponent.add(originalTimeSeries.getFirstValue().getValue()); - TimeSeries model = new TimeSeries("Model of " + originalTimeSeries.getName()); - model.addValue(originalTimeSeries.getFirstValue()); - //выполняется проход модели по сглаживанию - for (int t = 1; t < originalTimeSeries.getValues().size(); t++) { - sComponent.add(sComponent.get(t - 1) - + alpha.getDoubleValue() - * (originalTimeSeries.getNumericValue(t) - sComponent.get(t - 1))); - model.addValue(originalTimeSeries.getValues().get(t), sComponent.get(sComponent.size() - 1)); - } - return model; - } - - @Override - protected TimeSeries makeForecast(TimeSeries forecast) { - for (int t = 1; t < forecast.getLength(); t++) { - forecast.getValues().get(t).setValue(forecast.getValues().get(t - 1).getValue()); - } - return forecast; - } - - @Override - public List getAvailableParameters() { - return Collections.singletonList(alpha.getParam()); - } - - @Override - public TimeSeriesMethod setAvailableParameters(List parameters) { - for (TimeSeriesMethodParamValue parameter : parameters) { - if (parameter.getParameter() instanceof Alpha) { - alpha.setValue(parameter.getValue()); - } - } - return this; - } -}