add statistic service

This commit is contained in:
Anton Romanov 2023-01-08 12:39:40 +04:00
parent 35d88d4aa6
commit a6183567b9
5 changed files with 123 additions and 14 deletions

View File

@ -17,8 +17,8 @@ repositories {
} }
} }
sourceCompatibility = '11' sourceCompatibility = '17'
targetCompatibility = '11' targetCompatibility = '17'
dependencies { dependencies {
ext { ext {
@ -26,8 +26,8 @@ dependencies {
versionJetty = '9.3.16.v20170120' versionJetty = '9.3.16.v20170120'
} }
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-web' implementation group: 'org.springframework.boot', name: 'spring-boot-starter-web'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-jetty' implementation group: 'org.springframework.boot', name: 'spring-boot-starter-jetty'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-thymeleaf' implementation group: 'org.springframework.boot', name: 'spring-boot-starter-thymeleaf'
implementation group: 'org.slf4j', name: 'slf4j-api', version: versionSLF4J implementation group: 'org.slf4j', name: 'slf4j-api', version: versionSLF4J
implementation group: 'nz.net.ultraq.thymeleaf', name: 'thymeleaf-layout-dialect', version: '3.0.0' implementation group: 'nz.net.ultraq.thymeleaf', name: 'thymeleaf-layout-dialect', version: '3.0.0'

View File

@ -11,7 +11,7 @@ import static java.lang.Math.abs;
public class Smape extends ScoreMethod { public class Smape extends ScoreMethod {
public Smape() { public Smape() {
super("Smape"); super("Smape, %");
} }
@Override @Override

View File

@ -0,0 +1,43 @@
package ru.ulstu.statistic;
import org.springframework.stereotype.Service;
import ru.ulstu.datamodel.ts.TimeSeries;
import ru.ulstu.datamodel.ts.TimeSeriesValue;
import java.util.Optional;
import java.util.OptionalDouble;
import java.util.stream.DoubleStream;
@Service
public class StatisticService {
public Optional<Double> getAverage(TimeSeries timeSeries) {
return getOptionalValue(getDoubleStream(timeSeries).average());
}
public Optional<Double> getMin(TimeSeries timeSeries) {
return getOptionalValue(getDoubleStream(timeSeries).min());
}
public Optional<Double> getMax(TimeSeries timeSeries) {
return getOptionalValue(getDoubleStream(timeSeries).max());
}
public Optional<Double> getLength(TimeSeries timeSeries) {
return getOptionalValue(Double.valueOf(timeSeries.getLength()));
}
private DoubleStream getDoubleStream(TimeSeries timeSeries) {
return timeSeries.getValues().stream().mapToDouble(TimeSeriesValue::getValue);
}
private Optional<Double> getOptionalValue(OptionalDouble optionalDouble) {
return Optional.ofNullable(optionalDouble.isPresent()
? optionalDouble.getAsDouble()
: null);
}
private Optional<Double> getOptionalValue(Double value) {
return Optional.ofNullable(value);
}
}

View File

@ -91,10 +91,8 @@
json.plotOptions = plotOptions; json.plotOptions = plotOptions;
$('#chart').highcharts(json); $('#chart').highcharts(json);
}); });
</script> </script>
<form action="#" th:action="chart" th:object="${chartForm}"> <form action="#" th:action="chart" th:object="${chartForm}">
<div class="row"> <div class="row">
<div class="col-md-12 col-sm-12 col-lg-6"> <div class="col-md-12 col-sm-12 col-lg-6">
@ -109,7 +107,6 @@
<script th:inline="javascript" th:if="*{set != null}"> <script th:inline="javascript" th:if="*{set != null}">
$('#select-set').val([[*{set.key}]]); $('#select-set').val([[*{set.key}]]);
$('#select-set').selectpicker('refresh'); $('#select-set').selectpicker('refresh');
</script> </script>
<select id="select-ts" class="selectpicker form-group" data-live-search="true" <select id="select-ts" class="selectpicker form-group" data-live-search="true"
@ -121,15 +118,42 @@
th:utext="${ts.key}"> th:utext="${ts.key}">
</option> </option>
</select> </select>
<script th:inline="javascript" th:if="*{timeSeriesMeta != null}">
$('#select-ts').val([[*{timeSeriesMeta.key}]]);
$('#select-ts').selectpicker('refresh');
<script th:inline="javascript" th:if="*{timeSeriesMeta != null}">
$('#select-ts').val([[ * {timeSeriesMeta.key}]
])
;
$('#select-ts').selectpicker('refresh');
</script> </script>
<h5 th:if="${forecastDescription != null && forecastDescription.timeSeriesMethod != null}">
Результаты моделирования:
</h5>
<div th:if="${forecastDescription != null && forecastDescription.timeSeriesMethod != null}"> <div th:if="${forecastDescription != null && forecastDescription.timeSeriesMethod != null}">
<p> Метод прогнозирования: <span th:text="${forecastDescription.timeSeriesMethod}"> </span> <p> Метод прогнозирования:
<p> Оценка: <span th:text="${forecastDescription.score.value}"> </span> <span th:text="${forecastDescription.timeSeriesMethod}"/>
</p>
<hr/>
<p> Оценка прогноза по
<span th:text="${forecastDescription.score.scoreMethod.name}"/>:
<span th:text="${forecastDescription.score.value}"/>
</p>
<hr/>
</div>
<h5 th:if="${forecastDescription != null && forecastDescription.timeSeriesMethod != null}">
Статистические характеристики временного ряда:
</h5>
<div th:if="${forecastDescription != null && forecastDescription.timeSeriesMethod != null}">
<p> Метод прогнозирования:
<span th:text="${forecastDescription.timeSeriesMethod}"/>
</p>
<hr/>
<p> Оценка прогноза по
<span th:text="${forecastDescription.score.scoreMethod.name}"/>:
<span th:text="${forecastDescription.score.value}"/>
</p>
<hr/>
</div> </div>
</div> </div>
<div class="col-md-12 col-sm-12 col-lg-6"> <div class="col-md-12 col-sm-12 col-lg-6">

View File

@ -0,0 +1,42 @@
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import ru.ulstu.TimeSeriesUtils;
import ru.ulstu.datamodel.ts.TimeSeries;
import ru.ulstu.datamodel.ts.TimeSeriesValue;
import ru.ulstu.statistic.StatisticService;
import java.time.LocalDateTime;
public class StatisticServiceTest {
private TimeSeries getTimeSeries() {
TimeSeries ts = new TimeSeries();
for (int i = 0; i < 11; i++) {
ts.addValue(new TimeSeriesValue(LocalDateTime.now(), (double) i));
}
return TimeSeriesUtils.fillDates(ts);
}
@Test
public void testAverage() {
Assertions.assertEquals(new StatisticService().getAverage(getTimeSeries())
.orElseThrow(() -> new RuntimeException("Average test failed")), 5.0);
}
@Test
public void testMin() {
Assertions.assertEquals(new StatisticService().getMin(getTimeSeries())
.orElseThrow(() -> new RuntimeException("Min test failed")), 0.0);
}
@Test
public void testMax() {
Assertions.assertEquals(new StatisticService().getMax(getTimeSeries())
.orElseThrow(() -> new RuntimeException("Max test failed")), 10.0);
}
@Test
public void testLength() {
Assertions.assertEquals(new StatisticService().getLength(getTimeSeries())
.orElseThrow(() -> new RuntimeException("Length test failed")), 11.0);
}
}