create full brutforce over parameters

This commit is contained in:
Anton Romanov 2021-05-28 12:22:14 +04:00
parent ce8fd32642
commit 65fa782b10
19 changed files with 458 additions and 111 deletions

View File

@ -1,3 +1,11 @@
/*
*
* * 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;
import io.swagger.annotations.ApiOperation;
@ -9,8 +17,10 @@ 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;
@RestController
@ -18,9 +28,12 @@ import ru.ulstu.services.TimeSeriesService;
public class TimeSeriesController {
private final TimeSeriesService timeSeriesService;
private final MethodParamBruteForce methodParamBruteForce;
public TimeSeriesController(TimeSeriesService timeSeriesService) {
public TimeSeriesController(TimeSeriesService timeSeriesService,
MethodParamBruteForce methodParamBruteForce) {
this.timeSeriesService = timeSeriesService;
this.methodParamBruteForce = methodParamBruteForce;
}
@PostMapping("getForecast")
@ -29,4 +42,10 @@ public class TimeSeriesController {
return new ResponseEntity<>(timeSeriesService.getForecast(forecastParams.getOriginalTimeSeries(),
forecastParams.getCountForecast()), HttpStatus.OK);
}
@PostMapping("getSmoothed")
@ApiOperation("Получить сглаженный временной ряд")
public ResponseEntity<ModelingResult> getSmoothedTimeSeries(@RequestBody TimeSeries timeSeries) throws ModelingException {
return new ResponseEntity<>(methodParamBruteForce.getSmoothedTimeSeries(timeSeries), HttpStatus.OK);
}
}

View File

@ -1,6 +1,15 @@
/*
*
* * 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.exponential.param.TimeSeriesMethodParamValue;
import ru.ulstu.tsMethods.TimeSeriesMethod;
import ru.ulstu.tsMethods.TimeSeriesMethodParamValue;
import java.util.List;
@ -8,11 +17,16 @@ public class ModelingResult {
private final TimeSeries timeSeries;
private final List<TimeSeriesMethodParamValue> paramValues;
private final Score score;
private final TimeSeriesMethod timeSeriesMethod;
public ModelingResult(TimeSeries timeSeries, List<TimeSeriesMethodParamValue> paramValues, Score score) {
public ModelingResult(TimeSeries timeSeries,
List<TimeSeriesMethodParamValue> paramValues,
Score score,
TimeSeriesMethod timeSeriesMethod) {
this.timeSeries = timeSeries;
this.paramValues = paramValues;
this.score = score;
this.timeSeriesMethod = timeSeriesMethod;
}
public TimeSeries getTimeSeries() {
@ -26,4 +40,8 @@ public class ModelingResult {
public Score getScore() {
return score;
}
public TimeSeriesMethod getTimeSeriesMethod() {
return timeSeriesMethod;
}
}

View File

@ -1,5 +1,14 @@
/*
*
* * 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 com.fasterxml.jackson.annotation.JsonIgnore;
import ru.ulstu.score.ScoreMethod;
public class Score {
@ -18,4 +27,9 @@ public class Score {
public Number getValue() {
return value;
}
@JsonIgnore
public Double getDoubleValue() {
return value.doubleValue();
}
}

View File

@ -1,7 +1,40 @@
/*
*
* * 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;
public abstract class ScoreMethod {
public abstract Number evaluate(TimeSeries originalTimeSeries, TimeSeries modelTimeSeries);
private final String name;
public ScoreMethod(String name) {
this.name = name;
}
public Score getScore(TimeSeries original, TimeSeries model) throws ModelingException {
return new Score(this, evaluate(original, model));
}
public abstract Number evaluate(TimeSeries original, TimeSeries model) throws ModelingException;
public String getName() {
return name;
}
protected TimeSeriesValue getValueOnSameDate(TimeSeriesValue timeSeriesValueToFind, TimeSeries timeSeries) throws ModelingException {
return timeSeries.getValues()
.stream()
.filter(v -> v.getDate().equals(timeSeriesValueToFind.getDate()))
.findAny()
.orElseThrow(() -> new ModelingException("Значение модельного ряда не найдено в оригинальном ряде: " + timeSeriesValueToFind.getDate()));
}
}

View File

@ -0,0 +1,33 @@
/*
*
* * 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 static java.lang.Math.abs;
public class Smape extends ScoreMethod {
public Smape() {
super("Smape");
}
@Override
public Number evaluate(TimeSeries original, TimeSeries model) throws ModelingException {
double sum = 0;
for (TimeSeriesValue modelValue : model.getValues()) {
double actualValue = getValueOnSameDate(modelValue, original).getValue();
sum += abs(modelValue.getValue() - actualValue)
/ ((abs(actualValue) + abs(modelValue.getValue())) / 2);
}
sum = Math.round(sum * 100) / 100;
return sum * 100 / model.getLength();
}
}

View File

@ -1,60 +1,138 @@
/*
*
* * 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.services;
import org.springframework.stereotype.Service;
import ru.ulstu.models.ModelingResult;
import ru.ulstu.models.TimeSeries;
import ru.ulstu.models.exceptions.ModelingException;
import ru.ulstu.score.ScoreMethod;
import ru.ulstu.score.Smape;
import ru.ulstu.tsMethods.MethodParameter;
import ru.ulstu.tsMethods.TimeSeriesMethod;
import ru.ulstu.tsMethods.exponential.param.TimeSeriesMethodParam;
import ru.ulstu.tsMethods.exponential.param.TimeSeriesMethodParamValue;
import ru.ulstu.tsMethods.TimeSeriesMethodParamValue;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
@Service
public class MethodParamBruteForce {
private final int DEFAULT_THREAD_COUNT = 10;
private final List<TimeSeriesMethod> methods;
private ExecutorService executors = Executors.newFixedThreadPool(10);
private final ScoreMethod scoreMethod = new Smape();
private final ExecutorService executors = Executors.newFixedThreadPool(DEFAULT_THREAD_COUNT);
public MethodParamBruteForce(List<TimeSeriesMethod> methods) {
this.methods = methods;
}
public TimeSeries getForecast(TimeSeries timeSeries) {
throw new RuntimeException("Not implemented");
}
public TimeSeries getForecastWithOptimalLength(TimeSeries timeSeries) {
throw new RuntimeException("Not implemented");
}
public TimeSeries getSmoothedTimeSeries(TimeSeries timeSeries) {
List<Future<ModelingResult>> results = new ArrayList<>();
public ModelingResult getSmoothedTimeSeries(TimeSeries timeSeries) throws ModelingException {
//List<Future<ModelingResult>> results = new ArrayList<>();
List<ModelingResult> results2 = new CopyOnWriteArrayList<>();
for (TimeSeriesMethod method : methods) {
List<TimeSeriesMethodParam> availableParams = method.getAvailableParams();
Map<TimeSeriesMethodParam, List<Number>> paramsAvailableValues = new HashMap<>();
for (TimeSeriesMethodParam param : availableParams) {
paramsAvailableValues.put(param, param.getAvailableValues());
List<List<TimeSeriesMethodParamValue>> availableParametersValues = getAvailableParametersValues(method.getAvailableParameters());
for (List<TimeSeriesMethodParamValue> parametersValues : availableParametersValues) {
/*results.add(executors.submit(() -> {
TimeSeries model = method.createFor(timeSeries)
.setAvailableParameters(parametersValues)
.getModel();
return new ModelingResult(model, parametersValues, scoreMethod.getScore(timeSeries, model));
}));*/
TimeSeries model = method.createFor(timeSeries)
.setAvailableParameters(parametersValues)
.getModel();
results2.add(new ModelingResult(model,
parametersValues,
scoreMethod.getScore(timeSeries, model),
method));
}
List<TimeSeriesMethodParamValue> paramValues = new ArrayList<>();
results.add(executors.submit(() -> {
return new ModelingResult(method.getModel(),
method.createFor(timeSeries)
.setAvailableParams(paramValues)
.getModel());
}));
}
TimeSeries result = null;
try {
result = results.get(0).get();
/*results.forEach(modelingResultFuture -> {
try {
modelingResultFuture.get();
} catch (Exception e) {
e.printStackTrace();
}
});
for (Future<ModelingResult> futureModelingResult: results) {
results2.add(futureModelingResult.get());
}*/
return results2.stream()
.min(Comparator.comparing(modelingResult -> modelingResult.getScore().getDoubleValue()))
.orElse(null);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private List<List<TimeSeriesMethodParamValue>> getAvailableParametersValues(List<MethodParameter> availableParameters) {
List<List<TimeSeriesMethodParamValue>> result = new ArrayList<>();
Map<MethodParameter, Integer> parameterOffset = new TreeMap<>();
Map<MethodParameter, List<Number>> parameterValues = new TreeMap<>();
for (MethodParameter methodParameter : availableParameters) {
parameterOffset.put(methodParameter, 0);
parameterValues.put(methodParameter, methodParameter.getAvailableValues());
}
while (!isAllValuesUsed(parameterOffset, parameterValues)) {
List<TimeSeriesMethodParamValue> resultRow = new ArrayList<>();
for (MethodParameter methodParameter : parameterOffset.keySet()) {
resultRow.add(new TimeSeriesMethodParamValue(methodParameter,
parameterValues.get(methodParameter).get(parameterOffset.get(methodParameter))));
}
incrementOffset(parameterOffset, parameterValues);
result.add(resultRow);
}
return result;
}
private void incrementOffset(Map<MethodParameter, Integer> parameterOffset,
Map<MethodParameter, List<Number>> parameterValues) {
List<MethodParameter> parameters = new ArrayList<>(parameterOffset.keySet());
int i = 0;
while (i < parameters.size() && !isAllValuesUsed(parameterOffset, parameterValues)) {
if (parameterOffset.get(parameters.get(i)) == parameterValues.get(parameters.get(i)).size() - 1) {
parameterOffset.put(parameters.get(i), 0);
i++;
//continue;
}
if (parameterOffset.get(parameters.get(i)) < parameterValues.get(parameters.get(i)).size()) {
parameterOffset.put(parameters.get(i), parameterOffset.get(parameters.get(i)) + 1);
return;
}
i++;
}
}
private boolean isAllValuesUsed(Map<MethodParameter, Integer> parameterOffset,
Map<MethodParameter, List<Number>> parameterValues) {
for (MethodParameter methodParameter : parameterOffset.keySet()) {
if (parameterOffset.get(methodParameter) != parameterValues.get(methodParameter).size() - 1) {
return false;
}
}
return true;
}
}

View File

@ -16,11 +16,8 @@ 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.param.Alpha;
import ru.ulstu.tsMethods.exponential.param.Beta;
import ru.ulstu.tsMethods.exponential.param.ExponentialMethodParamValue;
import ru.ulstu.tsMethods.exponential.param.Gamma;
import ru.ulstu.tsMethods.exponential.param.Season;
import ru.ulstu.tsMethods.exponential.parameter.Alpha;
import ru.ulstu.tsMethods.exponential.parameter.ExponentialMethodParamValue;
@Service
@ -29,24 +26,16 @@ public class TimeSeriesService {
public TimeSeries getForecast(TimeSeries timeSeries, int countPoints) throws ModelingException {
TimeSeriesMethod method;
method = new NoTrendNoSeason(timeSeries, new ExponentialMethodParamValue<>(new Alpha(), 0.8));
method = new AddTrendAddSeason(timeSeries,
new ExponentialMethodParamValue<>(new Alpha(), 0.5),
new ExponentialMethodParamValue<>(new Beta(), 0.5),
new ExponentialMethodParamValue<>(new Gamma(), 0.5),
new ExponentialMethodParamValue<>(new Season(), 17));
method = new NoTrendNoSeason().createFor(timeSeries).setAlpha(new ExponentialMethodParamValue<>(new Alpha(), 0.8));
method = new AddTrendAddSeason().createFor(timeSeries);
return method.getForecast(countPoints);
}
public TimeSeries smoothTimeSeries(TimeSeries timeSeries) throws ModelingException {
//NoTrendNoSeason nn = new NoTrendNoSeason(timeSeries, ExponentialMethodParams.of(ExponentialParamName.ALPHA, 0.8));
TimeSeriesMethod method;
method = new NoTrendNoSeason(timeSeries, new ExponentialMethodParamValue<>(new Alpha(), 0.8));
method = new AddTrendAddSeason(timeSeries,
new ExponentialMethodParamValue<>(new Alpha(), 0.5),
new ExponentialMethodParamValue<>(new Beta(), 0.5),
new ExponentialMethodParamValue<>(new Gamma(), 0.5),
new ExponentialMethodParamValue<>(new Season(), 17));
method = new NoTrendNoSeason().createFor(timeSeries);
method = new AddTrendAddSeason().createFor(timeSeries);
return method.getModel();
}
}

View File

@ -0,0 +1,30 @@
/*
*
* * 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;
import java.util.List;
public abstract class MethodParameter implements Comparable {
protected String name;
public MethodParameter(String name) {
this.name = name;
}
public String getName() {
return name;
}
public abstract List<Number> getAvailableValues();
@Override
public int compareTo(Object o) {
return this.name.compareTo(((MethodParameter) o).getName());
}
}

View File

@ -1,22 +1,31 @@
/*
*
* * 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;
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.tsMethods.exponential.param.TimeSeriesMethodParam;
import ru.ulstu.tsMethods.exponential.param.TimeSeriesMethodParamValue;
import java.time.temporal.ChronoUnit;
import java.util.List;
/**
* Наиболее общая логика моделировани и прогнозирования временных рядов
* Наиболее общая логика моделировании и прогнозирования временных рядов
*/
public abstract class TimeSeriesMethod {
@JsonIgnore
protected TimeSeries originalTimeSeries;
@JsonIgnore
private TimeSeries model;
public abstract TimeSeriesMethod createFor(TimeSeries originalTimeSeries);
@ -113,13 +122,15 @@ public abstract class TimeSeriesMethod {
}
public TimeSeries getModel() throws ModelingException {
if (model == null) {
//TODO: what if always run?
//if (model == null) {
makeModel();
}
//}
return model;
}
public abstract List<TimeSeriesMethodParam> getAvailableParams();
@JsonIgnore
public abstract List<MethodParameter> getAvailableParameters();
public abstract TimeSeriesMethod setAvailableParams(List<TimeSeriesMethodParamValue> params);
public abstract TimeSeriesMethod setAvailableParameters(List<TimeSeriesMethodParamValue> parameters);
}

View File

@ -0,0 +1,27 @@
/*
*
* * 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;
}
}

View File

@ -11,35 +11,51 @@ 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.MethodParameter;
import ru.ulstu.tsMethods.TimeSeriesMethod;
import ru.ulstu.tsMethods.exponential.param.Alpha;
import ru.ulstu.tsMethods.exponential.param.Beta;
import ru.ulstu.tsMethods.exponential.param.ExponentialMethodParamValue;
import ru.ulstu.tsMethods.exponential.param.Gamma;
import ru.ulstu.tsMethods.exponential.param.Season;
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;
public class AddTrendAddSeason extends TimeSeriesMethod {
private final ExponentialMethodParamValue<Alpha> alpha;
private final ExponentialMethodParamValue<Beta> beta;
private final ExponentialMethodParamValue<Gamma> gamma;
private final ExponentialMethodParamValue<Season> season;
private ExponentialMethodParamValue<Alpha> alpha = new ExponentialMethodParamValue<>(Alpha.getInstance(), 0.5);
private ExponentialMethodParamValue<Beta> beta = new ExponentialMethodParamValue<>(Beta.getInstance(), 0.5);
private ExponentialMethodParamValue<Gamma> gamma = new ExponentialMethodParamValue<>(Gamma.getInstance(), 0.5);
private ExponentialMethodParamValue<Season> season = new ExponentialMethodParamValue<>(Season.getInstance(), 12);
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,
ExponentialMethodParamValue<Alpha> alpha,
ExponentialMethodParamValue<Beta> beta,
ExponentialMethodParamValue<Gamma> gamma,
ExponentialMethodParamValue<Season> season) throws ModelingException {
super(timeSeries);
public AddTrendAddSeason createFor(TimeSeries timeSeries) {
this.originalTimeSeries = timeSeries;
return this;
}
public AddTrendAddSeason setAlpha(ExponentialMethodParamValue<Alpha> alpha) {
this.alpha = alpha;
return this;
}
public AddTrendAddSeason setBeta(ExponentialMethodParamValue<Beta> beta) {
this.beta = beta;
return this;
}
public AddTrendAddSeason setGamma(ExponentialMethodParamValue<Gamma> gamma) {
this.gamma = gamma;
return this;
}
public AddTrendAddSeason setSeason(ExponentialMethodParamValue<Season> season) {
this.season = season;
return this;
}
@Override
@ -100,4 +116,28 @@ public class AddTrendAddSeason extends TimeSeriesMethod {
}
return forecast;
}
@Override
public List<MethodParameter> getAvailableParameters() {
return Arrays.asList(alpha.getParam(), beta.getParam(), gamma.getParam(), season.getParam());
}
@Override
public TimeSeriesMethod setAvailableParameters(List<TimeSeriesMethodParamValue> 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;
}
}

View File

@ -8,32 +8,43 @@
package ru.ulstu.tsMethods.exponential;
import org.springframework.stereotype.Component;
import ru.ulstu.models.TimeSeries;
import ru.ulstu.models.exceptions.ModelingException;
import ru.ulstu.tsMethods.MethodParameter;
import ru.ulstu.tsMethods.TimeSeriesMethod;
import ru.ulstu.tsMethods.exponential.param.Alpha;
import ru.ulstu.tsMethods.exponential.param.Beta;
import ru.ulstu.tsMethods.exponential.param.ExponentialMethodParamValue;
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 final ExponentialMethodParamValue<Alpha> alpha;
private final ExponentialMethodParamValue<Beta> beta;
private ExponentialMethodParamValue<Alpha> alpha = new ExponentialMethodParamValue<>(Alpha.getInstance(), 0.5);
private ExponentialMethodParamValue<Beta> beta = new ExponentialMethodParamValue<>(Beta.getInstance(), 0.5);
private final List<Double> sComponent = new ArrayList<>();
private final List<Double> tComponent = new ArrayList<>();
public AddTrendNoSeason(TimeSeries timeSeries,
ExponentialMethodParamValue<Alpha> alpha,
ExponentialMethodParamValue<Beta> beta) throws ModelingException {
super(timeSeries);
public AddTrendNoSeason createFor(TimeSeries timeSeries) {
this.originalTimeSeries = timeSeries;
return this;
}
public AddTrendNoSeason setAlpha(ExponentialMethodParamValue<Alpha> alpha) {
this.alpha = alpha;
return this;
}
public AddTrendNoSeason setBeta(ExponentialMethodParamValue<Beta> beta) {
this.beta = beta;
return this;
}
@Override
protected TimeSeries getModelOfValidTimeSeries() throws ModelingException {
protected TimeSeries getModelOfValidTimeSeries() {
sComponent.clear();
tComponent.clear();
sComponent.add(originalTimeSeries.getFirstValue().getValue());
@ -61,4 +72,22 @@ public class AddTrendNoSeason extends TimeSeriesMethod {
}
return forecast;
}
@Override
public List<MethodParameter> getAvailableParameters() {
return Arrays.asList(alpha.getParam(), beta.getParam());
}
@Override
public TimeSeriesMethod setAvailableParameters(List<TimeSeriesMethodParamValue> 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;
}
}

View File

@ -8,21 +8,20 @@
package ru.ulstu.tsMethods.exponential;
import org.springframework.stereotype.Component;
import ru.ulstu.models.TimeSeries;
import ru.ulstu.models.exceptions.ModelingException;
import ru.ulstu.tsMethods.MethodParameter;
import ru.ulstu.tsMethods.TimeSeriesMethod;
import ru.ulstu.tsMethods.exponential.param.Alpha;
import ru.ulstu.tsMethods.exponential.param.ExponentialMethodParam;
import ru.ulstu.tsMethods.exponential.param.ExponentialMethodParamValue;
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> alpha;
private ExponentialMethodParamValue<Alpha> alpha = new ExponentialMethodParamValue<>(Alpha.getInstance(), 0.5);
private final List<Double> sComponent = new ArrayList<>();
public NoTrendNoSeason createFor(TimeSeries timeSeries) {
@ -36,7 +35,7 @@ public class NoTrendNoSeason extends TimeSeriesMethod {
}
@Override
protected TimeSeries getModelOfValidTimeSeries() throws ModelingException {
protected TimeSeries getModelOfValidTimeSeries() {
sComponent.clear();
sComponent.add(originalTimeSeries.getFirstValue().getValue());
TimeSeries model = new TimeSeries("Model of " + originalTimeSeries.getName());
@ -60,15 +59,15 @@ public class NoTrendNoSeason extends TimeSeriesMethod {
}
@Override
public List<ExponentialMethodParam> getAvailableParams() {
public List<MethodParameter> getAvailableParameters() {
return Collections.singletonList(alpha.getParam());
}
@Override
public TimeSeriesMethod setAvailableParams(List<ExponentialMethodParamValue> params) {
for (ExponentialMethodParamValue param : params) {
if (param.getParam() instanceof Alpha) {
alpha.setValue(param.getValue());
public TimeSeriesMethod setAvailableParameters(List<TimeSeriesMethodParamValue> parameters) {
for (TimeSeriesMethodParamValue parameter : parameters) {
if (parameter.getParameter() instanceof Alpha) {
alpha.setValue(parameter.getValue());
}
}
return this;

View File

@ -6,10 +6,14 @@
*
*/
package ru.ulstu.tsMethods.exponential.param;
package ru.ulstu.tsMethods.exponential.parameter;
public class Alpha extends ExponentialMethodParam {
public class Alpha extends ExponentialMethodParameter {
public Alpha() {
super("ALPHA", 0, 1, DEFAULT_OPTIMIZATION_STEP);
}
public static Alpha getInstance() {
return new Alpha();
}
}

View File

@ -6,10 +6,14 @@
*
*/
package ru.ulstu.tsMethods.exponential.param;
package ru.ulstu.tsMethods.exponential.parameter;
public class Beta extends ExponentialMethodParam {
public class Beta extends ExponentialMethodParameter {
public Beta() {
super("BETA", 0, 1, DEFAULT_OPTIMIZATION_STEP);
}
public static Beta getInstance() {
return new Beta();
}
}

View File

@ -6,9 +6,9 @@
*
*/
package ru.ulstu.tsMethods.exponential.param;
package ru.ulstu.tsMethods.exponential.parameter;
public class ExponentialMethodParamValue<T extends ExponentialMethodParam> {
public class ExponentialMethodParamValue<T extends ExponentialMethodParameter> {
private final T param;
private Number value;

View File

@ -6,26 +6,27 @@
*
*/
package ru.ulstu.tsMethods.exponential.param;
package ru.ulstu.tsMethods.exponential.parameter;
public abstract class ExponentialMethodParam {
public static final Float DEFAULT_OPTIMIZATION_STEP = 0.01f;
private final String key;
import com.fasterxml.jackson.annotation.JsonIgnore;
import ru.ulstu.tsMethods.MethodParameter;
import java.util.ArrayList;
import java.util.List;
public abstract class ExponentialMethodParameter extends MethodParameter {
public static final Float DEFAULT_OPTIMIZATION_STEP = 0.1f;
private final Number minValue;
private final Number maxValue;
private final Number optimizationStep;
public ExponentialMethodParam(String key, Number minValue, Number maxValue, Number optimizationStep) {
this.key = key;
public ExponentialMethodParameter(String name, Number minValue, Number maxValue, Number optimizationStep) {
super(name);
this.minValue = minValue;
this.maxValue = maxValue;
this.optimizationStep = optimizationStep;
}
public String getKey() {
return key;
}
public Number getMinValue() {
return minValue;
}
@ -38,10 +39,20 @@ public abstract class ExponentialMethodParam {
return optimizationStep;
}
@Override
@JsonIgnore
public List<Number> getAvailableValues() {
List<Number> values = new ArrayList<>();
for (double i = minValue.doubleValue(); i <= maxValue.doubleValue(); i += optimizationStep.doubleValue()) {
values.add(i);
}
return values;
}
@Override
public String toString() {
return "TimeSeriesMethodParam{" +
"key='" + key + '\'' +
"name='" + name + '\'' +
", minValue=" + minValue +
", maxValue=" + maxValue +
", delta=" + optimizationStep +

View File

@ -6,10 +6,14 @@
*
*/
package ru.ulstu.tsMethods.exponential.param;
package ru.ulstu.tsMethods.exponential.parameter;
public class Gamma extends ExponentialMethodParam {
public class Gamma extends ExponentialMethodParameter {
public Gamma() {
super("Gamma", 0, 1, DEFAULT_OPTIMIZATION_STEP);
}
public static Gamma getInstance() {
return new Gamma();
}
}

View File

@ -6,12 +6,16 @@
*
*/
package ru.ulstu.tsMethods.exponential.param;
package ru.ulstu.tsMethods.exponential.parameter;
public class Season extends ExponentialMethodParam {
public class Season extends ExponentialMethodParameter {
private final static int DEFAULT_SEASON_OPTIMIZATION_STEP = 1;
public Season() {
super("Сезонность", 0, 12, DEFAULT_SEASON_OPTIMIZATION_STEP);
}
public static Season getInstance() {
return new Season();
}
}