diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 1ee2e3bd..1ab93696 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -1,10 +1,11 @@
version: 2
updates:
- - package-ecosystem: "maven"
+ - package-ecosystem: maven
target-branch: "develop"
directory: "/"
schedule:
- interval: "daily"
+ interval: "weekly"
+ day: "saturday"
open-pull-requests-limit: 10
- package-ecosystem: "github-actions"
target-branch: "develop"
diff --git a/.github/workflows/java-bundled.yml b/.github/workflows/java-bundled.yml
new file mode 100644
index 00000000..77e83eed
--- /dev/null
+++ b/.github/workflows/java-bundled.yml
@@ -0,0 +1,59 @@
+name: Update java.bundled
+
+on:
+ workflow_dispatch:
+ schedule:
+ - cron: '0 0 * * SAT'
+
+jobs:
+ update-mvn-property:
+ runs-on: ubuntu-latest
+ name: Update Maven property using the latest release version (tag) of a GitHub repository
+
+ env:
+ DEP_PROP: java.bundled.version
+ DEP_REPO: adoptium/temurin17-binaries
+
+ steps:
+ - name: Checkout source code
+ uses: actions/checkout@v4
+ with:
+ submodules: true
+ fetch-depth: 0
+
+ - name: Setup Java
+ uses: actions/setup-java@v3
+ with:
+ distribution: 'temurin'
+ java-version: 17
+ cache: 'maven'
+
+ - name: Get latest release version
+ id: lr
+ uses: pozetroninc/github-action-get-latest-release@master
+ with:
+ repository: ${{ env.DEP_REPO }}
+
+ - name: Apply latest release version on Maven property
+ run: >
+ mvn -B -ntp versions:set-property
+ -Dproperty=${{ env.DEP_PROP }}
+ -DnewVersion=${{ steps.lr.outputs.release }}
+ -DgenerateBackupPoms=false
+
+ - name: Create Pull Request
+ id: cpr
+ uses: peter-evans/create-pull-request@v5
+ with:
+ commit-message: Bump ${{ env.DEP_PROP }} to ${{ steps.lr.outputs.release }}
+ title: Bump ${{ env.DEP_PROP }} to ${{ steps.lr.outputs.release }}
+ body: ${{ steps.lr.outputs.description }}
+ delete-branch: true
+ branch: PR/maven/${{ github.ref_name }}/${{ env.DEP_PROP }}-${{ steps.lr.outputs.release }}
+ labels: dependencies,java
+
+ - name: Create summary
+ if: ${{ steps.cpr.outputs.pull-request-number }}
+ run: |
+ echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}" >> $GITHUB_STEP_SUMMARY
+ echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}" >> $GITHUB_STEP_SUMMARY
diff --git a/.github/workflows/java-ea-maven.yml b/.github/workflows/java-ea-maven.yml
index 6ec751ac..7906c032 100644
--- a/.github/workflows/java-ea-maven.yml
+++ b/.github/workflows/java-ea-maven.yml
@@ -11,7 +11,7 @@ jobs:
strategy:
fail-fast: false
matrix:
- java: [ '-ea' ]
+ java: [ 20 ]
os: [ ubuntu-latest ]
name: JDK${{ matrix.java }} on ${{ matrix.os }}
@@ -19,7 +19,7 @@ jobs:
steps:
- name: Checkout source code
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 0
diff --git a/.github/workflows/java-maven.yml b/.github/workflows/java-maven.yml
index 96ea2107..3aa58e6d 100644
--- a/.github/workflows/java-maven.yml
+++ b/.github/workflows/java-maven.yml
@@ -4,7 +4,7 @@ on: [ push, pull_request ]
jobs:
build-and-test-job:
- if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
+ if: github.event_name == 'pull_request' || startsWith(github.ref, 'refs/heads/develop') || startsWith(github.ref, 'refs/tags/v')
strategy:
fail-fast: false
matrix:
@@ -16,7 +16,7 @@ jobs:
steps:
- name: Checkout source code
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 0
@@ -28,11 +28,31 @@ jobs:
java-version: ${{ matrix.java }}
cache: 'maven'
+ - name: Pre-download dependencies with Maven
+ run: mvn -U -B -ntp dependency:go-offline
+
- name: Build and (headless) test with Maven
uses: smithki/xvfb-action@v1.1.2
with:
run: mvn -U -B -ntp package
+ auto-merge-job:
+ needs: build-and-test-job
+ if: startsWith(github.repository, 'jdemetra/') && github.event_name == 'pull_request' && github.actor == 'dependabot[bot]'
+ permissions:
+ contents: write
+ pull-requests: write
+
+ name: Auto-merge on dependabot PR
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Merge PR
+ run: gh pr merge --auto --rebase "$PR_URL"
+ env:
+ PR_URL: ${{github.event.pull_request.html_url}}
+ GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
+
snapshot-job:
needs: build-and-test-job
if: startsWith(github.repository, 'jdemetra/') && startsWith(github.ref, 'refs/heads/develop')
@@ -46,7 +66,7 @@ jobs:
steps:
- name: Checkout source code
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 0
@@ -96,7 +116,7 @@ jobs:
steps:
- name: Checkout source code
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 0
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c0cbe4a1..7290d80a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,31 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
+## [3.1.0] - 2023-10-11
+
+### Changed
+
+- ![OTHER] DeepSelect instead of Select to read MetaData with "." in key
+- ![UI] Modify menus for reference specifications
+
+### Fixed
+
+- ![STAT] Correct deviances in diffuse likelihood
+- ![STAT] Correct covariance of ARMA parameters in models with quasi-unit roots in AR
+- ![UI] Save correctly modified multiprocessing
+- ![UI] Fix non-removable star on data source nodes
+- ![IO] Fix NPE in grid reader when header is null
+
+### Added
+
+- ![STAT] Add Poisson distribution
+- ![OTHER] Serialize High-frequency series (modelling part)
+- ![OTHER] Add auxiliary functions to simplify the use of JD+ from R
+- ![OTHER] Add specifications and auxiliary functions for linear filters
+- ![OTHER] Add default modelling for seasonal adjustment (STL...)
+- ![OTHER] Add handling of time varying trading days
+- ![UI] Add export of SA documents to Excel
+
## [3.0.2] - 2023-06-14
### Changed
@@ -39,7 +64,8 @@ Install instructions are available at https://github.com/jdemetra/jdplus-main#in
This is the **initial release** of JDemetra+ v3.0.0.
[Java SE 17 or later](https://whichjdk.com/) version is required to run it.
-[Unreleased]: https://github.com/jdemetra/jd3-main/compare/v3.0.2...HEAD
+[Unreleased]: https://github.com/jdemetra/jd3-main/compare/v3.1.0...HEAD
+[3.1.0]: https://github.com/jdemetra/jd3-main/compare/v3.0.2...v3.1.0
[3.0.2]: https://github.com/jdemetra/jd3-main/compare/v3.0.1...v3.0.2
[3.0.1]: https://github.com/jdemetra/jd3-main/compare/v3.0.0...v3.0.1
[3.0.0]: https://github.com/jdemetra/jd3-main/releases/tag/v3.0.0
diff --git a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-api/pom.xml b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-api/pom.xml
index deae4c01..06c129c5 100644
--- a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-api/pom.xml
+++ b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-api/pom.xml
@@ -5,7 +5,7 @@
eu.europa.ec.joinup.sat
jdplus-sa-base-parent
- 3.0.2
+ 3.1.0
jdplus-sa-base-api
diff --git a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-api/src/main/java/jdplus/sa/base/api/SaItem.java b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-api/src/main/java/jdplus/sa/base/api/SaItem.java
index 4368052e..b9621e32 100644
--- a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-api/src/main/java/jdplus/sa/base/api/SaItem.java
+++ b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-api/src/main/java/jdplus/sa/base/api/SaItem.java
@@ -35,6 +35,7 @@
*/
@lombok.Value
@lombok.Builder(builderClassName = "Builder", toBuilder = true)
+@lombok.AllArgsConstructor(access=lombok.AccessLevel.PUBLIC)
public final class SaItem {
public static final String COMMENT = "comment";
@@ -151,6 +152,17 @@ public SaItem withTs(Ts ts) {
.build();
}
+ public SaItem withTsMetaData(Map info) {
+ Ts cur = definition.getTs();
+ Ts ncur = cur.toBuilder().clearMeta()
+ .meta(info)
+ .build();
+ SaDefinition ndef = definition.toBuilder()
+ .ts(ncur)
+ .build();
+ return new SaItem(name, ndef, meta, priority, estimation, processed);
+ }
+
public void accept() {
synchronized (this) {
if (estimation == null) {
diff --git a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-api/src/main/java/module-info.java b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-api/src/main/java/module-info.java
index 90fc70fb..152348a4 100644
--- a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-api/src/main/java/module-info.java
+++ b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-api/src/main/java/module-info.java
@@ -15,7 +15,6 @@
exports jdplus.sa.base.api.benchmarking;
exports jdplus.sa.base.api.diagnostics;
exports jdplus.sa.base.api.extractors;
- exports jdplus.sa.base.api.modelling;
exports jdplus.sa.base.api;
uses SaProcessingFactory;
diff --git a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-core/pom.xml b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-core/pom.xml
index 718633f1..621bb6e4 100644
--- a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-core/pom.xml
+++ b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-core/pom.xml
@@ -5,7 +5,7 @@
eu.europa.ec.joinup.sat
jdplus-sa-base-parent
- 3.0.2
+ 3.1.0
jdplus-sa-base-core
diff --git a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-core/src/main/java/jdplus/sa/base/core/regarima/AutomaticTradingDaysRegressionTest.java b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-core/src/main/java/jdplus/sa/base/core/regarima/AutomaticTradingDaysRegressionTest.java
index c200bafd..44e6e415 100644
--- a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-core/src/main/java/jdplus/sa/base/core/regarima/AutomaticTradingDaysRegressionTest.java
+++ b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-core/src/main/java/jdplus/sa/base/core/regarima/AutomaticTradingDaysRegressionTest.java
@@ -142,7 +142,7 @@ private ModelDescription createTestModel(RegSarimaModelling context, ITradingDay
tmp.setAirline(true);
tmp.setMean(true);
if (td != null) {
- tmp.addVariable(Variable.variable("td", td, ModelBuilder.calendarAMI));
+ tmp.addVariable(Variable.variable("td", td, ModelBuilder.calendarAMI));
}
if (lp != null) {
tmp.addVariable(Variable.variable("lp", lp, ModelBuilder.calendarAMI));
diff --git a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-core/src/main/java/jdplus/sa/base/core/regarima/FastKernel.java b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-core/src/main/java/jdplus/sa/base/core/regarima/FastKernel.java
deleted file mode 100644
index dda7445a..00000000
--- a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-core/src/main/java/jdplus/sa/base/core/regarima/FastKernel.java
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Copyright 2023 National Bank of Belgium
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved
- * by the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- */
-package jdplus.sa.base.core.regarima;
-
-import jdplus.toolkit.base.api.DemetraException;
-import jdplus.toolkit.base.api.modelling.regular.ModellingSpec;
-import nbbrd.design.Development;
-import jdplus.toolkit.base.core.regsarima.regular.IRegressionModule;
-import jdplus.toolkit.base.core.regsarima.regular.ModelDescription;
-import jdplus.toolkit.base.core.regsarima.regular.RegSarimaModelling;
-import jdplus.toolkit.base.core.regsarima.regular.RegSarimaProcessor;
-import jdplus.toolkit.base.api.processing.ProcessingLog;
-import jdplus.toolkit.base.api.timeseries.TsData;
-import jdplus.toolkit.base.api.timeseries.regression.ModellingContext;
-import jdplus.toolkit.base.core.regsarima.regular.ProcessingResult;
-import jdplus.toolkit.base.core.regarima.RegArimaEstimation;
-import jdplus.toolkit.base.core.regarima.RegArimaUtility;
-import jdplus.toolkit.base.core.regsarima.regular.ILogLevelModule;
-import jdplus.toolkit.base.core.regsarima.regular.IModelBuilder;
-import jdplus.toolkit.base.core.regsarima.regular.IOutliersDetectionModule;
-import jdplus.toolkit.base.core.regsarima.regular.RegSarimaModel;
-import jdplus.toolkit.base.core.regsarima.regular.RegressionVariablesTest;
-import jdplus.toolkit.base.core.sarima.SarimaModel;
-import nbbrd.design.BuilderPattern;
-import org.checkerframework.checker.nullness.qual.NonNull;
-
-/**
- *
- * @author Jean Palate
- */
-@Development(status = Development.Status.Preliminary)
-public class FastKernel implements RegSarimaProcessor {
-
- private static final String DEMETRA = "demetra";
-
- @lombok.Value
- @lombok.Builder
- public static class AmiOptions {
-
- boolean checkMu;
- double cval;
- double va;
- double precision, intermediatePrecision;
-
- public static Builder builder() {
- return new Builder()
- .cval(2)
- .intermediatePrecision(1e-5)
- .precision(1e-7);
- }
- }
-
- public static Builder builder() {
- return new Builder();
- }
-
- private static final AmiOptions DEFAULT = AmiOptions.builder().build();
-
- @BuilderPattern(FastKernel.class)
- public static class Builder {
-
- private IModelBuilder modelBuilder;
- private ILogLevelModule transformation;
- private IRegressionModule calendarTest, easterTest;
- private IOutliersDetectionModule outliers;
- private RegressionVariablesTest regressionTest0, regressionTest1;
- private AmiOptions options = DEFAULT;
-
- public Builder modelBuilder(@NonNull IModelBuilder builder) {
- this.modelBuilder = builder;
- return this;
- }
-
- public Builder options(AmiOptions options) {
- this.options = options;
- return this;
- }
-
- public Builder logLevel(ILogLevelModule ll) {
- this.transformation = ll;
- return this;
- }
-
- public Builder calendarTest(IRegressionModule calendarTest) {
- this.calendarTest = calendarTest;
- return this;
- }
-
- public Builder easterTest(IRegressionModule easterTest) {
- this.easterTest = easterTest;
- return this;
- }
-
- public Builder outliers(IOutliersDetectionModule outliers) {
- this.outliers = outliers;
- return this;
- }
-
- public Builder initialRegressionTest(RegressionVariablesTest test0) {
- this.regressionTest0 = test0;
- return this;
- }
-
- public Builder finalRegressionTest(RegressionVariablesTest test1) {
- this.regressionTest1 = test1;
- return this;
- }
-
- public FastKernel build() {
- FastKernel processor = new FastKernel(this);
- return processor;
- }
-
- }
-
- private final IModelBuilder modelBuilder;
- private final ILogLevelModule transformation;
- private final IRegressionModule calendarTest, easterTest;
- private final IOutliersDetectionModule outliers;
- private final RegressionVariablesTest regressionTest0, regressionTest1;
- private final AmiOptions options;
- private final ModelEstimator finalEstimator;
-
- private double curva = 0;
-
- private FastKernel(Builder builder) {
- this.modelBuilder = builder.modelBuilder;
- this.transformation = builder.transformation;
- this.calendarTest = builder.calendarTest;
- this.easterTest = builder.easterTest;
- this.outliers = builder.outliers;
- this.options = builder.options;
- this.regressionTest0 = builder.regressionTest0;
- this.regressionTest1 = builder.regressionTest1;
- finalEstimator = ModelEstimator.builder()
- .precision(options.precision)
- .build();
- }
-
- public static FastKernel of(ModellingSpec spec, ModellingContext context) {
- if (! spec.isEnabled())
- return null;
- SpecDecoder helper = new SpecDecoder(spec, context);
- return helper.buildProcessor();
- }
-
- @Override
- public RegSarimaModel process(TsData originalTs, ProcessingLog log) {
- if (log == null) {
- log = ProcessingLog.dummy();
- }
- clear();
- log.push(DEMETRA);
- ModelDescription desc = modelBuilder.build(originalTs, log);
- if (desc == null) {
- throw new DemetraException("Initialization failed");
- }
- if (outliers != null) {
- curva = options.getVa();
- if (curva == 0) {
- curva = DemetraUtility.calcCv(desc.getEstimationDomain().getLength());
- }
- }
- RegSarimaModelling modelling = RegSarimaModelling.of(desc, log);
- RegSarimaModel rslt = calc(modelling, log);
- log.pop();
-
- return rslt;
- }
-
- private void clear() {
- }
-
- private RegSarimaModel calc(RegSarimaModelling modelling, ProcessingLog log) {
-
- if (transformation != null) {
- transformation.process(modelling);
- } else if (modelling.getDescription().isLogTransformation()) {
- if (modelling.getDescription().getSeries().getValues().anyMatch(x -> x <= 0)) {
- modelling.getLog().warning("logs changed to levels");
- modelling.getDescription().setLogTransformation(false);
- modelling.clearEstimation();
- }
- }
-
- regAIC(modelling);
- checkMu(modelling, options.cval);
- if (outliers != null && ProcessingResult.Changed == outliers.process(modelling, curva)) {
- if (modelling.needEstimation()) {
- modelling.estimate(options.precision);
- }
- regressionTest0.process(modelling);
- }
-
- finalEstimator.estimate(modelling);
-
- return modelling.build();
- }
-
- private ProcessingResult regAIC(RegSarimaModelling modelling) {
- ProcessingResult rslt = ProcessingResult.Unchanged;
- if (calendarTest != null && calendarTest.test(modelling) == ProcessingResult.Changed) {
- rslt = ProcessingResult.Changed;
- }
- if (easterTest != null && easterTest.test(modelling) == ProcessingResult.Changed) {
- rslt = ProcessingResult.Changed;
- }
-// if (userTest != null && userTest.process(context) == ProcessingResult.Changed) {
-// rslt = ProcessingResult.Changed;
-// }
- return rslt;
- }
-
-
- private ProcessingResult checkMu(RegSarimaModelling modelling, double cv) {
- if (!options.checkMu) {
- return ProcessingResult.Unchanged;
- }
- ModelDescription desc = modelling.getDescription();
- RegArimaEstimation est = modelling.getEstimation();
- boolean mean = desc.isMean();
- if (!mean) {
- desc = ModelDescription.copyOf(desc);
- desc.setMean(true);
- est = null;
- }
- if (est == null) {
- est = desc.estimate(RegArimaUtility.processor(true, options.getIntermediatePrecision()));
- }
- double t = est.getConcentratedLikelihood().tstat(0, 0, false);
- boolean nmean = Math.abs(t) > cv;
- if (nmean == mean) {
- return ProcessingResult.Unchanged;
- } else {
- modelling.getDescription().setMean(nmean);
- modelling.clearEstimation();
- return ProcessingResult.Changed;
- }
- }
-
-}
diff --git a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-core/src/main/java/jdplus/sa/base/core/regarima/FastRegArimaFactory.java b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-core/src/main/java/jdplus/sa/base/core/regarima/FastRegArimaFactory.java
deleted file mode 100644
index 27874021..00000000
--- a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-core/src/main/java/jdplus/sa/base/core/regarima/FastRegArimaFactory.java
+++ /dev/null
@@ -1,509 +0,0 @@
-/*
- * Copyright 2023 National Bank of Belgium
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved
- * by the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- */
-package jdplus.sa.base.core.regarima;
-
-import jdplus.toolkit.base.api.arima.SarimaSpec;
-import jdplus.toolkit.base.api.data.Parameter;
-import jdplus.toolkit.base.api.data.Range;
-import jdplus.toolkit.base.api.modelling.TransformationType;
-import jdplus.toolkit.base.api.modelling.regular.CalendarSpec;
-import jdplus.toolkit.base.api.modelling.regular.EasterSpec;
-import jdplus.toolkit.base.api.modelling.regular.ModellingSpec;
-import jdplus.toolkit.base.api.modelling.regular.OutlierSpec;
-import jdplus.toolkit.base.api.modelling.regular.RegressionSpec;
-import jdplus.toolkit.base.api.modelling.regular.TradingDaysSpec;
-import jdplus.toolkit.base.api.modelling.regular.TransformSpec;
-import jdplus.sa.base.api.ComponentType;
-import jdplus.sa.base.api.EstimationPolicyType;
-import jdplus.sa.base.api.SaVariable;
-import jdplus.toolkit.base.api.timeseries.TimeSelector;
-import jdplus.toolkit.base.api.timeseries.TsDomain;
-import jdplus.toolkit.base.api.timeseries.TsPeriod;
-import jdplus.toolkit.base.api.timeseries.calendars.LengthOfPeriodType;
-import jdplus.toolkit.base.api.timeseries.calendars.TradingDaysType;
-import jdplus.toolkit.base.api.timeseries.regression.EasterVariable;
-import jdplus.toolkit.base.api.timeseries.regression.IOutlier;
-import jdplus.toolkit.base.api.timeseries.regression.ITradingDaysVariable;
-import jdplus.toolkit.base.api.timeseries.regression.ITsVariable;
-import jdplus.toolkit.base.api.timeseries.regression.InterventionVariable;
-import jdplus.toolkit.base.api.timeseries.regression.Ramp;
-import jdplus.toolkit.base.api.timeseries.regression.TrendConstant;
-import jdplus.toolkit.base.api.timeseries.regression.TsContextVariable;
-import jdplus.toolkit.base.api.timeseries.regression.Variable;
-import java.time.LocalDateTime;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import jdplus.toolkit.base.core.modelling.GeneralLinearModel;
-import jdplus.toolkit.base.core.regarima.ami.ModellingUtility;
-
-/**
- *
- * @author palatej
- */
-public class FastRegArimaFactory {
-
- private static final FastRegArimaFactory INSTANCE = new FastRegArimaFactory();
-
- public static FastRegArimaFactory getInstance() {
- return INSTANCE;
- }
-
- public ModellingSpec generateSpec(ModellingSpec spec, GeneralLinearModel.Description desc) {
- if (desc == null) {
- return spec;
- }
- ModellingSpec.Builder builder = spec.toBuilder();
- update(spec.getTransform(), desc, builder);
- update(desc, builder);
- update(spec.getOutliers(), builder);
- update(spec.getRegression(), desc, builder);
-
- return builder.build();
- }
-
- public ModellingSpec refreshSpec(ModellingSpec currentSpec, ModellingSpec domainSpec, EstimationPolicyType policy, TsDomain frozenDomain) {
- ModellingSpec.Builder builder = currentSpec.toBuilder();
- switch (policy) {
- case Complete -> {
- return domainSpec;
- }
- case Outliers_StochasticComponent -> {
- resetArima(domainSpec, builder);
- RegressionSpec rspec = removeOutliers(currentSpec, domainSpec, builder, frozenDomain);
- freeVariables(rspec, domainSpec, builder);
- }
- case Outliers -> {
- clearArima(currentSpec, domainSpec, builder);
- RegressionSpec rspec = removeOutliers(currentSpec, domainSpec, builder, frozenDomain);
- freeVariables(rspec, domainSpec, builder);
- }
- case LastOutliers -> {
- clearArima(currentSpec, domainSpec, builder);
- RegressionSpec rspec = removeOutliers(currentSpec, domainSpec, builder, frozenDomain);
- freeVariables(rspec, domainSpec, builder);
- }
- case FreeParameters -> {
- freeArima(currentSpec, domainSpec, builder);
- freeVariables(currentSpec.getRegression(), domainSpec, builder);
- }
- case FixedAutoRegressiveParameters -> {
- fixAR(currentSpec, domainSpec, builder);
- freeVariables(currentSpec.getRegression(), domainSpec, builder);
- }
- case FixedParameters -> {
- fixArima(currentSpec, builder);
- freeVariables(currentSpec.getRegression(), domainSpec, builder);
- }
- case Fixed, Current -> {
- fixArima(currentSpec, builder);
- fixVariables(currentSpec.getRegression(), builder, frozenDomain);
- }
- default -> {
- return currentSpec;
- }
- }
- return builder.build();
- }
-
- private void update(TransformSpec transform, GeneralLinearModel.Description rslts, ModellingSpec.Builder builder) {
- if (transform.getFunction() == TransformationType.Auto) {
- TransformSpec ntransform = transform.toBuilder()
- .function(rslts.isLogTransformation() ? TransformationType.Log : TransformationType.None)
- .adjust(rslts.getLengthOfPeriodTransformation())
- .build();
- builder.transform(ntransform);
- }
- }
-
- private void update(GeneralLinearModel.Description rslts, ModellingSpec.Builder builder) {
- SarimaSpec nspec = rslts.getStochasticComponent();
- builder.arima(nspec);
- }
-
- private void update(OutlierSpec outliers, ModellingSpec.Builder builder) {
- if (outliers.isUsed()) { // Disable outliers
- builder.outliers(
- outliers.toBuilder()
- .ao(false)
- .ls(false)
- .tc(false)
- .so(false)
- .build());
- }
- }
-
- private void update(RegressionSpec regression, GeneralLinearModel.Description rslts, ModellingSpec.Builder builder) {
- // The huge part.
- RegressionSpec.Builder rbuilder = regression.toBuilder();
- // all the coefficients (fixed or free) of the variables have already been filled
- Variable[] variables = rslts.getVariables();
- updateMean(variables, rbuilder);
- update(regression.getCalendar(), variables, rbuilder);
- updateOutliers(variables, rbuilder);
- updateUserVariables(variables, rbuilder);
- builder.regression(rbuilder.build());
- }
-
- private void updateMean(Variable[] vars, RegressionSpec.Builder builder) {
- Optional fc = Arrays.stream(vars)
- .filter(v -> v.getName().equals(TrendConstant.NAME)).findFirst();
- builder.checkMu(false);
- if (fc.isPresent()) {
- builder.mean(fc.orElseThrow().getCoefficient(0));
- } else {
- builder.mean(null);
- }
- }
-
- private void updateOutliers(Variable[] vars, RegressionSpec.Builder builder) {
- builder.clearOutliers();
- Arrays.stream(vars)
- .filter(v -> ModellingUtility.isOutlier(v))
- .forEach(v -> builder.outlier(v.removeAttribute(ModellingUtility.AMI)));
- }
-
- private void updateUserVariables(Variable[] vars, RegressionSpec.Builder builder) {
-
- builder.clearInterventionVariables();
- Arrays.stream(vars)
- .filter(v -> v.getCore() instanceof InterventionVariable)
- .forEach(v -> builder.interventionVariable(v));
- builder.clearRamps();
- Arrays.stream(vars)
- .filter(v -> v.getCore() instanceof Ramp)
- .forEach(v -> builder.ramp(v));
- builder.clearUserDefinedVariables();
- Arrays.stream(vars)
- .filter(v -> ModellingUtility.isUser(v))
- .filter(v -> !(v.getCore() instanceof InterventionVariable))
- .filter(v -> !(v.getCore() instanceof Ramp))
- .map(v -> v.withCore(TsContextVariable.of(v.getCore())))
- .forEach(v -> builder.userDefinedVariable(v));
- }
-
- private void update(CalendarSpec cspec, Variable[] variables, RegressionSpec.Builder builder) {
- CalendarSpec.Builder cbuilder = CalendarSpec.builder();
- update(cspec.getTradingDays(), variables, cbuilder);
- update(cspec.getEaster(), variables, cbuilder);
- builder.calendar(cbuilder.build());
- }
-
- private void update(TradingDaysSpec tdspec, Variable[] vars, CalendarSpec.Builder builder) {
- // leap year
- Optional flp = Arrays.stream(vars)
- .filter(v -> ModellingUtility.isLengthOfPeriod(v)).findFirst();
- Optional ftd = Arrays.stream(vars)
- .filter(v -> ModellingUtility.isTradingDays(v)).findFirst();
-
- TradingDaysSpec ntdspec = TradingDaysSpec.none();
-
- LengthOfPeriodType lp = LengthOfPeriodType.None;
- Parameter clp = null;
- if (flp.isPresent()) {
- Variable v = flp.orElseThrow();
- lp = tdspec.getLengthOfPeriodType();
- clp = v.getCoefficient(0);
- }
- TradingDaysType td = TradingDaysType.NONE;
- Parameter[] ctd = null;
- if (ftd.isPresent()) {
- Variable v = ftd.orElseThrow();
- if (tdspec.isAutomatic()) {
- ITradingDaysVariable tdv = (ITradingDaysVariable) v.getCore();
- td = tdv.getTradingDaysType();
- } else {
- td = tdspec.getTradingDaysType();
- }
- ctd = v.getCoefficients();
- }
-
- if (ftd.isPresent() || flp.isPresent()) {
- if (tdspec.isStockTradingDays()) {
- int ntd = tdspec.getStockTradingDays();
- ntdspec = TradingDaysSpec.stockTradingDays(ntd, ctd);
- } else if (tdspec.isHolidays()) {
- ntdspec = TradingDaysSpec.holidays(tdspec.getHolidays(),
- td, lp, ctd, clp);
- } else if (tdspec.isUserDefined()) {
- ntdspec = TradingDaysSpec.userDefined(tdspec.getUserVariables(), ctd);
- } else { //normal case
- ntdspec = TradingDaysSpec.td(td, lp, ctd, clp);
- }
- }
- builder.tradingDays(ntdspec);
- }
-
- private void update(EasterSpec espec, Variable[] vars, CalendarSpec.Builder builder) {
- // Search for an optional easter variable
- Optional fe = Arrays.stream(vars)
- .filter(v -> ModellingUtility.isEaster(v)).findFirst();
- if (fe.isPresent()) {
- Variable ev = fe.orElseThrow();
- EasterVariable evar = (EasterVariable) ev.getCore();
- espec = espec.toBuilder()
- .test(false)
- .duration(evar.getDuration())
- .coefficient(ev.getCoefficient(0))
- .build();
- } else {
- espec = EasterSpec.none();
- }
- builder.easter(espec);
- }
-
- private void resetArima(ModellingSpec domainSpec, ModellingSpec.Builder builder) {
- builder.arima(domainSpec.getArima());
- }
-
- private RegressionSpec removeOutliers(ModellingSpec currentSpec, ModellingSpec domainSpec, ModellingSpec.Builder builder, TsDomain frozen) {
- OutlierSpec ospec = domainSpec.getOutliers();
- if (frozen != null) {
- ospec = ospec.toBuilder().span(TimeSelector.from(frozen.getEndPeriod().start())).build();
- }
- builder.outliers(ospec);
-
- // remove existing automatic outliers...
- List> outliers = currentSpec.getRegression().getOutliers();
- List> defoutliers = domainSpec.getRegression().getOutliers();
-
- RegressionSpec.Builder rbuilder = currentSpec.getRegression().toBuilder()
- .clearOutliers();
- // use frozen outliers and outliers specified in the domain spec (avoid doubles)
- defoutliers.forEach(outlier -> {
- rbuilder.outlier(outlier);
- });
-
- outliers.stream()
- .filter(outlier -> !belongsTo(outlier, defoutliers))
- .filter(outlier -> (frozen != null && frozen.contains(outlier.getCore().getPosition())))
- .forEachOrdered(outlier -> {
- rbuilder.outlier(outlier);
- });
- return rbuilder.build();
- }
-
- private static boolean belongsTo(Variable outlier, List> defoutliers) {
- return defoutliers.stream()
- .filter(o -> o.getCore().getCode().equals(outlier.getCore().getCode()))
- .anyMatch(o -> o.getCore().getPosition().equals(outlier.getCore().getPosition()));
- }
-
- private void freeArima(ModellingSpec currentSpec, ModellingSpec domainSpec, ModellingSpec.Builder builder) {
- builder.arima(currentSpec.getArima().freeParameters(domainSpec.getArima()));
- }
-
- private void clearArima(ModellingSpec currentSpec, ModellingSpec domainSpec, ModellingSpec.Builder builder) {
- builder.arima(currentSpec.getArima().resetParameters(domainSpec.getArima()));
- }
-
- private void fixAR(ModellingSpec currentSpec, ModellingSpec domainSpec, ModellingSpec.Builder builder) {
- SarimaSpec arima = currentSpec.getArima();
- Parameter[] phi = Parameter.fixParameters(arima.getPhi());
- Parameter[] bphi = Parameter.fixParameters(arima.getBphi());
- SarimaSpec.Builder abuilder = arima.toBuilder()
- .phi(phi)
- .bphi(bphi);
-
- SarimaSpec refarima = domainSpec.getArima();
- abuilder.theta(Parameter.freeParameters(arima.getTheta(), refarima.getTheta()))
- .btheta(Parameter.freeParameters(arima.getTheta(), refarima.getBtheta()));
- builder.arima(abuilder.build());
- }
-
- private void fixArima(ModellingSpec currentSpec, ModellingSpec.Builder builder) {
- builder.arima(currentSpec.getArima().fixParameters());
- }
-
- private void freeVariables(RegressionSpec reg, ModellingSpec domainSpec, ModellingSpec.Builder builder) {
- RegressionSpec dreg = domainSpec.getRegression();
- RegressionSpec.Builder rbuilder = reg.toBuilder();
- Parameter mean = reg.getMean();
- if (mean != null && mean.isFixed()) {
- Parameter dc = dreg.getMean();
- if (dc == null || !dc.isFixed()) {
- mean = Parameter.initial(mean.getValue());
- }
- }
-
- List> iv = reg.getInterventionVariables();
- List> niv = new ArrayList<>();
- iv.forEach(v -> {
- niv.add(v.withCoefficients(freeCoefficients(v, dreg.getInterventionVariables())));
- });
-
- List> o = reg.getOutliers();
- List> no = new ArrayList<>();
- o.forEach(v -> {
- no.add(v.withCoefficients(freeCoefficients(v, dreg.getOutliers())));
- });
-
- List> r = reg.getRamps();
- List> nr = new ArrayList<>();
- r.forEach(v -> {
- nr.add(v.withCoefficients(freeCoefficients(v, dreg.getRamps())));
- });
-
- List> u = reg.getUserDefinedVariables();
- List> nu = new ArrayList<>();
- u.forEach(v -> {
- nu.add(v.withCoefficients(freeCoefficients(v, dreg.getUserDefinedVariables())));
- });
-
- EasterSpec easter = reg.getCalendar().getEaster();
- Parameter c = easter.getCoefficient();
- if (c != null && c.isFixed()) {
- Parameter dc = dreg.getCalendar().getEaster().getCoefficient();
- if (dc == null || !dc.isFixed()) {
- c = Parameter.initial(c.getValue());
- easter = easter.toBuilder()
- .coefficient(c)
- .build();
- }
- }
- TradingDaysSpec td = reg.getCalendar().getTradingDays();
- c = td.getLpCoefficient();
- Parameter[] tdc = td.getTdCoefficients();
- if (c != null || tdc != null) {
- if (c != null && c.isFixed()) {
- Parameter dc = dreg.getCalendar().getTradingDays().getLpCoefficient();
- if (dc == null || !dc.isFixed()) {
- c = Parameter.initial(c.getValue());
- }
- }
- tdc = Parameter.freeParameters(tdc, dreg.getCalendar().getTradingDays().getTdCoefficients());
- td = td.withCoefficients(tdc, c);
- }
-
- builder.regression(rbuilder
- .mean(mean)
- .clearInterventionVariables().interventionVariables(niv)
- .clearOutliers().outliers(no)
- .clearRamps().ramps(nr)
- .clearUserDefinedVariables().userDefinedVariables(nu)
- .calendar(CalendarSpec.builder()
- .easter(easter)
- .tradingDays(td)
- .build())
- .build());
- }
-
- private static Parameter[] freeCoefficients(Variable var, List> ref) {
- Parameter[] c = var.getCoefficients();
- if (c == null) {
- return null;
- }
- Optional> rvar = ref.stream().filter(v -> v.getName().equals(var.getName())).findFirst();
- if (rvar.isPresent()) {
- return Parameter.freeParameters(c, rvar.orElseThrow().getCoefficients());
- } else {
- return Parameter.freeParameters(c);
- }
- }
-
- private static Map ao_attributes() {
- HashMap attributes = new HashMap<>();
- attributes.put(ModellingUtility.AMI, "demetra");
- attributes.put(SaVariable.REGEFFECT, ComponentType.Irregular.name());
- return attributes;
- }
-
- private static final Map IV_AO = ao_attributes();
-
- private void fixVariables(RegressionSpec reg, ModellingSpec.Builder builder, TsDomain frozenDomain) {
- RegressionSpec.Builder rbuilder = reg.toBuilder();
- Parameter mean = reg.getMean();
- if (mean != null && mean.isDefined()) {
- mean = Parameter.fixed(mean.getValue());
- }
-
- List> iv = reg.getInterventionVariables();
- List> niv = new ArrayList<>();
- iv.forEach(v -> {
- String n = v.getName();
- if (!n.startsWith(EstimationPolicyType.IV_AO)) {
- niv.add(v.withCoefficients(Parameter.fixParameters(v.getCoefficients())));
- } else {
- niv.add(v);
- }
- });
- if (frozenDomain != null) {
- // Current AO: Add IV (ao for the frozen period)
- for (int i = 0; i < frozenDomain.getLength(); ++i) {
- TsPeriod period = frozenDomain.get(i);
- LocalDateTime day = period.start();
- InterventionVariable ao = InterventionVariable.builder()
- .sequence(Range.of(day, day))
- .build();
- niv.add(Variable.builder()
- .name(EstimationPolicyType.IV_AO + period.display())
- .attributes(IV_AO)
- .core(ao)
- .build());
- }
- }
-
- List> o = reg.getOutliers();
- List> no = new ArrayList<>();
- o.forEach(v -> {
- no.add(v.withCoefficients(Parameter.fixParameters(v.getCoefficients())));
- });
-
- List> r = reg.getRamps();
- List> nr = new ArrayList<>();
- r.forEach(v -> {
- nr.add(v.withCoefficients(Parameter.fixParameters(v.getCoefficients())));
- });
-
- List> u = reg.getUserDefinedVariables();
- List> nu = new ArrayList<>();
- u.forEach(v -> {
- nu.add(v.withCoefficients(Parameter.fixParameters(v.getCoefficients())));
- });
-
- EasterSpec easter = reg.getCalendar().getEaster();
- Parameter c = easter.getCoefficient();
- if (c != null) {
- easter = easter.toBuilder()
- .coefficient(Parameter.fixed(c.getValue()))
- .build();
- }
- TradingDaysSpec td = reg.getCalendar().getTradingDays();
- c = td.getLpCoefficient();
- Parameter[] tdc = td.getTdCoefficients();
- if (c != null || tdc != null) {
- td = td.withCoefficients(Parameter.fixParameters(tdc), c == null ? null : Parameter.fixed(c.getValue()));
- }
-
- builder.regression(rbuilder
- .mean(mean)
- .clearInterventionVariables().interventionVariables(niv)
- .clearOutliers().outliers(no)
- .clearRamps().ramps(nr)
- .clearUserDefinedVariables().userDefinedVariables(nu)
- .calendar(CalendarSpec.builder()
- .easter(easter)
- .tradingDays(td)
- .build())
- .build());
-
- }
-
-}
diff --git a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-core/src/main/java/jdplus/sa/base/core/regarima/ModelBuilder.java b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-core/src/main/java/jdplus/sa/base/core/regarima/ModelBuilder.java
index 12d08d66..20dfac81 100644
--- a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-core/src/main/java/jdplus/sa/base/core/regarima/ModelBuilder.java
+++ b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-core/src/main/java/jdplus/sa/base/core/regarima/ModelBuilder.java
@@ -323,7 +323,7 @@ public static ITradingDaysVariable tradingDays(ModellingSpec spec, ModellingCont
}
}
- static ITradingDaysVariable td(ModellingSpec spec, DayClustering dc, ModellingContext context) {
+ public static ITradingDaysVariable td(ModellingSpec spec, DayClustering dc, ModellingContext context) {
TradingDaysSpec tdspec = spec.getRegression().getCalendar().getTradingDays();
if (!tdspec.isUsed()) {
return null;
@@ -332,7 +332,6 @@ static ITradingDaysVariable td(ModellingSpec spec, DayClustering dc, ModellingCo
return null;
} else if (tdspec.getHolidays() != null) {
GenericTradingDays gtd = GenericTradingDays.contrasts(dc);
-
HolidaysCorrectedTradingDays.HolidaysCorrector corrector = HolidaysCorrectionFactory.corrector(tdspec.getHolidays(), context.getCalendars(), DayOfWeek.SUNDAY);
return HolidaysCorrectedTradingDays.builder().corrector(corrector).clustering(gtd.getClustering()).build();
} else if (tdspec.getUserVariables() != null) {
@@ -387,18 +386,15 @@ public static ILengthOfPeriodVariable leapYear(TradingDaysSpec tdspec) {
}
public static IEasterVariable easter(EasterSpec.Type type, int w) {
- switch (type) {
- case JULIANEASTER:
- return new JulianEasterVariable(w, true);
- case EASTER:
- return EasterVariable.builder()
- .duration(w)
- .meanCorrection(EasterVariable.Correction.Simple)
- .endPosition(-1)
- .build();
- default:
- return null;
- }
+ return switch (type) {
+ case JULIANEASTER -> new JulianEasterVariable(w, true);
+ case EASTER -> EasterVariable.builder()
+ .duration(w)
+ .meanCorrection(EasterVariable.Correction.Simple)
+ .endPosition(-1)
+ .build();
+ default -> null;
+ };
}
public static IEasterVariable easter(ModellingSpec spec) {
EasterSpec espec = spec.getRegression().getCalendar().getEaster();
diff --git a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-core/src/main/java/jdplus/sa/base/core/regarima/ModelEstimator.java b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-core/src/main/java/jdplus/sa/base/core/regarima/ModelEstimator.java
deleted file mode 100644
index 8e485c5f..00000000
--- a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-core/src/main/java/jdplus/sa/base/core/regarima/ModelEstimator.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright 2022 National Bank of Belgium
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved
- * by the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- */
-package jdplus.sa.base.core.regarima;
-
-import jdplus.toolkit.base.core.math.functions.levmar.LevenbergMarquardtMinimizer;
-import jdplus.toolkit.base.core.regsarima.RegSarimaComputer;
-import jdplus.toolkit.base.core.regsarima.regular.IModelEstimator;
-import jdplus.toolkit.base.core.regsarima.regular.RegSarimaModelling;
-import nbbrd.design.BuilderPattern;
-import nbbrd.design.Development;
-
-/**
- *
- * @author palatej
- */
-@Development(status = Development.Status.Preliminary)
-public class ModelEstimator implements IModelEstimator {
-
- public static Builder builder() {
- return new Builder();
- }
-
- @BuilderPattern(ModelEstimator.class)
- public static class Builder {
-
- private double epsilon = .00001;
- private RegSarimaComputer.StartingPoint starting = RegSarimaComputer.StartingPoint.Multiple;
- private boolean exactDerivatives = true;
-
- public Builder precision(double precision) {
- this.epsilon = precision;
- return this;
- }
-
- public Builder exactDerivatives(boolean exactDerivatives) {
- this.exactDerivatives = exactDerivatives;
- return this;
- }
-
- public Builder startingPoint(RegSarimaComputer.StartingPoint starting) {
- this.starting = starting;
- return this;
- }
-
- public ModelEstimator build() {
- return new ModelEstimator(epsilon, starting, exactDerivatives);
- }
-
- }
- private final double eps;
- private final RegSarimaComputer.StartingPoint starting;
- private final boolean exactDerivatives;
-
- private ModelEstimator(double eps, RegSarimaComputer.StartingPoint starting, boolean exactDerivatives) {
- this.eps = eps;
- this.starting = starting;
- this.exactDerivatives = exactDerivatives;
- }
-
- @Override
- public boolean estimate(RegSarimaModelling context) {
-
- try {
- RegSarimaComputer processor = RegSarimaComputer.builder()
- .minimizer(LevenbergMarquardtMinimizer.builder())
- .precision(eps)
- .startingPoint(starting)
- .computeExactFinalDerivatives(exactDerivatives)
- .build();
- context.getDescription().freeArimaParameters();
- context.estimate(processor);
- return true;
- } catch (RuntimeException err) {
- return false;
- }
- }
-}
diff --git a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-core/src/main/java/jdplus/sa/base/core/regarima/SpecDecoder.java b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-core/src/main/java/jdplus/sa/base/core/regarima/SpecDecoder.java
deleted file mode 100644
index 5e84ae4c..00000000
--- a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-core/src/main/java/jdplus/sa/base/core/regarima/SpecDecoder.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright 2019 National Bank of Belgium
- *
- * Licensed under the EUPL, Version 1.1 or – as soon they will be approved
- * by the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * http://ec.europa.eu/idabc/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- */
-package jdplus.sa.base.core.regarima;
-
-import jdplus.toolkit.base.api.modelling.TransformationType;
-import jdplus.toolkit.base.api.modelling.regular.EasterSpec;
-import jdplus.toolkit.base.api.modelling.regular.ModellingSpec;
-import jdplus.toolkit.base.api.modelling.regular.OutlierSpec;
-import jdplus.toolkit.base.api.modelling.regular.TradingDaysSpec;
-import jdplus.toolkit.base.api.modelling.regular.TransformSpec;
-import jdplus.toolkit.base.api.timeseries.regression.ModellingContext;
-import jdplus.toolkit.base.core.regarima.AICcComparator;
-import jdplus.toolkit.base.core.regsarima.regular.RegressionVariablesTest;
-import jdplus.toolkit.base.api.timeseries.calendars.LengthOfPeriodType;
-import org.checkerframework.checker.nullness.qual.NonNull;
-import jdplus.toolkit.base.api.timeseries.regression.IEasterVariable;
-import jdplus.toolkit.base.api.timeseries.calendars.DayClustering;
-import jdplus.toolkit.base.api.timeseries.regression.ITradingDaysVariable;
-
-/**
- * The Tramo processing builder initializes the regarima processing, which
- * contains the initial model and the possible AMI modules. It starts from a
- * time series and from a Tramo specification. In a first step, we create the
- * initial model. In a second step, we define the processor itself
- *
- * @author Jean Palate
- */
-final class SpecDecoder {
-
- private final FastKernel.Builder builder = FastKernel.builder();
-
- SpecDecoder(@NonNull ModellingSpec spec, ModellingContext context) {
- if (context == null) {
- context = ModellingContext.getActiveContext();
- }
-
- readTransformation(spec);
- readOutliers(spec);
- builder.modelBuilder(new ModelBuilder(spec, context));
- readRegression(spec, context);
- readAmiOptions(spec);
- }
-
- FastKernel buildProcessor() {
- return builder.build();
- }
-
- private void readTransformation(final ModellingSpec spec) {
- TransformSpec tspec = spec.getTransform();
- TradingDaysSpec tdspec = spec.getRegression().getCalendar().getTradingDays();
- if (tspec.getFunction() == TransformationType.Auto) {
- builder.logLevel(LogLevelModule.builder()
- .aiccLogCorrection(tspec.getAicDiff())
- .estimationPrecision(spec.getEstimate().getIntermediatePrecision())
- .preadjust(tdspec.isAutoAdjust() ? tdspec.getLengthOfPeriodType() : LengthOfPeriodType.None)
- .outliersCorrection(tspec.isOutliersCorrection())
- .build());
- }
- }
-
- private void readOutliers(final ModellingSpec spec) {
- OutlierSpec outliers = spec.getOutliers();
- if (!outliers.isUsed()) {
- return;
- }
- OutliersDetectionModule module = OutliersDetectionModule.builder()
- .ao(outliers.isAo())
- .ls(outliers.isLs())
- .tc(outliers.isTc())
- .so(outliers.isSo())
- .span(outliers.getSpan())
- .tcrate(outliers.getDeltaTC())
- .precision(spec.getEstimate().getIntermediatePrecision())
- .build();
- builder.outliers(module);
- }
-
- private ITradingDaysVariable[] nestedtd(final ModellingSpec spec, ModellingContext context) {
- return new ITradingDaysVariable[]{
- ModelBuilder.td(spec, DayClustering.TD2, context),
- ModelBuilder.td(spec, DayClustering.TD3, context),
- ModelBuilder.td(spec, DayClustering.TD4, context),
- ModelBuilder.td(spec, DayClustering.TD7, context)
- };
- }
-
- private ITradingDaysVariable[] alltd(final ModellingSpec spec, ModellingContext context) {
- return new ITradingDaysVariable[]{
- ModelBuilder.td(spec, DayClustering.TD2c, context),
- ModelBuilder.td(spec, DayClustering.TD2, context),
- ModelBuilder.td(spec, DayClustering.TD3, context),
- ModelBuilder.td(spec, DayClustering.TD3c, context),
- ModelBuilder.td(spec, DayClustering.TD4, context),
- ModelBuilder.td(spec, DayClustering.TD7, context)
- };
- }
-
- private void readRegression(final ModellingSpec spec, ModellingContext context) {
- TradingDaysSpec tdspec = spec.getRegression().getCalendar().getTradingDays();
- AICcComparator comparator = new AICcComparator(spec.getRegression().getAicDiff());
- if (tdspec.isAutomatic()) {
- switch (tdspec.getAutomaticMethod()) {
- case AIC:
- builder.calendarTest(AutomaticTradingDaysRegressionTest.builder()
- .leapYear(ModelBuilder.leapYear(tdspec))
- .tradingDays(alltd(spec, context))
- .adjust(tdspec.isAutoAdjust())
- .aic()
- .estimationPrecision(spec.getEstimate().getIntermediatePrecision())
- .build());
- break;
- case BIC:
- builder.calendarTest(AutomaticTradingDaysRegressionTest.builder()
- .leapYear(ModelBuilder.leapYear(tdspec))
- .tradingDays(alltd(spec, context))
- .adjust(tdspec.isAutoAdjust())
- .estimationPrecision(spec.getEstimate().getIntermediatePrecision())
- .bic()
- .build());
- break;
- case WALD:
- builder.calendarTest(AutomaticTradingDaysWaldTest.builder()
- .leapYear(ModelBuilder.leapYear(tdspec))
- .tradingDays(nestedtd(spec, context))
- .adjust(tdspec.isAutoAdjust())
- .estimationPrecision(spec.getEstimate().getIntermediatePrecision())
- .build());
- break;
-
- }
- } else if (tdspec.isTest()) {
- CalendarEffectsDetectionModule cal = CalendarEffectsDetectionModule.builder()
- .tradingDays(ModelBuilder.tradingDays(spec, context))
- .leapYear(ModelBuilder.leapYear(tdspec))
- .adjust(tdspec.isAutoAdjust() ? tdspec.getLengthOfPeriodType() : LengthOfPeriodType.None)
- .modelComparator(comparator)
- .build();
- builder.calendarTest(cal);
- }
- EasterSpec espec = spec.getRegression().getCalendar().getEaster();
- if (espec.getType() != EasterSpec.Type.UNUSED && espec.isTest()) {
- int[] w = new int[]{espec.getDuration()};
- IEasterVariable[] easters = new IEasterVariable[w.length];
- for (int i = 0; i < easters.length; ++i) {
- easters[i] = ModelBuilder.easter(espec.getType(), w[i]);
- }
- EasterDetectionModule e = EasterDetectionModule.builder()
- .easters(easters)
- .modelComparator(comparator)
- .build();
- builder.easterTest(e);
- }
-
- RegressionVariablesTest.Builder rbuilder = RegressionVariablesTest.builder();
- if (tdspec.isTest()) {
- rbuilder.tdTest(RegressionVariablesTest.CVAL, true);
- }
- if (espec.getType() != EasterSpec.Type.UNUSED && espec.isTest()) {
- rbuilder.movingHolidaysTest(RegressionVariablesTest.CVAL);
- }
- builder.initialRegressionTest(rbuilder.build());
- builder.finalRegressionTest(rbuilder.build());
- }
-
- private void readAmiOptions(ModellingSpec spec) {
- builder.options(
- FastKernel.AmiOptions.builder()
- .precision(spec.getEstimate().getPrecision())
- .intermediatePrecision(spec.getEstimate().getIntermediatePrecision())
- .va(spec.getOutliers().getCriticalValue())
- .checkMu(spec.getRegression().isCheckMu())
- .build());
-
- }
-
-}
diff --git a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-core/src/test/java/jdplus/sa/base/core/regarima/Converter.java b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-core/src/test/java/jdplus/sa/base/core/regarima/Converter.java
deleted file mode 100644
index 746dc4dc..00000000
--- a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-core/src/test/java/jdplus/sa/base/core/regarima/Converter.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package jdplus.sa.base.core.regarima;
-
-import jdplus.toolkit.base.api.timeseries.TsData;
-
-/**
- *
- * @author palatej
- */
-class Converter {
- static ec.tstoolkit.timeseries.simplets.TsData convert(TsData s) {
- int period = s.getAnnualFrequency();
- int year = s.getStart().year(), pos = s.getStart().annualPosition();
- return new ec.tstoolkit.timeseries.simplets.TsData(ec.tstoolkit.timeseries.simplets.TsFrequency.valueOf(period),
- year, pos, s.getValues().toArray(), false);
- }
-
-}
diff --git a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-core/src/test/java/jdplus/sa/base/core/regarima/FastKernelTest.java b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-core/src/test/java/jdplus/sa/base/core/regarima/FastKernelTest.java
deleted file mode 100644
index 6e60fa62..00000000
--- a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-core/src/test/java/jdplus/sa/base/core/regarima/FastKernelTest.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright 2022 National Bank of Belgium
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved
- * by the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- */
-package jdplus.sa.base.core.regarima;
-
-import tck.demetra.data.Data;
-import jdplus.toolkit.base.api.modelling.regular.CalendarSpec;
-import jdplus.toolkit.base.api.modelling.regular.EasterSpec;
-import jdplus.toolkit.base.api.modelling.regular.ModellingSpec;
-import jdplus.toolkit.base.api.modelling.regular.RegressionSpec;
-import jdplus.toolkit.base.api.modelling.regular.TradingDaysSpec;
-import jdplus.toolkit.base.api.timeseries.calendars.LengthOfPeriodType;
-import jdplus.toolkit.base.api.timeseries.calendars.TradingDaysType;
-import jdplus.toolkit.base.core.regsarima.regular.RegSarimaModel;
-import org.junit.Test;
-import static org.junit.Assert.*;
-
-/**
- *
- * @author palatej
- */
-public class FastKernelTest {
-
- public FastKernelTest() {
- }
-
- @Test
- public void testProd() {
- ModellingSpec spec = ModellingSpec.FULL;
- FastKernel kernel = FastKernel.of(spec, null);
- RegSarimaModel rslt = kernel.process(Data.TS_PROD, null);
- assertTrue(rslt != null);
- }
-
- public static void main(String[] args) {
- ModellingSpec spec=ModellingSpec.FULL;
- TradingDaysSpec tradingDays = TradingDaysSpec
- .td(TradingDaysType.TD2, LengthOfPeriodType.LeapYear, true, true);
- //.automatic(LengthOfPeriodType.LeapYear, TradingDaysSpec.AutoMethod.BIC, 0.01, true);
-
- CalendarSpec cspec=CalendarSpec.builder()
- .easter(EasterSpec.DEFAULT_USED)
- .tradingDays(tradingDays)
- .build();
- RegressionSpec rspec=RegressionSpec.builder()
- .checkMu(true)
- .calendar(cspec)
- .build();
-
- spec=spec.toBuilder().regression(rspec)
- .build();
-
- long t0 = System.currentTimeMillis();
- for (int i = 0; i < 1000; ++i) {
- FastKernel kernel = FastKernel.of(spec, null);
- RegSarimaModel rslt = kernel.process(Data.TS_ABS_RETAIL, null);
- }
- long t1 = System.currentTimeMillis();
- System.out.println(t1 - t0);
- }
-
-}
diff --git a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-core/src/test/java/jdplus/sa/base/core/regarima/LogLevelModuleTest.java b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-core/src/test/java/jdplus/sa/base/core/regarima/LogLevelModuleTest.java
deleted file mode 100644
index f28df9a9..00000000
--- a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-core/src/test/java/jdplus/sa/base/core/regarima/LogLevelModuleTest.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Copyright 2017 National Bank of Belgium
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved
- * by the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- */
-package jdplus.sa.base.core.regarima;
-
-import tck.demetra.data.Data;
-import jdplus.sa.base.api.ComponentType;
-import jdplus.sa.base.api.SaVariable;
-import jdplus.toolkit.base.api.timeseries.TsData;
-import jdplus.toolkit.base.api.timeseries.calendars.DayClustering;
-import jdplus.toolkit.base.api.timeseries.calendars.GenericTradingDays;
-import jdplus.toolkit.base.api.timeseries.calendars.LengthOfPeriodType;
-import jdplus.toolkit.base.api.timeseries.regression.GenericTradingDaysVariable;
-import jdplus.toolkit.base.api.timeseries.regression.LengthOfPeriod;
-import jdplus.toolkit.base.api.timeseries.regression.Variable;
-import ec.tstoolkit.modelling.DefaultTransformationType;
-import ec.tstoolkit.modelling.RegStatus;
-import ec.tstoolkit.modelling.arima.PreadjustmentType;
-import ec.tstoolkit.timeseries.calendars.TradingDaysType;
-import jdplus.toolkit.base.core.regsarima.regular.ModelDescription;
-import jdplus.toolkit.base.core.regsarima.regular.RegSarimaModelling;
-import org.junit.jupiter.api.Test;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-/**
- *
- * @author Jean Palate
- */
-public class LogLevelModuleTest {
-
- public LogLevelModuleTest() {
- }
-
- @Test
- public void testNoAdjust() {
- TsData[] insee = Data.insee();
- for (int i = 0; i < insee.length; ++i) {
- LogLevelModule ll = LogLevelModule.builder()
- .preadjust(LengthOfPeriodType.None)
- .estimationPrecision(1e-5)
- .aiccLogCorrection(-2)
- .build();
- ModelDescription model = new ModelDescription(insee[i], null);
- model.setAirline(true);
- RegSarimaModelling m = RegSarimaModelling.of(model);
- ll.process(m);
- boolean log = m.getDescription().isLogTransformation();
- ec.tstoolkit.modelling.arima.x13.LogLevelTest oll = new ec.tstoolkit.modelling.arima.x13.LogLevelTest();
- ec.tstoolkit.timeseries.simplets.TsData s = Converter.convert(insee[i]);
- ec.tstoolkit.modelling.arima.ModelDescription desc = new ec.tstoolkit.modelling.arima.ModelDescription(s, null);
- ec.tstoolkit.modelling.arima.ModellingContext context = new ec.tstoolkit.modelling.arima.ModellingContext();
- desc.setTransformation(DefaultTransformationType.Auto);
- desc.setAirline(true);
- context.description = desc;
- context.hasseas = true;
- oll.process(context);
- boolean olog = oll.isChoosingLog();
- assertEquals(ll.getAICcLevel(), oll.getLevel().getStatistics().AICC, 1e-1);
- assertEquals(ll.getAICcLog(), oll.getLog().getStatistics().AICC, 1e-1);
- assertTrue(log == olog);
- }
- }
-
- @Test
- public void testAdjust() {
- TsData[] insee = Data.insee();
- for (int i = 0; i < insee.length; ++i) {
- LogLevelModule ll = LogLevelModule.builder()
- .preadjust(LengthOfPeriodType.LeapYear)
- .estimationPrecision(1e-5)
- .aiccLogCorrection(-2)
- .build();
- ModelDescription model = new ModelDescription(insee[i], null);
- model.setAirline(true);
- model.addVariable(Variable.builder().name("lp").core(new LengthOfPeriod(LengthOfPeriodType.LeapYear)).build());
- model.addVariable(Variable.builder().name("td").core(new GenericTradingDaysVariable(GenericTradingDays.contrasts(DayClustering.TD7))).build());
- RegSarimaModelling m = RegSarimaModelling.of(model);
- ll.process(m);
- boolean log = m.getDescription().isLogTransformation();
- ec.tstoolkit.modelling.arima.x13.LogLevelTest oll = new ec.tstoolkit.modelling.arima.x13.LogLevelTest();
- ec.tstoolkit.timeseries.simplets.TsData s = Converter.convert(insee[i]);
- ec.tstoolkit.modelling.arima.ModelDescription desc = new ec.tstoolkit.modelling.arima.ModelDescription(s, null);
- ec.tstoolkit.modelling.arima.ModellingContext context = new ec.tstoolkit.modelling.arima.ModellingContext();
- desc.setAirline(true);
- desc.setTransformation(PreadjustmentType.Auto);
- desc.setTransformation(DefaultTransformationType.Auto);
- desc.addVariable(ec.tstoolkit.modelling.Variable.lpVariable(new ec.tstoolkit.timeseries.regression.LeapYearVariable(ec.tstoolkit.timeseries.calendars.LengthOfPeriodType.LeapYear), RegStatus.ToRemove));
- desc.addVariable(ec.tstoolkit.modelling.Variable.tdVariable(ec.tstoolkit.timeseries.regression.GregorianCalendarVariables.getDefault(TradingDaysType.TradingDays), RegStatus.ToRemove));
- context.description = desc;
- context.hasseas = true;
- oll.process(context);
- boolean olog = oll.isChoosingLog();
- assertTrue(log == olog);
- assertEquals(ll.getAICcLevel(), oll.getLevel().getStatistics().AICC, 1e-1);
- assertEquals(ll.getAICcLog(), oll.getLog().getStatistics().AICC, 1e-1);
- }
- }
-
- @Test
- public void testAdjustTD() {
- int n = 0;
- TsData[] insee = Data.insee();
- for (int i = 0; i < insee.length; ++i) {
- LogLevelModule ll = LogLevelModule.builder()
- .preadjust(LengthOfPeriodType.LeapYear)
- .estimationPrecision(1e-5)
- .aiccLogCorrection(-2)
- .build();
- ModelDescription model0 = new ModelDescription(insee[i], null);
- model0.setAirline(true);
- RegSarimaModelling m0 = RegSarimaModelling.of(model0);
- ll.process(m0);
- boolean log0 = m0.getDescription().isLogTransformation();
- ModelDescription model1 = new ModelDescription(insee[i], null);
- model1.setAirline(true);
- model1.addVariable(Variable.builder().name("lp").core(new LengthOfPeriod(LengthOfPeriodType.LeapYear)).attribute(SaVariable.REGEFFECT, ComponentType.CalendarEffect.name()).build());
- model1.addVariable(Variable.builder().name("td").core(new GenericTradingDaysVariable(GenericTradingDays.contrasts(DayClustering.TD7))).attribute(SaVariable.REGEFFECT, ComponentType.CalendarEffect.name()).build());
- RegSarimaModelling m1 = RegSarimaModelling.of(model1);
- ll.process(m1);
- boolean log1 = m1.getDescription().isLogTransformation();
- if (log0 != log1) {
- ++n;
- }
- }
- }
-
- @Test
- public void testAO() {
- TsData[] insee = Data.insee();
- for (int i = 0; i < insee.length; ++i) {
- LogLevelModule ll = LogLevelModule.builder()
- .preadjust(LengthOfPeriodType.None)
- .estimationPrecision(1e-5)
- .aiccLogCorrection(2)
- .build();
- ModelDescription model = new ModelDescription(insee[i], null);
- model.setAirline(true);
- RegSarimaModelling m = RegSarimaModelling.of(model);
- ll.process(m);
-// System.out.print(ll.isChoosingLog());
- System.out.print('\t');
-
- double[] nvals = insee[i].getValues().toArray();
- nvals[nvals.length - 3] *= 0.25;
- nvals[nvals.length - 2] *= 0.20;
- TsData s = TsData.ofInternal(insee[i].getStart(), nvals);
- model = new ModelDescription(s, null);
- model.setAirline(true);
- m = RegSarimaModelling.of(model);
- ll.process(m);
-// System.out.println(ll.isChoosingLog());
- }
- }
-}
diff --git a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-csv/pom.xml b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-csv/pom.xml
index 972508ac..b059880d 100644
--- a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-csv/pom.xml
+++ b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-csv/pom.xml
@@ -5,7 +5,7 @@
eu.europa.ec.joinup.sat
jdplus-sa-base-parent
- 3.0.2
+ 3.1.0
jdplus-sa-base-csv
diff --git a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-information/pom.xml b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-information/pom.xml
index 44bf9972..2530495b 100644
--- a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-information/pom.xml
+++ b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-information/pom.xml
@@ -5,7 +5,7 @@
eu.europa.ec.joinup.sat
jdplus-sa-base-parent
- 3.0.2
+ 3.1.0
jdplus-sa-base-information
diff --git a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-information/src/main/java/jdplus/sa/base/information/highfreq/EasterSpecMapping.java b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-information/src/main/java/jdplus/sa/base/information/highfreq/EasterSpecMapping.java
new file mode 100644
index 00000000..e28000ac
--- /dev/null
+++ b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-information/src/main/java/jdplus/sa/base/information/highfreq/EasterSpecMapping.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2020 National Bank of Belgium
+ *
+ * Licensed under the EUPL, Version 1.2 or – as soon they will be approved
+ * by the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ *
+ * https://joinup.ec.europa.eu/software/page/eupl
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ */
+package jdplus.sa.base.information.highfreq;
+
+import jdplus.toolkit.base.api.data.Parameter;
+import jdplus.toolkit.base.api.information.InformationSet;
+import jdplus.toolkit.base.api.modelling.highfreq.EasterSpec;
+
+/**
+ *
+ * @author PALATEJ
+ */
+@lombok.experimental.UtilityClass
+public class EasterSpecMapping {
+
+ final String TYPE = "type", PARAM = "param", TEST = "test", COEF = "coef";
+
+ public InformationSet write(EasterSpec spec, boolean verbose) {
+ if (!verbose && spec.isDefault()) {
+ return null;
+ }
+ InformationSet easterInfo = new InformationSet();
+ writeProperties(easterInfo, spec, verbose);
+ Parameter coef = spec.getCoefficient();
+ if (coef != null) {
+ easterInfo.set(COEF, coef);
+ }
+ return easterInfo;
+ }
+
+ private void writeProperties(InformationSet easterInfo, EasterSpec spec, boolean verbose) {
+ easterInfo.add(TYPE, spec.getType().name());
+ if (verbose || spec.getDuration() != 0) {
+ easterInfo.add(PARAM, spec.getDuration());
+ }
+ if (verbose || !spec.isTest()) {
+ easterInfo.add(TEST, spec.isTest());
+ }
+ }
+
+ public EasterSpec read(InformationSet easterInfo) {
+ if (easterInfo == null) {
+ return EasterSpec.DEFAULT_UNUSED;
+ }
+ EasterSpec.Builder builder = EasterSpec.builder();
+ readProperties(easterInfo, builder);
+ Parameter c = easterInfo.get(COEF, Parameter.class);
+ return builder.coefficient(c)
+ .build();
+ }
+
+ private void readProperties(InformationSet easterInfo, EasterSpec.Builder builder) {
+ String type = easterInfo.get(TYPE, String.class);
+ EasterSpec.Type mtype = EasterSpec.Type.UNUSED;
+ if (type != null) {
+ mtype = EasterSpec.Type.valueOf(type);
+ }
+ Integer w = easterInfo.get(PARAM, Integer.class);
+ Boolean test = easterInfo.get(TEST, Boolean.class);
+ boolean rtest = false;
+ if (test != null) {
+ rtest = test;
+ }
+
+ builder.duration(w == null ? EasterSpec.DEF_IDUR : w)
+ .type(mtype)
+ .test(rtest);
+ }
+}
diff --git a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-information/src/main/java/jdplus/sa/base/information/highfreq/EstimateSpecMapping.java b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-information/src/main/java/jdplus/sa/base/information/highfreq/EstimateSpecMapping.java
new file mode 100644
index 00000000..06086d8d
--- /dev/null
+++ b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-information/src/main/java/jdplus/sa/base/information/highfreq/EstimateSpecMapping.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2020 National Bank of Belgium
+ *
+ * Licensed under the EUPL, Version 1.2 or – as soon they will be approved
+ * by the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ *
+ * https://joinup.ec.europa.eu/software/page/eupl
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ */
+package jdplus.sa.base.information.highfreq;
+
+import jdplus.toolkit.base.api.information.InformationSet;
+import jdplus.toolkit.base.api.modelling.highfreq.EstimateSpec;
+import jdplus.toolkit.base.api.timeseries.TimeSelector;
+
+/**
+ *
+ * @author PALATEJ
+ */
+@lombok.experimental.UtilityClass
+public class EstimateSpecMapping {
+
+ final String SPAN = "span",
+ TOL = "tol", HESSIAN ="hessian";
+
+ public InformationSet write(EstimateSpec spec, boolean verbose) {
+ if (!verbose && spec.isDefault()) {
+ return null;
+ }
+ InformationSet info = new InformationSet();
+ if (verbose || spec.getSpan().getType() != TimeSelector.SelectionType.All) {
+ info.set(SPAN, spec.getSpan());
+ }
+ if (verbose || spec.getPrecision() != EstimateSpec.EPS) {
+ info.set(TOL, spec.getPrecision());
+ }
+ if (verbose || !spec.isApproximateHessian()){
+ info.set(HESSIAN, spec.isApproximateHessian());
+ }
+ return info;
+ }
+
+ public EstimateSpec read(InformationSet info) {
+ if (info == null) {
+ return EstimateSpec.DEFAULT;
+ }
+
+ EstimateSpec.Builder builder = EstimateSpec.builder();
+
+ TimeSelector span = info.get(SPAN, TimeSelector.class);
+ if (span != null) {
+ builder.span(span);
+ }
+ Double tol = info.get(TOL, Double.class);
+ if (tol != null) {
+ builder.precision(tol);
+ }
+ Boolean hessian = info.get(HESSIAN, Boolean.class);
+ if (hessian != null) {
+ builder.approximateHessian(hessian);
+ }
+
+ return builder.build();
+ }
+}
diff --git a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-information/src/main/java/jdplus/sa/base/information/highfreq/HolidaysSpecMapping.java b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-information/src/main/java/jdplus/sa/base/information/highfreq/HolidaysSpecMapping.java
new file mode 100644
index 00000000..a28f744c
--- /dev/null
+++ b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-information/src/main/java/jdplus/sa/base/information/highfreq/HolidaysSpecMapping.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2020 National Bank of Belgium
+ *
+ * Licensed under the EUPL, Version 1.2 or – as soon they will be approved
+ * by the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ *
+ * https://joinup.ec.europa.eu/software/page/eupl
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ */
+package jdplus.sa.base.information.highfreq;
+
+import java.util.Arrays;
+import jdplus.toolkit.base.api.data.Parameter;
+import jdplus.toolkit.base.api.information.InformationSet;
+import jdplus.toolkit.base.api.modelling.highfreq.HolidaysSpec;
+import jdplus.toolkit.base.api.timeseries.calendars.HolidaysOption;
+import jdplus.toolkit.base.api.timeseries.regression.HolidaysVariable;
+
+/**
+ *
+ * @author PALATEJ
+ */
+@lombok.experimental.UtilityClass
+public class HolidaysSpecMapping {
+
+ final String HOLIDAYS = "holidays", OPTION = "option",
+ SINGLE = "single", NONWORKING = "nonworking", TEST = "test",
+ COEF = "coef";
+
+ public InformationSet write(HolidaysSpec spec, boolean verbose) {
+ if (!verbose && !spec.isUsed()) {
+ return null;
+ }
+ InformationSet hinfo = new InformationSet();
+
+ writeProperties(hinfo, spec, verbose, true);
+
+ Parameter[] coef = spec.getCoefficients();
+ if (coef != null) {
+ hinfo.set(COEF, coef);
+ }
+ return hinfo;
+ }
+
+ public void writeProperties(InformationSet hinfo, HolidaysSpec spec, boolean verbose, boolean v3) {
+ if (spec.getHolidays() != null) {
+ hinfo.add(HOLIDAYS, spec.getHolidays());
+ }
+ if (verbose || spec.getHolidaysOption() != HolidaysSpec.DEF_OPTION) {
+ hinfo.add(OPTION, spec.getHolidaysOption().name());
+ }
+ if (verbose || spec.isSingle()) {
+ hinfo.add(SINGLE, spec.isSingle());
+ }
+ if (verbose || !Arrays.equals(spec.getNonWorkingDays(), HolidaysVariable.NONWORKING_WE)) {
+ hinfo.add(NONWORKING, spec.getNonWorkingDays());
+ }
+ if (verbose || spec.isTest()) {
+ hinfo.add(TEST, spec.isTest());
+ }
+ }
+
+ public HolidaysSpec read(InformationSet hinfo) {
+ if (hinfo == null) {
+ return HolidaysSpec.DEFAULT_UNUSED;
+ }
+ String holidays = hinfo.get(HOLIDAYS, String.class);
+ if (holidays == null) {
+ return HolidaysSpec.DEFAULT_UNUSED;
+ }
+ HolidaysSpec.Builder builder = HolidaysSpec.builder()
+ .holidays(holidays);
+ String option = hinfo.get(OPTION, String.class);
+ if (option != null){
+ HolidaysOption o= HolidaysOption.valueOf(option);
+ builder.holidaysOption(o);
+ }
+ Boolean single = hinfo.get(SINGLE, Boolean.class);
+ if (single != null){
+ builder.single(single);
+ }
+ int[] nwd=hinfo.get(NONWORKING, int[].class);
+ if (nwd != null){
+ builder.nonWorkingDays(nwd);
+ }
+ Boolean test = hinfo.get(TEST, Boolean.class);
+ if (test != null && test) {
+ builder.test(true);
+ } else {
+ Parameter[] coef = hinfo.get(COEF, Parameter[].class);
+ if (coef != null) {
+ builder.coefficients(coef);
+ }
+ }
+
+ return builder.build();
+ }
+
+}
diff --git a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-information/src/main/java/jdplus/sa/base/information/highfreq/OutlierSpecMapping.java b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-information/src/main/java/jdplus/sa/base/information/highfreq/OutlierSpecMapping.java
new file mode 100644
index 00000000..5a635dde
--- /dev/null
+++ b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-information/src/main/java/jdplus/sa/base/information/highfreq/OutlierSpecMapping.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2020 National Bank of Belgium
+ *
+ * Licensed under the EUPL, Version 1.2 or – as soon they will be approved
+ * by the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ *
+ * https://joinup.ec.europa.eu/software/page/eupl
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ */
+package jdplus.sa.base.information.highfreq;
+
+import jdplus.toolkit.base.api.information.InformationSet;
+import jdplus.toolkit.base.api.modelling.highfreq.OutlierSpec;
+import jdplus.toolkit.base.api.timeseries.TimeSelector;
+
+/**
+ *
+ * @author PALATEJ
+ */
+@lombok.experimental.UtilityClass
+public class OutlierSpecMapping {
+
+ final String SPAN = "span",
+ AO = "ao", LS = "ls", WO = "wo",
+ VA = "va";
+
+ public InformationSet write(OutlierSpec spec, boolean verbose) {
+ if (!verbose && spec.isDefault()) {
+ return null;
+ }
+ InformationSet info = new InformationSet();
+ TimeSelector span = spec.getSpan();
+ if (verbose || span.getType() != TimeSelector.SelectionType.All) {
+ info.add(SPAN, span);
+ }
+ if (spec.isAo() || verbose) {
+ info.add(AO, spec.isAo());
+ }
+ if (spec.isLs() || verbose) {
+ info.add(LS, spec.isLs());
+ }
+ if (spec.isWo() || verbose) {
+ info.add(WO, spec.isWo());
+ }
+ double cv = spec.getCriticalValue();
+ if (verbose || cv != 0) {
+ info.add(VA, cv);
+ }
+ return info;
+ }
+
+ public OutlierSpec read(InformationSet info) {
+ if (info == null) {
+ return OutlierSpec.DEFAULT_DISABLED;
+ }
+
+ OutlierSpec.Builder builder = OutlierSpec.builder();
+
+ TimeSelector span = info.get(SPAN, TimeSelector.class);
+ if (span != null) {
+ builder = builder.span(span);
+ }
+ Boolean ao = info.get(AO, Boolean.class);
+ if (ao != null) {
+ builder.ao(ao);
+ }
+ Boolean ls = info.get(LS, Boolean.class);
+ if (ls != null) {
+ builder.ls(ls);
+ }
+ Boolean wo = info.get(WO, Boolean.class);
+ if (wo != null) {
+ builder.wo(wo);
+ }
+ Double cv = info.get(VA, Double.class);
+ if (cv != null) {
+ builder = builder.criticalValue(cv);
+ }
+ return builder.build();
+ }
+
+}
diff --git a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-information/src/main/java/jdplus/sa/base/information/highfreq/RegressionSpecMapping.java b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-information/src/main/java/jdplus/sa/base/information/highfreq/RegressionSpecMapping.java
new file mode 100644
index 00000000..d4963159
--- /dev/null
+++ b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-information/src/main/java/jdplus/sa/base/information/highfreq/RegressionSpecMapping.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2020 National Bank of Belgium
+ *
+ * Licensed under the EUPL, Version 1.2 or – as soon they will be approved
+ * by the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ *
+ * https://joinup.ec.europa.eu/software/page/eupl
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ */
+package jdplus.sa.base.information.highfreq;
+
+import jdplus.toolkit.base.api.information.Information;
+import jdplus.toolkit.base.api.information.InformationSet;
+import jdplus.toolkit.base.information.VariableMapping;
+import jdplus.toolkit.base.api.modelling.highfreq.RegressionSpec;
+import jdplus.toolkit.base.api.timeseries.TsDomain;
+import jdplus.toolkit.base.api.timeseries.regression.IOutlier;
+import jdplus.toolkit.base.api.timeseries.regression.InterventionVariable;
+import jdplus.toolkit.base.api.timeseries.regression.TsContextVariable;
+import jdplus.toolkit.base.api.timeseries.regression.Variable;
+import java.util.List;
+import jdplus.toolkit.base.api.modelling.highfreq.EasterSpec;
+import jdplus.toolkit.base.api.modelling.highfreq.HolidaysSpec;
+
+/**
+ *
+ * @author PALATEJ
+ */
+@lombok.experimental.UtilityClass
+public class RegressionSpecMapping {
+
+ final String CAL = "calendar", EASTER = "easter",
+ OUTLIER = "outlier", OUTLIERS = "outlier*",
+ USER = "user", USERS = "user*",
+ INTERVENTION = "intervention", INTERVENTIONS = "intervention*";
+
+ public RegressionSpec read(InformationSet info) {
+ if (info == null) {
+ return RegressionSpec.DEFAULT;
+ }
+ RegressionSpec.Builder builder = RegressionSpec.builder();
+
+ HolidaysSpec hol = HolidaysSpecMapping.read(info.getSubSet(CAL));
+ if (hol != null) {
+ builder.holidays(hol);
+ }
+ EasterSpec e=EasterSpecMapping.read(info.getSubSet(EASTER));
+ if (e != null){
+ builder.easter(e);
+ }
+ List> sel = info.select(OUTLIERS, InformationSet.class);
+ if (!sel.isEmpty()) {
+ for (Information sub : sel) {
+ Variable v = VariableMapping.readO(sub.getValue());
+ builder.outlier(v);
+ }
+ }
+ sel = info.select(INTERVENTIONS, InformationSet.class);
+ if (!sel.isEmpty()) {
+ for (Information sub : sel) {
+ Variable v = VariableMapping.readIV(sub.getValue());
+ builder.interventionVariable(v);
+ }
+ }
+ sel = info.select(USERS, InformationSet.class);
+ if (!sel.isEmpty()) {
+ for (Information sub : sel) {
+ Variable v = VariableMapping.readT(sub.getValue());
+ builder.userDefinedVariable(v);
+ }
+ }
+ return builder.build();
+ }
+
+ public InformationSet write(RegressionSpec spec, TsDomain context, boolean verbose) {
+ if (!spec.isUsed()) {
+ return null;
+ }
+ InformationSet info = new InformationSet();
+
+ InformationSet hinfo = HolidaysSpecMapping.write(spec.getHolidays(), verbose);
+ if (hinfo != null) {
+ info.set(CAL, hinfo);
+ }
+ InformationSet einfo = EasterSpecMapping.write(spec.getEaster(), verbose);
+ if (einfo != null) {
+ info.set(EASTER, einfo);
+ }
+ List> voutliers = spec.getOutliers();
+ if (!voutliers.isEmpty()) {
+ int idx = 1;
+ for (Variable v : voutliers) {
+ InformationSet w = VariableMapping.writeO(v, verbose);
+ info.set(OUTLIER + (idx++), w);
+ }
+ }
+ List> vusers = spec.getUserDefinedVariables();
+ if (!vusers.isEmpty()) {
+ int idx = 1;
+ for (Variable v : vusers) {
+ InformationSet w = VariableMapping.writeT(v, verbose);
+ info.set(USER + (idx++), w);
+ }
+ }
+ List> viv = spec.getInterventionVariables();
+ if (!viv.isEmpty()) {
+ int idx = 1;
+ for (Variable v : viv) {
+ InformationSet w = VariableMapping.writeIV(v, verbose);
+ info.set(INTERVENTION + (idx++), w);
+ }
+ }
+ return info;
+ }
+
+}
diff --git a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-information/src/main/java/jdplus/sa/base/information/highfreq/SeriesSpecMapping.java b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-information/src/main/java/jdplus/sa/base/information/highfreq/SeriesSpecMapping.java
new file mode 100644
index 00000000..c6ededb0
--- /dev/null
+++ b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-information/src/main/java/jdplus/sa/base/information/highfreq/SeriesSpecMapping.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2020 National Bank of Belgium
+ *
+ * Licensed under the EUPL, Version 1.2 or – as soon they will be approved
+ * by the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ *
+ * https://joinup.ec.europa.eu/software/page/eupl
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ */
+package jdplus.sa.base.information.highfreq;
+
+import jdplus.toolkit.base.api.information.InformationSet;
+import jdplus.toolkit.base.api.modelling.highfreq.SeriesSpec;
+import jdplus.toolkit.base.api.timeseries.TimeSelector;
+import jdplus.toolkit.base.api.modelling.highfreq.DataCleaning;
+
+/**
+ *
+ * @author PALATEJ
+ */
+@lombok.experimental.UtilityClass
+public class SeriesSpecMapping {
+
+ final String SPAN = "span", CLEANING = "cleaning";
+
+
+ public InformationSet write(SeriesSpec spec, boolean verbose) {
+ if (!verbose && spec.isDefault()) {
+ return null;
+ }
+ InformationSet info = new InformationSet();
+ if (verbose || spec.getSpan().getType() != TimeSelector.SelectionType.All) {
+ info.add(SPAN, spec.getSpan());
+ }
+ if (verbose || spec.getCleaning() != DataCleaning.NONE) {
+ info.add(CLEANING, spec.getCleaning().name());
+ }
+ return info;
+ }
+
+ public SeriesSpec read(InformationSet info) {
+
+ if (info == null) {
+ return SeriesSpec.DEFAULT;
+ }
+
+ SeriesSpec.Builder builder = SeriesSpec.builder();
+ TimeSelector span = info.get(SPAN, TimeSelector.class);
+ if (span != null) {
+ builder.span(span);
+ }
+ String cleaning = info.get(CLEANING, String.class);
+ if (cleaning != null) {
+ DataCleaning dc=DataCleaning.valueOf(cleaning);
+ builder.cleaning(dc);
+ }
+ return builder.build();
+ }
+
+}
diff --git a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-information/src/main/java/jdplus/sa/base/information/highfreq/TransformSpecMapping.java b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-information/src/main/java/jdplus/sa/base/information/highfreq/TransformSpecMapping.java
new file mode 100644
index 00000000..bd9ce839
--- /dev/null
+++ b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-information/src/main/java/jdplus/sa/base/information/highfreq/TransformSpecMapping.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2020 National Bank of Belgium
+ *
+ * Licensed under the EUPL, Version 1.2 or – as soon they will be approved
+ * by the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ *
+ * https://joinup.ec.europa.eu/software/page/eupl
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ */
+package jdplus.sa.base.information.highfreq;
+
+import jdplus.toolkit.base.api.information.InformationSet;
+import jdplus.toolkit.base.api.modelling.TransformationType;
+import jdplus.toolkit.base.api.modelling.highfreq.TransformSpec;
+
+/**
+ *
+ * @author PALATEJ
+ */
+@lombok.experimental.UtilityClass
+public class TransformSpecMapping {
+
+ final String FN = "function",
+ AICDIFF = "aicdiff"
+ ;
+
+ public InformationSet write(TransformSpec spec, boolean verbose) {
+ if (!verbose && spec.isDefault()) {
+ return null;
+ }
+ InformationSet info = new InformationSet();
+ if (verbose || spec.getFunction() != TransformationType.None) {
+ info.add(FN, spec.getFunction().name());
+ }
+ return info;
+ }
+
+ public TransformSpec read(InformationSet info) {
+ if (info == null) {
+ return TransformSpec.DEFAULT;
+ }
+ TransformSpec.Builder builder = TransformSpec.builder();
+ String fn = info.get(FN, String.class);
+ if (fn != null) {
+ builder = builder.function(TransformationType.valueOf(fn));
+ }
+ Double aic = info.get(AICDIFF, Double.class);
+ if (aic != null) {
+ builder.aicDiff(aic);
+ }
+ return builder.build();
+ }
+
+}
diff --git a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-information/src/main/java/module-info.java b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-information/src/main/java/module-info.java
index 61655676..d697fdc3 100644
--- a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-information/src/main/java/module-info.java
+++ b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-information/src/main/java/module-info.java
@@ -11,6 +11,7 @@
requires jdplus.toolkit.base.information;
exports jdplus.sa.base.information;
+ exports jdplus.sa.base.information.highfreq;
uses SaSpecificationMapping;
}
\ No newline at end of file
diff --git a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-protobuf/pom.xml b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-protobuf/pom.xml
index b06dac6a..5bb09539 100644
--- a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-protobuf/pom.xml
+++ b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-protobuf/pom.xml
@@ -5,7 +5,7 @@
eu.europa.ec.joinup.sat
jdplus-sa-base-parent
- 3.0.2
+ 3.1.0
jdplus-sa-base-protobuf
diff --git a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-r/pom.xml b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-r/pom.xml
index fa73b0d0..1d5a9d4c 100644
--- a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-r/pom.xml
+++ b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-r/pom.xml
@@ -5,7 +5,7 @@
eu.europa.ec.joinup.sat
jdplus-sa-base-parent
- 3.0.2
+ 3.1.0
jdplus-sa-base-r
diff --git a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-workspace/pom.xml b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-workspace/pom.xml
index 02667fb0..6b1e59aa 100644
--- a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-workspace/pom.xml
+++ b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-workspace/pom.xml
@@ -5,7 +5,7 @@
eu.europa.ec.joinup.sat
jdplus-sa-base-parent
- 3.0.2
+ 3.1.0
jdplus-sa-base-workspace
diff --git a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-workspace/src/main/java/jdplus/sa/base/workspace/MultiProcessing.java b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-workspace/src/main/java/jdplus/sa/base/workspace/MultiProcessing.java
index fd131e03..0d1c4518 100644
--- a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-workspace/src/main/java/jdplus/sa/base/workspace/MultiProcessing.java
+++ b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-workspace/src/main/java/jdplus/sa/base/workspace/MultiProcessing.java
@@ -16,6 +16,9 @@
*/
package jdplus.sa.base.workspace;
+import java.time.Clock;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
import jdplus.sa.base.api.SaItem;
import jdplus.sa.base.api.SaItems;
import jdplus.sa.base.api.SaSpecification;
@@ -26,6 +29,10 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import jdplus.sa.base.api.EstimationPolicy;
+import jdplus.sa.base.api.EstimationPolicyType;
+import jdplus.toolkit.base.api.timeseries.TsDomain;
+import jdplus.toolkit.base.api.timeseries.TsInformationType;
/**
*
@@ -33,7 +40,7 @@
*/
@lombok.Data
public class MultiProcessing {
-
+
public static MultiProcessing of(String name, SaItems processing) {
MultiProcessing p = new MultiProcessing(name);
p.metaData.putAll(processing.getMeta());
@@ -44,18 +51,38 @@ public static MultiProcessing of(String name, SaItems processing) {
public MultiProcessing(String name) {
this.name = name;
}
-
- public void compute(ModellingContext context) {
+
+ private static final String TIMESTAMP="@timestamp";
+
+ public MultiProcessing refresh(String policy, TsDomain domain, String info){
+ MultiProcessing p =new MultiProcessing(name);
+ for (SaItem cur : items) {
+ p.items.add(cur.refresh(new EstimationPolicy(EstimationPolicyType.valueOf(policy), domain),
+ TsInformationType.valueOf(info)));
+ }
+ p.metaData.putAll(metaData);
+ p.metaData.put(TIMESTAMP, LocalDateTime.now(Clock.systemDefaultZone()).format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
+ return p;
+ }
+
+ public void compute(ModellingContext context) {
items.parallelStream().forEach(v -> v.compute(context, false));
}
public void process(ModellingContext context) {
items.parallelStream().forEach(v -> v.process(context, false));
}
-
- public void add(SaItem item){
+
+ public void add(SaItem item) {
items.add(item);
}
+
+ public MultiProcessing makeCopy(){
+ MultiProcessing mp=new MultiProcessing(name);
+ mp.metaData.putAll(metaData);
+ mp.items.addAll(items); // SaItem are immutable !
+ return mp;
+ }
public void add(String name, TsData s, SaSpecification spec) {
Ts ts = Ts.of(name, s);
@@ -71,19 +98,9 @@ public void set(int pos, SaItem newItem) {
items.set(pos, newItem);
}
- public void setDomainSpecification(int pos, SaSpecification newspec){
- SaItem nitem=items.get(pos).withDomainSpecification(newspec);
- items.set(pos, nitem);
- }
-
- public void setSpecification(int pos, SaSpecification newspec){
- SaItem nitem=items.get(pos).withSpecification(newspec);
- items.set(pos, nitem);
- }
-
- public void setData(int pos, TsData ndata){
- SaItem item=items.get(pos);
- Ts nts=Ts.of(item.getDefinition().getTs().getName(), ndata);
+ public void setData(int pos, TsData ndata) {
+ SaItem item = items.get(pos);
+ Ts nts = Ts.of(item.getDefinition().getTs().getName(), ndata);
items.set(pos, item.withTs(nts));
}
diff --git a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-workspace/src/main/java/jdplus/sa/base/workspace/Utility.java b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-workspace/src/main/java/jdplus/sa/base/workspace/Utility.java
new file mode 100644
index 00000000..c1362da9
--- /dev/null
+++ b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-workspace/src/main/java/jdplus/sa/base/workspace/Utility.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2022 National Bank of Belgium
+ *
+ * Licensed under the EUPL, Version 1.2 or – as soon they will be approved
+ * by the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ *
+ * https://joinup.ec.europa.eu/software/page/eupl
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ */
+package jdplus.sa.base.workspace;
+
+import java.util.HashMap;
+import jdplus.sa.base.api.SaDefinition;
+import jdplus.sa.base.api.SaItem;
+import jdplus.toolkit.base.api.timeseries.Ts;
+
+/**
+ *
+ * @author palatej
+ */
+@lombok.experimental.UtilityClass
+public class Utility {
+ public SaItem withTsMetaData(SaItem item, String key, String value) {
+ SaDefinition definition = item.getDefinition();
+ Ts cur = definition.getTs();
+ HashMap map = new HashMap<>(cur.getMeta());
+ map.put(key, value);
+ Ts ncur = cur.toBuilder().clearMeta()
+ .meta(map)
+ .build();
+ SaDefinition ndef = definition.toBuilder()
+ .ts(ncur)
+ .build();
+ return new SaItem(item.getName(), ndef, item.getMeta(), item.getPriority(), item.getEstimation(), item.isProcessed());
+ }
+
+ public String getSingleMetaData(SaItem item, String key) {
+ return item.getMeta().get(key);
+ }
+
+ public String getSingleTsMetaData(SaItem item, String key) {
+ Ts cur = item.getDefinition().getTs();
+ return cur.getMeta().get(key);
+ }
+
+
+}
diff --git a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-workspace/src/main/java/jdplus/sa/base/workspace/Ws.java b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-workspace/src/main/java/jdplus/sa/base/workspace/Ws.java
index d4845fa4..46735a21 100644
--- a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-workspace/src/main/java/jdplus/sa/base/workspace/Ws.java
+++ b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-workspace/src/main/java/jdplus/sa/base/workspace/Ws.java
@@ -39,37 +39,41 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import jdplus.sa.base.api.EstimationPolicy;
+import jdplus.sa.base.api.EstimationPolicyType;
+import jdplus.toolkit.base.api.timeseries.TsDomain;
+import jdplus.toolkit.base.api.timeseries.TsInformationType;
/**
*
* @author PALATEJ
*/
public class Ws {
-
+
private final String source;
private ModellingContext context;
private final List multiProcessing = new ArrayList<>();
-
+
public Ws() {
this.source = null;
this.context = new ModellingContext();
}
-
+
public Ws(final String source, final ModellingContext context) {
this.source = source;
this.context = context;
}
-
+
public static Ws create(ModellingContext context) {
return new Ws(null, context);
}
-
+
public static Ws open(String fileName) throws IOException {
File file = new File(fileName);
FileWorkspace fws = FileWorkspace.open(file.toPath(), DemetraVersion.JD3);
ModellingContext context = WorkspaceUtility.context(fws, false);
Ws ws = new Ws(fileName, context);
-
+
List sa = WorkspaceUtility.select(fws, SaHandlers.SA_MULTI);
for (WorkspaceItemDescriptor s : sa) {
SaItems mp = (SaItems) fws.load(s.getKey());
@@ -77,9 +81,9 @@ public static Ws open(String fileName) throws IOException {
}
return ws;
}
-
+
@Deprecated
- public ModellingContext context(){
+ public ModellingContext context() {
return context;
}
@@ -89,19 +93,19 @@ public boolean save(String v) {
}
return saveAs(source, v, false);
}
-
+
public boolean saveAs(String sfile, String v, boolean failIfExists) {
DemetraVersion version = DemetraVersion.JD3;
if (v != null && v.equalsIgnoreCase("jd2")) {
version = DemetraVersion.JD2;
}
File file = new File(sfile);
-
+
boolean exist = file.exists();
if (exist && failIfExists) {
return false;
}
- try ( FileWorkspace storage = FileWorkspace.create(file.toPath(), version)) {
+ try (FileWorkspace storage = FileWorkspace.create(file.toPath(), version)) {
storage.setName(Paths.changeExtension(file.getName(), null));
storeCalendar(storage, context.getCalendars());
// store variables
@@ -122,7 +126,7 @@ public boolean saveAs(String sfile, String v, boolean failIfExists) {
new WorkspaceItemDescriptor.Attributes(mp.getName(), false, null));
// build the multiProcessing
Map meta = new HashMap<>(mp.getMetaData());
- meta.put("@timestamp", LocalDateTime.now(Clock.systemDefaultZone()).format(DateTimeFormatter.ISO_DATE));
+ meta.put("@timestamp", LocalDateTime.now(Clock.systemDefaultZone()).format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
meta.putAll(mp.getMetaData());
SaItems items = SaItems.builder()
.meta(meta)
@@ -131,13 +135,13 @@ public boolean saveAs(String sfile, String v, boolean failIfExists) {
.build();
storage.store(cur, items);
}
-
+
} catch (IOException | InvalidPathException ex) {
return false;
}
return true;
}
-
+
// public static Path getRootFolder(Path indexFile) throws IOException {
// Path parent = indexFile.toAbsolutePath().getParent();
// if (parent == null) {
@@ -150,62 +154,80 @@ public boolean saveAs(String sfile, String v, boolean failIfExists) {
= new WorkspaceItemDescriptor(
new WorkspaceItemDescriptor.Key(WorkspaceFamily.UTIL_CAL, "Calendars"),
new WorkspaceItemDescriptor.Attributes("Calendars", false, null));
-
+
private static void storeCalendar(FileWorkspace storage, CalendarManager value) throws IOException {
storage.store(CAL_ID, value);
}
-
+
public MultiProcessing getMultiProcessing(int idx) {
return multiProcessing.get(idx);
}
-
+
public int getMultiProcessingCount() {
return multiProcessing.size();
}
-
+
public MultiProcessing newMultiProcessing(String name) {
MultiProcessing n = new MultiProcessing(name);
multiProcessing.add(n);
return n;
}
-
+
public ModellingContext getContext() {
return (this.context);
}
-
+
public void setContext(ModellingContext context) {
- this.context=context;
+ this.context = context;
}
-
- public void addVariable(String family, String name, TsData data){
+
+ public void addVariable(String family, String name, TsData data) {
TsDataSuppliers tsfamily = context.getTsVariables(family);
- if (tsfamily == null){
- tsfamily=new TsDataSuppliers();
+ if (tsfamily == null) {
+ tsfamily = new TsDataSuppliers();
context.getTsVariableManagers().set(name, tsfamily);
}
tsfamily.set(name, new StaticTsDataSupplier(data));
}
-
- public void addCalendar(String name, CalendarDefinition calendar){
+
+ public void addCalendar(String name, CalendarDefinition calendar) {
context.getCalendars().set(name, calendar);
}
public void computeAll() {
multiProcessing.stream().forEach(p -> p.compute(context));
}
-
+
public void compute(String name) {
multiProcessing.stream().filter(p -> p.getName().equals(name)).forEach(q -> q.compute(context));
}
-
+
public void processAll() {
multiProcessing.stream().forEach(p -> p.process(context));
}
-
+
public void process(String name) {
multiProcessing.stream().filter(p -> p.getName().equals(name)).forEach(q -> q.process(context));
}
+ public void add(MultiProcessing sap) {
+ multiProcessing.add(sap);
+ }
+
+ public void refreshAll(String policy, TsDomain domain, String info) {
+ multiProcessing.replaceAll(sap -> sap.refresh(policy, domain, info));
+ }
+
+ public Ws makeCopy(){
+ Ws copy=new Ws();
+ copy.context=context; // ? perhaps should it be changed
+ copy.multiProcessing
+ .addAll(multiProcessing.stream()
+ .map(p->p.makeCopy())
+ .toList());
+ return copy;
+ }
+
// public boolean save(String fileName) {
// File file = new File(fileName);
// try {
diff --git a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-xml/pom.xml b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-xml/pom.xml
index 261ee46b..d71b0215 100644
--- a/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-xml/pom.xml
+++ b/jdplus-main-base/jdplus-sa-base-parent/jdplus-sa-base-xml/pom.xml
@@ -5,7 +5,7 @@
eu.europa.ec.joinup.sat
jdplus-sa-base-parent
- 3.0.2
+ 3.1.0
jdplus-sa-base-xml
diff --git a/jdplus-main-base/jdplus-sa-base-parent/pom.xml b/jdplus-main-base/jdplus-sa-base-parent/pom.xml
index b59cb5d4..17f804de 100644
--- a/jdplus-main-base/jdplus-sa-base-parent/pom.xml
+++ b/jdplus-main-base/jdplus-sa-base-parent/pom.xml
@@ -5,7 +5,7 @@
eu.europa.ec.joinup.sat
jdplus-main-base
- 3.0.2
+ 3.1.0
jdplus-sa-base-parent
diff --git a/jdplus-main-base/jdplus-spreadsheet-base-parent/jdplus-spreadsheet-base-api/pom.xml b/jdplus-main-base/jdplus-spreadsheet-base-parent/jdplus-spreadsheet-base-api/pom.xml
index fbb6993a..0d81385b 100644
--- a/jdplus-main-base/jdplus-spreadsheet-base-parent/jdplus-spreadsheet-base-api/pom.xml
+++ b/jdplus-main-base/jdplus-spreadsheet-base-parent/jdplus-spreadsheet-base-api/pom.xml
@@ -6,7 +6,7 @@
eu.europa.ec.joinup.sat
jdplus-spreadsheet-base-parent
- 3.0.2
+ 3.1.0
jdplus-spreadsheet-base-api
@@ -23,6 +23,11 @@
jdplus-toolkit-base-tsp
${project.version}
+
+ eu.europa.ec.joinup.sat
+ jdplus-sa-base-core
+ ${project.version}
+
com.github.nbbrd.spreadsheet4j
spreadsheet-api
diff --git a/jdplus-main-base/jdplus-spreadsheet-base-parent/jdplus-spreadsheet-base-api/src/main/java/internal/spreadsheet/base/api/CachedSpreadSheetConnection.java b/jdplus-main-base/jdplus-spreadsheet-base-parent/jdplus-spreadsheet-base-api/src/main/java/internal/spreadsheet/base/api/CachedSpreadSheetConnection.java
index 4a2d7ddd..fedc5340 100644
--- a/jdplus-main-base/jdplus-spreadsheet-base-parent/jdplus-spreadsheet-base-api/src/main/java/internal/spreadsheet/base/api/CachedSpreadSheetConnection.java
+++ b/jdplus-main-base/jdplus-spreadsheet-base-parent/jdplus-spreadsheet-base-api/src/main/java/internal/spreadsheet/base/api/CachedSpreadSheetConnection.java
@@ -17,19 +17,16 @@
package internal.spreadsheet.base.api;
import jdplus.toolkit.base.api.timeseries.TsCollection;
-import jdplus.toolkit.base.tsp.util.IOCache;
-import jdplus.toolkit.base.tsp.util.IOCacheFactory;
+import jdplus.toolkit.base.tsp.util.ShortLivedCache;
+import jdplus.toolkit.base.tsp.util.ShortLivedCaching;
import lombok.AccessLevel;
-import nbbrd.io.Resource;
-import nbbrd.io.function.IOSupplier;
+import nbbrd.design.StaticFactoryMethod;
import org.checkerframework.checker.nullness.qual.NonNull;
import java.io.File;
import java.io.IOException;
import java.util.List;
-import java.util.Objects;
import java.util.Optional;
-import java.util.stream.Collectors;
/**
* @author Philippe Charles
@@ -37,7 +34,8 @@
@lombok.AllArgsConstructor(access = AccessLevel.PACKAGE)
public final class CachedSpreadSheetConnection implements SpreadSheetConnection {
- public static @NonNull SpreadSheetConnection of(@NonNull SpreadSheetConnection delegate, @NonNull File target, @NonNull IOCacheFactory cacheFactory) {
+ @StaticFactoryMethod
+ public static @NonNull CachedSpreadSheetConnection of(@NonNull SpreadSheetConnection delegate, @NonNull File target, @NonNull ShortLivedCaching cacheFactory) {
return new CachedSpreadSheetConnection(delegate, cacheFactory.ofFile(target));
}
@@ -45,50 +43,65 @@ public final class CachedSpreadSheetConnection implements SpreadSheetConnection
private final SpreadSheetConnection delegate;
@lombok.NonNull
- private final IOCache cache;
+ private final ShortLivedCache> cache;
@Override
- public Optional getSheetByName(String name) throws IOException {
- Objects.requireNonNull(name);
-
- List all = peek("getSheets");
+ public @lombok.NonNull Optional getSheetByName(@lombok.NonNull String name) throws IOException {
+ List all = peekAll();
if (all != null) {
- return all.stream().filter(o -> o.getName().equals(name)).findFirst();
+ return all.stream()
+ .filter(collection -> collection.getName().equals(name))
+ .findFirst();
}
- return load("getSheetByName/" + name, () -> delegate.getSheetByName(name));
+ String key = "getSheetByName/" + name;
+ List cachedValue = cache.get(key);
+ if (cachedValue == null) {
+ Optional result = delegate.getSheetByName(name);
+ cache.put(key, result.stream().toList());
+ return result;
+ } else {
+ return cachedValue.stream().findFirst();
+ }
}
@Override
- public List getSheetNames() throws IOException {
- List all = peek("getSheets");
+ public @lombok.NonNull List getSheetNames() throws IOException {
+ List all = peekAll();
if (all != null) {
- return all.stream().map(TsCollection::getName).collect(Collectors.toList());
+ return all.stream()
+ .map(TsCollection::getName)
+ .toList();
}
- return load("getSheetNames", delegate::getSheetNames);
+ String key = "getSheetNames";
+ List cachedValue = cache.get(key);
+ if (cachedValue == null) {
+ List result = delegate.getSheetNames();
+ cache.put(key, result.stream().map(TsCollection::ofName).toList());
+ return result;
+ } else {
+ return cachedValue.stream().map(TsCollection::getName).toList();
+ }
}
@Override
- public List getSheets() throws IOException {
- return load("getSheets", delegate::getSheets);
+ public @lombok.NonNull List getSheets() throws IOException {
+ String key = "getSheets";
+ List cachedValue = cache.get(key);
+ if (cachedValue == null) {
+ cachedValue = delegate.getSheets();
+ cache.put(key, cachedValue);
+ }
+ return cachedValue;
}
@Override
public void close() throws IOException {
- Resource.closeBoth(cache, delegate);
+ delegate.close();
}
- private T peek(String key) {
- return (T) cache.get(key);
- }
-
- private T load(String key, IOSupplier loader) throws IOException {
- T result = peek(key);
- if (result == null) {
- result = loader.getWithIO();
- cache.put(key, result);
- }
- return result;
+ private List peekAll() {
+ return cache.get("getSheets");
}
}
diff --git a/jdplus-main-base/jdplus-spreadsheet-base-parent/jdplus-spreadsheet-base-api/src/main/java/internal/spreadsheet/base/api/SpreadSheetDataDisplayName.java b/jdplus-main-base/jdplus-spreadsheet-base-parent/jdplus-spreadsheet-base-api/src/main/java/internal/spreadsheet/base/api/SpreadSheetDataDisplayName.java
index c61a24fc..6fcf5c9b 100644
--- a/jdplus-main-base/jdplus-spreadsheet-base-parent/jdplus-spreadsheet-base-api/src/main/java/internal/spreadsheet/base/api/SpreadSheetDataDisplayName.java
+++ b/jdplus-main-base/jdplus-spreadsheet-base-parent/jdplus-spreadsheet-base-api/src/main/java/internal/spreadsheet/base/api/SpreadSheetDataDisplayName.java
@@ -24,6 +24,7 @@
import jdplus.toolkit.base.tsp.HasDataDisplayName;
import jdplus.toolkit.base.tsp.util.DataSourcePreconditions;
import jdplus.toolkit.base.api.util.MultiLineNameUtil;
+import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.Locale;
@@ -37,14 +38,14 @@ public final class SpreadSheetDataDisplayName implements HasDataDisplayName {
private final SpreadSheetParam resource;
@Override
- public String getDisplayName(DataSource dataSource) throws IllegalArgumentException {
+ public @NonNull String getDisplayName(@NonNull DataSource dataSource) throws IllegalArgumentException {
DataSourcePreconditions.checkProvider(providerName, dataSource);
SpreadSheetBean bean = resource.get(dataSource);
return bean.getFile().getPath() + toString(bean.getGathering());
}
@Override
- public String getDisplayName(DataSet dataSet) throws IllegalArgumentException {
+ public @NonNull String getDisplayName(@NonNull DataSet dataSet) throws IllegalArgumentException {
DataSourcePreconditions.checkProvider(providerName, dataSet);
switch (dataSet.getKind()) {
case COLLECTION:
@@ -56,7 +57,7 @@ public String getDisplayName(DataSet dataSet) throws IllegalArgumentException {
}
@Override
- public String getDisplayNodeName(DataSet dataSet) {
+ public @NonNull String getDisplayNodeName(@NonNull DataSet dataSet) {
DataSourcePreconditions.checkProvider(providerName, dataSet);
switch (dataSet.getKind()) {
case COLLECTION:
diff --git a/jdplus-main-base/jdplus-spreadsheet-base-parent/jdplus-spreadsheet-base-api/src/main/java/internal/spreadsheet/base/api/SpreadSheetSupport.java b/jdplus-main-base/jdplus-spreadsheet-base-parent/jdplus-spreadsheet-base-api/src/main/java/internal/spreadsheet/base/api/SpreadSheetSupport.java
index 87279adb..624e320a 100644
--- a/jdplus-main-base/jdplus-spreadsheet-base-parent/jdplus-spreadsheet-base-api/src/main/java/internal/spreadsheet/base/api/SpreadSheetSupport.java
+++ b/jdplus-main-base/jdplus-spreadsheet-base-parent/jdplus-spreadsheet-base-api/src/main/java/internal/spreadsheet/base/api/SpreadSheetSupport.java
@@ -64,7 +64,7 @@ public final class SpreadSheetSupport implements HasDataHierarchy, HasTsStream {
private final DataSetConversion seriesName;
@Override
- public List children(DataSource dataSource) throws IllegalArgumentException, IOException {
+ public @NonNull List children(@NonNull DataSource dataSource) throws IllegalArgumentException, IOException {
DataSourcePreconditions.checkProvider(providerName, dataSource);
try (SpreadSheetConnection connection = spreadsheet.open(dataSource)) {
@@ -79,7 +79,7 @@ public List children(DataSource dataSource) throws IllegalArgumentExcep
}
@Override
- public List children(DataSet parent) throws IllegalArgumentException, IOException {
+ public @NonNull List children(@NonNull DataSet parent) throws IllegalArgumentException, IOException {
DataSourcePreconditions.checkProvider(providerName, parent);
try (SpreadSheetConnection connection = spreadsheet.open(parent.getDataSource())) {
@@ -96,7 +96,7 @@ public List children(DataSet parent) throws IllegalArgumentException, I
}
@Override
- public Stream getData(DataSource dataSource, TsInformationType type) throws IOException {
+ public @NonNull Stream getData(@NonNull DataSource dataSource, @NonNull TsInformationType type) throws IOException {
DataSourcePreconditions.checkProvider(providerName, dataSource);
try (SpreadSheetConnection connection = spreadsheet.open(dataSource)) {
@@ -113,7 +113,7 @@ public Stream getData(DataSource dataSource, TsInformationType type)
}
@Override
- public Stream getData(DataSet dataSet, TsInformationType type) throws IllegalArgumentException, IOException {
+ public @NonNull Stream getData(@NonNull DataSet dataSet, @NonNull TsInformationType type) throws IllegalArgumentException, IOException {
DataSourcePreconditions.checkProvider(providerName, dataSet);
try (SpreadSheetConnection connection = spreadsheet.open(dataSet.getDataSource())) {
diff --git a/jdplus-main-base/jdplus-spreadsheet-base-parent/jdplus-spreadsheet-base-api/src/main/java/internal/spreadsheet/base/api/BookSupplier.java b/jdplus-main-base/jdplus-spreadsheet-base-parent/jdplus-spreadsheet-base-api/src/main/java/internal/spreadsheet/base/api/SpreadsheetManager.java
similarity index 58%
rename from jdplus-main-base/jdplus-spreadsheet-base-parent/jdplus-spreadsheet-base-api/src/main/java/internal/spreadsheet/base/api/BookSupplier.java
rename to jdplus-main-base/jdplus-spreadsheet-base-parent/jdplus-spreadsheet-base-api/src/main/java/internal/spreadsheet/base/api/SpreadsheetManager.java
index 07428539..eb34303d 100644
--- a/jdplus-main-base/jdplus-spreadsheet-base-parent/jdplus-spreadsheet-base-api/src/main/java/internal/spreadsheet/base/api/BookSupplier.java
+++ b/jdplus-main-base/jdplus-spreadsheet-base-parent/jdplus-spreadsheet-base-api/src/main/java/internal/spreadsheet/base/api/SpreadsheetManager.java
@@ -18,32 +18,41 @@
import ec.util.spreadsheet.Book;
import ec.util.spreadsheet.BookFactoryLoader;
-import org.checkerframework.checker.nullness.qual.NonNull;
+import lombok.NonNull;
+import nbbrd.design.StaticFactoryMethod;
import java.io.File;
+import java.util.List;
import java.util.Optional;
/**
* @author Philippe Charles
*/
-public interface BookSupplier {
+//@MightBePromoted
+@lombok.Builder
+public final class SpreadsheetManager {
- @NonNull Optional getFactory(@NonNull File file);
-
- default boolean hasFactory(@NonNull File file) {
- return getFactory(file).isPresent();
+ @StaticFactoryMethod
+ public static @NonNull SpreadsheetManager ofServiceLoader() {
+ return SpreadsheetManager.builder().factories(BookFactoryLoader.get()).build();
}
- @NonNull
- static BookSupplier usingServiceLoader() {
- return BookSupplier::getLoaderByFile;
- }
+ @lombok.Singular
+ private final List factories;
- static Optional getLoaderByFile(File file) {
- return BookFactoryLoader.get()
+ public @NonNull Optional getReader(@NonNull File file) {
+ return factories
.stream()
.filter(Book.Factory::canLoad)
.filter(factory -> factory.accept(file))
.findFirst();
}
+
+ public @NonNull Optional getWriter(@NonNull File file) {
+ return factories
+ .stream()
+ .filter(Book.Factory::canStore)
+ .filter(factory -> factory.accept(file))
+ .findFirst();
+ }
}
diff --git a/jdplus-main-base/jdplus-spreadsheet-base-parent/jdplus-spreadsheet-base-api/src/main/java/internal/spreadsheet/base/api/grid/SheetGridOutput.java b/jdplus-main-base/jdplus-spreadsheet-base-parent/jdplus-spreadsheet-base-api/src/main/java/internal/spreadsheet/base/api/grid/SheetGridOutput.java
index cff49460..bfa65b88 100644
--- a/jdplus-main-base/jdplus-spreadsheet-base-parent/jdplus-spreadsheet-base-api/src/main/java/internal/spreadsheet/base/api/grid/SheetGridOutput.java
+++ b/jdplus-main-base/jdplus-spreadsheet-base-parent/jdplus-spreadsheet-base-api/src/main/java/internal/spreadsheet/base/api/grid/SheetGridOutput.java
@@ -19,6 +19,8 @@
import jdplus.toolkit.base.tsp.grid.GridDataType;
import ec.util.spreadsheet.helpers.ArraySheet;
import jdplus.toolkit.base.tsp.grid.GridOutput;
+import org.checkerframework.checker.nullness.qual.NonNull;
+
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
@@ -38,7 +40,7 @@ public final class SheetGridOutput implements GridOutput {
private ArraySheet result = null;
@Override
- public Set getDataTypes() {
+ public @NonNull Set getDataTypes() {
EnumSet dataTypes = EnumSet.noneOf(GridDataType.class);
if (isSupportedDataType.test(String.class)) {
dataTypes.add(GridDataType.STRING);
@@ -53,7 +55,7 @@ public Set getDataTypes() {
}
@Override
- public Stream open(String name, int rows, int columns) {
+ public @NonNull Stream open(@NonNull String name, int rows, int columns) {
return new SheetGridOutputStream(ArraySheet.builder(rows, columns).name(name));
}
diff --git a/jdplus-main-base/jdplus-spreadsheet-base-parent/jdplus-spreadsheet-base-api/src/main/java/internal/spreadsheet/base/api/legacy/LegacySpreadSheetMoniker.java b/jdplus-main-base/jdplus-spreadsheet-base-parent/jdplus-spreadsheet-base-api/src/main/java/internal/spreadsheet/base/api/legacy/LegacySpreadSheetMoniker.java
index ebfc4789..c0fb662b 100644
--- a/jdplus-main-base/jdplus-spreadsheet-base-parent/jdplus-spreadsheet-base-api/src/main/java/internal/spreadsheet/base/api/legacy/LegacySpreadSheetMoniker.java
+++ b/jdplus-main-base/jdplus-spreadsheet-base-parent/jdplus-spreadsheet-base-api/src/main/java/internal/spreadsheet/base/api/legacy/LegacySpreadSheetMoniker.java
@@ -25,6 +25,7 @@
import jdplus.toolkit.base.tsp.HasDataMoniker;
import jdplus.toolkit.base.tsp.legacy.LegacyFileId;
import jdplus.toolkit.base.tsp.util.DataSourcePreconditions;
+import org.checkerframework.checker.nullness.qual.NonNull;
import java.io.File;
import java.util.Optional;
@@ -40,19 +41,19 @@ public final class LegacySpreadSheetMoniker implements HasDataMoniker {
private final SpreadSheetParam param;
@Override
- public TsMoniker toMoniker(DataSource dataSource) throws IllegalArgumentException {
+ public @NonNull TsMoniker toMoniker(@NonNull DataSource dataSource) throws IllegalArgumentException {
DataSourcePreconditions.checkProvider(providerName, dataSource);
throw new IllegalArgumentException("Not supported yet.");
}
@Override
- public TsMoniker toMoniker(DataSet dataSet) throws IllegalArgumentException {
+ public @NonNull TsMoniker toMoniker(@NonNull DataSet dataSet) throws IllegalArgumentException {
DataSourcePreconditions.checkProvider(providerName, dataSet);
throw new IllegalArgumentException("Not supported yet.");
}
@Override
- public Optional toDataSource(TsMoniker moniker) throws IllegalArgumentException {
+ public @NonNull Optional toDataSource(@NonNull TsMoniker moniker) throws IllegalArgumentException {
DataSourcePreconditions.checkProvider(providerName, moniker);
LegacyFileId id = LegacyFileId.parse(moniker.getId());
@@ -60,7 +61,7 @@ public Optional toDataSource(TsMoniker moniker) throws IllegalArgume
}
@Override
- public Optional toDataSet(TsMoniker moniker) throws IllegalArgumentException {
+ public @NonNull Optional toDataSet(@NonNull TsMoniker moniker) throws IllegalArgumentException {
DataSourcePreconditions.checkProvider(providerName, moniker);
LegacySpreadSheetId id = LegacySpreadSheetId.parse(moniker.getId());
diff --git a/jdplus-main-base/jdplus-spreadsheet-base-parent/jdplus-spreadsheet-base-api/src/main/java/jdplus/spreadsheet/base/api/SpreadSheetProvider.java b/jdplus-main-base/jdplus-spreadsheet-base-parent/jdplus-spreadsheet-base-api/src/main/java/jdplus/spreadsheet/base/api/SpreadSheetProvider.java
index 4ade4bf3..fea5b0f2 100644
--- a/jdplus-main-base/jdplus-spreadsheet-base-parent/jdplus-spreadsheet-base-api/src/main/java/jdplus/spreadsheet/base/api/SpreadSheetProvider.java
+++ b/jdplus-main-base/jdplus-spreadsheet-base-parent/jdplus-spreadsheet-base-api/src/main/java/jdplus/spreadsheet/base/api/SpreadSheetProvider.java
@@ -16,18 +16,18 @@
*/
package jdplus.spreadsheet.base.api;
+import ec.util.spreadsheet.Book;
+import internal.spreadsheet.base.api.*;
+import internal.spreadsheet.base.api.grid.SheetGrid;
+import internal.spreadsheet.base.api.legacy.LegacySpreadSheetMoniker;
import jdplus.toolkit.base.api.timeseries.TsProvider;
import jdplus.toolkit.base.tsp.*;
import jdplus.toolkit.base.tsp.grid.GridReader;
import jdplus.toolkit.base.tsp.stream.HasTsStream;
import jdplus.toolkit.base.tsp.stream.TsStreamAsProvider;
import jdplus.toolkit.base.tsp.util.FallbackDataMoniker;
-import jdplus.toolkit.base.tsp.util.IOCacheFactoryLoader;
import jdplus.toolkit.base.tsp.util.ResourcePool;
-import ec.util.spreadsheet.Book;
-import internal.spreadsheet.base.api.*;
-import internal.spreadsheet.base.api.grid.SheetGrid;
-import internal.spreadsheet.base.api.legacy.LegacySpreadSheetMoniker;
+import jdplus.toolkit.base.tsp.util.ShortLivedCachingLoader;
import nbbrd.design.DirectImpl;
import nbbrd.service.ServiceProvider;
@@ -41,9 +41,9 @@
@ServiceProvider(TsProvider.class)
public final class SpreadSheetProvider implements FileLoader {
- private static final String NAME = "XCLPRVDR";
+ public static final String NAME = "XCLPRVDR";
- private final BookSupplier bookSupplier;
+ private final SpreadsheetManager spreadsheetManager;
@lombok.experimental.Delegate
private final HasDataSourceMutableList mutableListSupport;
@@ -67,7 +67,7 @@ public final class SpreadSheetProvider implements FileLoader {
private final TsProvider tsSupport;
public SpreadSheetProvider() {
- this.bookSupplier = BookSupplier.usingServiceLoader();
+ this.spreadsheetManager = SpreadsheetManager.ofServiceLoader();
ResourcePool pool = SpreadSheetSupport.newConnectionPool();
SpreadSheetParam param = new SpreadSheetParam.V1();
@@ -77,7 +77,7 @@ public SpreadSheetProvider() {
this.beanSupport = HasDataSourceBean.of(NAME, param, param.getVersion());
this.filePathSupport = HasFilePaths.of(pool::clear);
this.displayNameSupport = SpreadSheetDataDisplayName.of(NAME, param);
- this.spreadSheetSupport = SpreadSheetSupport.of(NAME, pool.asFactory(dataSource -> openConnection(dataSource, filePathSupport, param, bookSupplier)), ignore -> param.getSheetParam(), ignore -> param.getSeriesParam());
+ this.spreadSheetSupport = SpreadSheetSupport.of(NAME, pool.asFactory(dataSource -> openConnection(dataSource, filePathSupport, param, spreadsheetManager)), ignore -> param.getSheetParam(), ignore -> param.getSeriesParam());
this.tsSupport = TsStreamAsProvider.of(NAME, spreadSheetSupport, monikerSupport, pool::clear);
}
@@ -93,15 +93,15 @@ public String getFileDescription() {
@Override
public boolean accept(File pathname) {
- return bookSupplier.hasFactory(pathname);
+ return spreadsheetManager.getReader(pathname).isPresent();
}
- private static SpreadSheetConnection openConnection(DataSource key, HasFilePaths paths, SpreadSheetParam param, BookSupplier books) throws IOException {
+ private static SpreadSheetConnection openConnection(DataSource key, HasFilePaths paths, SpreadSheetParam param, SpreadsheetManager books) throws IOException {
SpreadSheetBean bean = param.get(key);
File file = paths.resolveFilePath(bean.getFile());
- Book.Factory factory = books.getFactory(file).orElseThrow(() -> new IOException("File type not supported"));
+ Book.Factory factory = books.getReader(file).orElseThrow(() -> new IOException("File type not supported"));
SheetGrid result = SheetGrid.of(file, factory, getReader(bean));
- return CachedSpreadSheetConnection.of(result, file, IOCacheFactoryLoader.get());
+ return CachedSpreadSheetConnection.of(result, file, ShortLivedCachingLoader.get());
}
private static GridReader getReader(SpreadSheetBean bean) {
diff --git a/jdplus-main-base/jdplus-spreadsheet-base-parent/jdplus-spreadsheet-base-api/src/main/java/jdplus/spreadsheet/base/api/sa/SpreadsheetOutput.java b/jdplus-main-base/jdplus-spreadsheet-base-parent/jdplus-spreadsheet-base-api/src/main/java/jdplus/spreadsheet/base/api/sa/SpreadsheetOutput.java
new file mode 100644
index 00000000..02705bd3
--- /dev/null
+++ b/jdplus-main-base/jdplus-spreadsheet-base-parent/jdplus-spreadsheet-base-api/src/main/java/jdplus/spreadsheet/base/api/sa/SpreadsheetOutput.java
@@ -0,0 +1,232 @@
+/*
+ * Copyright 2013 National Bank of Belgium
+ *
+ * Licensed under the EUPL, Version 1.1 or – as soon they will be approved
+ * by the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ *
+ * http://ec.europa.eu/idabc/eupl
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ */
+package jdplus.spreadsheet.base.api.sa;
+
+
+import ec.util.spreadsheet.Book;
+import ec.util.spreadsheet.helpers.ArrayBook;
+import ec.util.spreadsheet.helpers.ArraySheet;
+import internal.spreadsheet.base.api.SpreadsheetManager;
+import jdplus.sa.base.api.SaDocument;
+import jdplus.toolkit.base.api.information.Explorable;
+import jdplus.toolkit.base.api.processing.Output;
+import jdplus.toolkit.base.api.timeseries.TsData;
+import jdplus.toolkit.base.api.timeseries.TsDataTable;
+import jdplus.toolkit.base.api.timeseries.TsPeriod;
+import jdplus.toolkit.base.api.util.MultiLineNameUtil;
+import jdplus.toolkit.base.api.util.NamedObject;
+import jdplus.toolkit.base.api.util.Paths;
+import nbbrd.design.VisibleForTesting;
+
+import java.io.File;
+import java.io.IOException;
+import java.time.ZoneId;
+import java.util.*;
+import java.util.Map.Entry;
+
+/**
+ * @author Kristof Bayens
+ */
+public final class SpreadsheetOutput implements Output {
+
+ private final SpreadsheetOutputConfiguration config;
+ private final SpreadsheetManager spreadsheetManager;
+ private final List summaries;
+ private File folder;
+
+ public SpreadsheetOutput(SpreadsheetOutputConfiguration config) {
+ this(config, SpreadsheetManager.ofServiceLoader());
+ }
+
+ @VisibleForTesting
+ SpreadsheetOutput(SpreadsheetOutputConfiguration config, SpreadsheetManager spreadsheetManager) {
+ this.config = config.clone();
+ this.spreadsheetManager = spreadsheetManager;
+ this.summaries = new ArrayList<>();
+ }
+
+ @Override
+ public void process(SaDocument document) {
+ Summary summary = Summary.of(document.getName(), document.getResults(), config.getSeries());
+// if (config_.isSaveModel()) {
+// summary.setModel(document.getSpecification());
+// }
+ summaries.add(summary);
+ }
+
+ @Override
+ public void start(Object context) {
+ summaries.clear();
+ folder = Paths.folderFromContext(config.getFolder(), context);
+ }
+
+ @Override
+ public void end(Object context) throws Exception {
+ File ssfile = getOutputFile();
+
+ Book.Factory factory = spreadsheetManager.getWriter(ssfile)
+ .orElseThrow(() -> new IOException("Cannot find spreadsheet writer for file '" + ssfile + "'"));
+
+ ArrayBook.Builder workbook = ArrayBook.builder();
+
+ switch (config.getLayout()) {
+ case ByComponent: {
+ Map>> allData = new LinkedHashMap<>();
+ for (Summary summary : summaries) {
+ String name = getDisplayName(summary);
+ summary.series().forEach((k, v) -> allData.computeIfAbsent(k, ignore -> new ArrayList<>()).add(new NamedObject<>(name, v)));
+ }
+ for (Entry>> keyValue : allData.entrySet()) {
+ String sheetName = keyValue.getKey();
+ List firstHeader = new ArrayList<>();
+ List secondHeader = new ArrayList<>();
+ List table = new ArrayList<>();
+
+ firstHeader.add(keyValue.getKey());
+ keyValue.getValue().forEach(data -> {
+ secondHeader.add(data.getName());
+ table.add(nullToEmpty(data.getName(), data.getObject()));
+ });
+
+ workbook.sheet(toSheet(sheetName, firstHeader, secondHeader, table, config.isVerticalOrientation()));
+ }
+ break;
+ }
+ case BySeries: {
+ for (int sheetIndex = 0; sheetIndex < summaries.size(); sheetIndex++) {
+ Summary summary = summaries.get(sheetIndex);
+
+ String sheetName = "Series" + sheetIndex;
+ List firstHeader = new ArrayList<>();
+ List secondHeader = new ArrayList<>();
+ List table = new ArrayList<>();
+
+ firstHeader.add(getDisplayName(summary));
+ summary.series().forEach((k, v) -> {
+ secondHeader.add(k);
+ table.add(nullToEmpty(k, v));
+ });
+
+ workbook.sheet(toSheet(sheetName, firstHeader, secondHeader, table, config.isVerticalOrientation()));
+ }
+ break;
+ }
+ case OneSheet: {
+ String sheetName = "Series";
+ List firstHeader = new ArrayList<>();
+ List secondHeader = new ArrayList<>();
+ List table = new ArrayList<>();
+
+ for (Summary summary : summaries) {
+ firstHeader.add(getDisplayName(summary));
+ for (int columnIndex = 1; columnIndex < summary.series().size(); columnIndex++) {
+ firstHeader.add(null);
+ }
+ summary.series().forEach((k, v) -> {
+ secondHeader.add(k);
+ table.add(nullToEmpty(k, v));
+ });
+ }
+
+ workbook.sheet(toSheet(sheetName, firstHeader, secondHeader, table, config.isVerticalOrientation()));
+ break;
+ }
+ }
+
+ factory.store(ssfile, workbook.build());
+ }
+
+ @Override
+ public String getName() {
+ return "Spreadsheet";
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ private File getOutputFile() {
+ return new File(folder, config.getFileName()).getAbsoluteFile();
+ }
+
+ private String getDisplayName(Summary summary) {
+ return config.isFullName() ? MultiLineNameUtil.join(summary.name(), " * ") : MultiLineNameUtil.last(summary.name());
+ }
+
+ private static TsData nullToEmpty(String k, TsData v) {
+ return v != null ? v : TsData.empty("MISSING " + k);
+ }
+
+ private static ArraySheet toSheet(String sheetName, List headers0, List headers1, List collection, boolean verticalOrientation) {
+ TsDataTable table = TsDataTable.of(collection);
+ ArraySheet.Builder result = ArraySheet.builder().name(sheetName);
+ if (verticalOrientation) {
+ //headers0
+ result.row(0, 1, headers0);
+ //headers1
+ result.row(1, 1, headers1);
+ //columnvalues & data
+ TsDataTable.Cursor cursor = table.cursor(TsDataTable.DistributionType.FIRST);
+ for (int p = 0; p < cursor.getPeriodCount(); p++) {
+ List
-
- org.junit.jupiter
- junit-jupiter-api
- 5.9.2
- test
-
-
- org.junit.jupiter
- junit-jupiter-params
- 5.9.2
- test
-
-
- org.junit.jupiter
- junit-jupiter-engine
- 5.9.2
- test
-
\ No newline at end of file
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/arima/ArimaSeriesGenerator.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/arima/ArimaSeriesGenerator.java
index c1e5f286..a0fca4cf 100644
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/arima/ArimaSeriesGenerator.java
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/arima/ArimaSeriesGenerator.java
@@ -16,6 +16,7 @@
*/
package jdplus.toolkit.base.core.arima;
+import jdplus.toolkit.base.api.dstats.ContinuousDistribution;
import jdplus.toolkit.base.core.data.DataBlock;
import jdplus.toolkit.base.core.dstats.Normal;
import jdplus.toolkit.base.core.math.matrices.FastMatrix;
@@ -45,7 +46,7 @@ public static class Builder {
private double startMean = 100;
private double startStdev = 10;
private final RandomNumberGenerator rng;
- private Distribution dist = new Normal();
+ private ContinuousDistribution dist = new Normal();
private Builder() {
rng = XorshiftRNG.fromSystemNanoTime();
@@ -72,7 +73,7 @@ public Builder initialWarmUp(int n) {
* @param distribution
* @return
*/
- public Builder distribution(Distribution distribution) {
+ public Builder distribution(ContinuousDistribution distribution) {
dist = distribution;
return this;
}
@@ -104,7 +105,7 @@ public static Builder builder(@NonNull RandomNumberGenerator rng) {
private final double startMean;
private final double startStdev;
private final RandomNumberGenerator rng;
- private final Distribution distribution;
+ private final ContinuousDistribution distribution;
public ArimaSeriesGenerator() {
this(new Builder());
@@ -265,7 +266,7 @@ public double[] generateStationary(final IArimaModel starima, final double mean,
return z;
}
- public static double[] generate(IArimaModel model, int n, double[] initial, Distribution distribution, int warmup) {
+ public static double[] generate(IArimaModel model, int n, double[] initial, ContinuousDistribution distribution, int warmup) {
Polynomial phi = model.getAr().asPolynomial();
int p = phi.degree();
if (initial.length < p) {
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/dstats/Poisson.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/dstats/Poisson.java
new file mode 100644
index 00000000..8eb3791e
--- /dev/null
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/dstats/Poisson.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2022 National Bank of Belgium
+ *
+ * Licensed under the EUPL, Version 1.2 or – as soon they will be approved
+ * by the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ *
+ * https://joinup.ec.europa.eu/software/page/eupl
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ */
+package jdplus.toolkit.base.core.dstats;
+
+import jdplus.toolkit.base.api.dstats.BoundaryType;
+import jdplus.toolkit.base.api.dstats.DStatException;
+import jdplus.toolkit.base.api.dstats.DiscreteDistribution;
+import jdplus.toolkit.base.api.dstats.RandomNumberGenerator;
+import jdplus.toolkit.base.api.stats.ProbabilityType;
+import jdplus.toolkit.base.core.stats.Combinatorics;
+
+/**
+ *
+ * @author palatej
+ */
+public class Poisson implements DiscreteDistribution {
+
+ private final double mu, emu;
+
+ public Poisson(double mu) {
+ this.mu = mu;
+ this.emu = Math.exp(-mu);
+ }
+
+ @Override
+ public long getLeftBound() {
+ return 0;
+ }
+
+ @Override
+ public long getRightBound() {
+ return Long.MAX_VALUE;
+ }
+
+ @Override
+ public String getDescription() {
+ return "Poisson - " + Double.toString(mu);
+ }
+
+ @Override
+ public double getExpectation() throws DStatException {
+ return mu;
+ }
+
+ @Override
+ public double getProbability(long x) throws DStatException {
+ double p;
+ double lf = Combinatorics.logFactorial(x);
+ p = Math.exp(Math.log(mu) * x - lf - mu);
+ return p;
+ }
+
+ @Override
+ public double getVariance() throws DStatException {
+ return mu;
+ }
+
+ @Override
+ public BoundaryType hasLeftBound() {
+ return BoundaryType.Finite;
+ }
+
+ @Override
+ public BoundaryType hasRightBound() {
+ return BoundaryType.None;
+ }
+
+ @Override
+ public boolean isSymmetrical() {
+ return false;
+ }
+
+ @Override
+ public long random(RandomNumberGenerator rng) throws DStatException {
+ int rndPoisson = -1;
+ double p = 1;
+ do {
+ p *= rng.nextDouble();
+ ++rndPoisson;
+ } while (p > emu);
+ return rndPoisson;
+ }
+
+}
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/linearfilters/AsymmetricFiltersFactory.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/linearfilters/AsymmetricFiltersFactory.java
index 0e68d91c..28bd5e1a 100644
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/linearfilters/AsymmetricFiltersFactory.java
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/linearfilters/AsymmetricFiltersFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 National Bank of Belgium.
+ * Copyright 2023 National Bank of Belgium.
*
* Licensed under the EUPL, Version 1.2 or – as soon they will be approved
* by the European Commission - subsequent versions of the EUPL (the "Licence");
@@ -35,12 +35,6 @@
@lombok.experimental.UtilityClass
public class AsymmetricFiltersFactory {
- public static enum Option {
- Direct,
- CutAndNormalize,
- MMSRE
- }
-
/**
*
* @param s
@@ -49,13 +43,13 @@ public static enum Option {
* @return
*/
public IFiniteFilter musgraveFilter(final SymmetricFilter s, final int q, double ic) {
- double r = 4 / (Math.PI * ic * ic);
double[] h = s.weightsToArray();
int n = s.length();
int l = (n - 1) / 2;
int m = l + q + 1;
double[] c = new double[m];
+ double r = Math.PI * ic * ic / 4;
for (int i = 0; i < m; i++) {
c[i] = h[i];
double p1 = 0.0, p2 = 0.0;
@@ -64,9 +58,8 @@ public IFiniteFilter musgraveFilter(final SymmetricFilter s, final int q, double
p2 += h[j] * ((j + 1) - (m + 1) / 2.0);
}
p1 /= m;
- p2 *= (((i + 1) - (m + 1) / 2.0) * r / (1 + (m * (m - 1) * (m + 1)
- * r * (1.0 / 12.0))));
- c[i] += (p1 + p2);
+ p2 *= ((i + 1) - (m + 1) / 2.0) / (r + m * (m - 1) * (m + 1) / 12.0);
+ c[i] += p1 + p2;
}
return FiniteFilter.ofInternal(c, -l);
}
@@ -201,10 +194,8 @@ public IFiniteFilter mmsreFilter(SymmetricFilter sw, int q, int u, double[] dz,
/**
* Extension of the usual asymmetric filters that introduces a timeliness
- * criterion,
- * "à la Guggemos".
- * See Grun-Rehomme, Guggemos and Ladiray, "Asymmetric Moving Averages
- * Minimizing Phase-Shift"
+ * criterion, "à la Guggemos". See Grun-Rehomme, Guggemos and Ladiray,
+ * "Asymmetric Moving Averages Minimizing Phase-Shift"
*
* @param sw
* @param q
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/linearfilters/CrossValidation.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/linearfilters/CrossValidation.java
index 8db34b20..b1e57ae5 100644
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/linearfilters/CrossValidation.java
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/linearfilters/CrossValidation.java
@@ -1,11 +1,24 @@
/*
- * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
- * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
+ * Copyright 2023 National Bank of Belgium.
+ *
+ * Licensed under the EUPL, Version 1.2 or – as soon they will be approved
+ * by the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ *
+ * https://joinup.ec.europa.eu/software/page/eupl
+ *
+ * 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 jdplus.toolkit.base.core.math.linearfilters;
import jdplus.toolkit.base.api.data.DoubleSeq;
import java.util.function.IntFunction;
+import jdplus.toolkit.base.core.math.linearfilters.SymmetricFilter;
/**
*
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/linearfilters/FilterUtility.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/linearfilters/FilterUtility.java
index d24de3f5..73237257 100644
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/linearfilters/FilterUtility.java
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/linearfilters/FilterUtility.java
@@ -36,20 +36,20 @@ public class FilterUtility {
final double EPS = 1e-9;
/**
- * Checks that the absolute values of all the given roots are higher
- * than the given limit.
+ * Checks that the absolute values of all the inverse of the given roots are
+ * lower than the given limit.
*
* @param roots The roots
- * @param amin The limit (positive number)
+ * @param rmin The limit (positive number)
* @return
*/
- public boolean checkRoots(final Complex[] roots, final double amin) {
- if (roots == null || amin < 0) {
+ public boolean checkRoots(final Complex[] roots, final double rmin) {
+ if (roots == null || rmin < 0) {
return true;
}
for (int i = 0; i < roots.length; ++i) {
double n = (roots[i].abs());
- if (n <= amin) {
+ if (1 / n >= rmin) {
return false;
}
}
@@ -57,49 +57,52 @@ public boolean checkRoots(final Complex[] roots, final double amin) {
}
/**
- * Checks that the norm of the roots of a given polynomial
+ * Checks that the norm of the inverse of the roots of a given polynomial
* are higher than rmin
*
* @param c The coefficients of the polynomial (excluding the constant,
- * which is considered as 1).
- * The polynomial is 1+c(0)x+...
- * @param rmin The limit of the roots
+ * which is considered as 1). The polynomial is 1+c(0)x+...
+ * @param rmin The limit of the inverse of the roots
* @return
*/
public boolean checkRoots(final DoubleSeq c, final double rmin) {
int nc = c.length();
switch (nc) {
- case 0:
+ case 0 -> {
return true;
- case 1:
+ }
+ case 1 -> {
double cabs = Math.abs(c.get(0));
- return (1 / cabs) > rmin;
- case 2:
+ return cabs < rmin;
+ }
+ case 2 -> {
double a = c.get(0),
- b = c.get(1);
+ b = c.get(1);
double ro = a * a - 4 * b;
if (ro > 0) { // Roots are (-a+-sqrt(ro))/(2b)
double sro = Math.sqrt(ro);
double x0 = (-a + sro) / (2 * b), x1 = (-a - sro) / (2 * b);
- return Math.abs(x0) > rmin && Math.abs(x1) > rmin;
+ return 1 / Math.abs(x0) < rmin && 1 / Math.abs(x1) < rmin;
} else // Roots are (-a+-isqrt(-ro))/(2b). Abs(roots) = (1/2b)*sqrt((a*a - a*a+4*b))=1/sqr(b)
// b is necessary positive
{
- return (1 / Math.sqrt(b)) > rmin;
+ return Math.sqrt(b) < rmin;
}
- default:
+ }
+ default -> {
double[] ctmp = new double[nc + 1];
ctmp[0] = 1;
c.copyTo(ctmp, 1);
Polynomial p = Polynomial.ofInternal(ctmp);
return checkRoots(p.roots(), rmin);
+ }
}
}
/**
- * Checks that the polynomial corresponding to the given coefficients
- * has all its roots outside the unit circle. Same as checkRoots(c, 1), but
- * more efficient.
+ * Checks that the polynomial corresponding to the given coefficients has
+ * all its roots outside the unit circle. Same as checkRoots(c, 1), but more
+ * efficient.
*
* @param c The coefficients of the polynomial. The polynomial is
* 1+c(0)x+...
@@ -162,13 +165,13 @@ public boolean checkStability(final Polynomial p) {
/**
* /**
- * Stabilize a given polynomial (all its roots will be > 1/rmin)
+ * Stabilize a given polynomial (all its roots will be >= 1/rmin)
*
* @param c The coefficients of the polynomial (excluding the constant,
- * which is considered as 1).
- * The polynomial is 1+c(0)x+...
- * @param rmin The inverse of the limit of the roots
- * @return true if some coefficients where changed , false otherwise
+ * which is considered as 1). The polynomial is 1+c(0)x+...
+ * @param rmin The limit of the inverse of the roots (all abs of the roots
+ * will be >= 1/rmin)
+ * @return true if some coefficients where changed, false otherwise
*/
public boolean stabilize(DoubleSeq.Mutable c, double rmin) {
int nc = c.length();
@@ -177,15 +180,16 @@ public boolean stabilize(DoubleSeq.Mutable c, double rmin) {
}
if (nc == 1) {
double c0 = c.get(0);
- double cabs = Math.abs(c0);
- if (cabs < rmin) {
+ double rabs = Math.abs(c0);
+ if (rabs < rmin) {
return false;
}
-
- if (rmin < 1) {
- c.set(0, c0 > 0 ? rmin : -rmin);
- } else {
+ if (rabs > 1 / rmin) {
c.set(0, 1 / c0);
+ } else {
+ // in [rmin, 1/rmin]
+ // we put it nearly on the boundary
+ c.set(0, c0 > 0 ? rmin - EPS : -rmin + EPS);
}
return true;
}
@@ -201,6 +205,7 @@ public boolean stabilize(DoubleSeq.Mutable c, double rmin) {
}
return true;
}
+
return false;
}
@@ -210,8 +215,7 @@ public boolean stabilize(DoubleSeq.Mutable c, double rmin) {
* @param p
* @param rmin
* @return A new polynomial is returned if the initial polynomial was not
- * stable
- * (= some roots were higher than rmin
+ * stable (= some roots were lower than 1/rmin)
*/
public Polynomial stabilize(Polynomial p, double rmin) {
if (p == null) {
@@ -222,14 +226,15 @@ public Polynomial stabilize(Polynomial p, double rmin) {
boolean changed = false;
for (int i = 0; i < roots.length; ++i) {
Complex root = roots[i];
- double n = 1 / roots[i].abs();
- if (n > rmin) {
- if (rmin < 1) {
- roots[i] = root.times(n / rmin);
- } else if (n > 1) {
- roots[i] = root.inv();
-
+ double n = roots[i].abs();
+ if (n < 1 / rmin) {
+ if (n < 1) {
+ root = root.inv();
}
+ if (n > rmin) {
+ root = root.div(rmin - EPS);
+ }
+ roots[i] = root;
changed = true;
}
}
@@ -263,7 +268,8 @@ public double[] compact(final double[] data) {
}
/**
- * Computes the frequency response (f(w)=sum(w(t)e(iwt))=sum(w(t)(cos(wt)+i*sin(wt)))
+ * Computes the frequency response
+ * (f(w)=sum(w(t)e(iwt))=sum(w(t)(cos(wt)+i*sin(wt)))
*
* @param c
* @param lb Lower bound (included)
@@ -365,6 +371,25 @@ public DoubleSeq filter(DoubleSeq input, final SymmetricFilter filter, final IFi
return DoubleSeq.of(x);
}
+ public void inPlaceFilter(DoubleSeq input, DataBlock output, final SymmetricFilter filter, final IFiniteFilter[] afilters) {
+ int h = filter.getUpperBound(), ilen = input.length();
+ DataBlock out = output.drop(h, h);
+ filter.apply(input, out);
+
+ // apply the endpoints filters
+ if (afilters != null) {
+ for (int i = 0, j = h - 1, k = ilen - h, len = 2 * h; i < h; ++i, --len, --j, ++k) {
+ output.set(j, afilters[i].apply(input.extract(0, len).reverse()));
+ output.set(k, afilters[i].apply(input.extract(ilen - len, len)));
+ }
+ } else {
+ for (int i = 0; i < h; ++i) {
+ output.set(i, Double.NaN);
+ output.set(ilen - i - 1, Double.NaN);
+ }
+ }
+ }
+
/**
* Applies the given central filter on a sequence of input. The end-points
* are handled using given asymmetric filters or set to NaN.
@@ -410,4 +435,33 @@ public DoubleSeq filter(DoubleSeq input, final IFiniteFilter filter, final IFini
}
return DoubleSeq.of(x);
}
+
+ public void inPlaceFilter(DoubleSeq input, DataBlock output, final IFiniteFilter filter, final IFiniteFilter[] leftFilters, final IFiniteFilter[] rightFilters) {
+ int l = -filter.getLowerBound(), u = filter.getUpperBound(), ilen = input.length();
+ DataBlock out = output.drop(l, u);
+ filter.apply(input, out);
+
+ // apply the endpoints filters
+ if (leftFilters != null) {
+ for (int i = 0, j = l - 1; i < l; ++i, --j) {
+ IFiniteFilter cur = leftFilters[i];
+ output.set(j, cur.apply(input.extract(j + cur.getLowerBound(), cur.length())));
+ }
+ } else {
+ for (int i = 0; i < l; ++i) {
+ output.set(i, Double.NaN);
+ }
+ }
+ if (rightFilters != null) {
+ for (int i = 0, j = ilen - u; i < u; ++i, ++j) {
+ IFiniteFilter cur = rightFilters[i];
+ output.set(j, cur.apply(input.extract(j + cur.getLowerBound(), cur.length())));
+ }
+ } else {
+ for (int i = 0; i < l; ++i) {
+ output.set(ilen - i - 1, Double.NaN);
+ }
+ }
+ }
+
}
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/linearfilters/Filtering.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/linearfilters/Filtering.java
new file mode 100644
index 00000000..67f0c8d0
--- /dev/null
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/linearfilters/Filtering.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2023 National Bank of Belgium.
+ *
+ * Licensed under the EUPL, Version 1.2 or – as soon they will be approved
+ * by the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ *
+ * https://joinup.ec.europa.eu/software/page/eupl
+ *
+ * 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 jdplus.toolkit.base.core.math.linearfilters;
+
+import jdplus.toolkit.base.api.data.DoubleSeq;
+import jdplus.toolkit.base.core.math.polynomials.Polynomial;
+import jdplus.toolkit.base.api.math.matrices.Matrix;
+import jdplus.toolkit.base.core.data.DataBlock;
+
+/**
+ *
+ * @author PALATEJ
+ */
+public class Filtering implements IFiltering {
+
+ private final IFiniteFilter cf;
+ private final IFiniteFilter[] lf;
+ private final IFiniteFilter[] rf;
+
+ public Filtering(IFiniteFilter cf, IFiniteFilter[] lf, IFiniteFilter[] rf) {
+ this.cf = cf;
+ this.lf = lf.clone();
+ this.rf = rf.clone();
+ }
+
+ public static Filtering of(DoubleSeq cf, Matrix lf, Matrix rf) {
+ int lb = lf.getColumnsCount(), rb = rf.getColumnsCount();
+ if (cf.length() != lb + rb + 1) {
+ throw new IllegalArgumentException();
+ }
+ FiniteFilter fcf = new FiniteFilter(Polynomial.of(cf.toArray()), -lb);
+ IFiniteFilter[] flf = new IFiniteFilter[lb];
+ for (int i = 0; i < lb; ++i) {
+ flf[i] = new FiniteFilter(lfilter(lf.column(i)), i - lb + 1);
+ }
+ IFiniteFilter[] frf = new IFiniteFilter[rb];
+ for (int i = 0; i < rb; ++i) {
+ Polynomial r = rfilter(rf.column(i));
+ frf[i] = new FiniteFilter(r, rb-i-r.degree()-1);
+ }
+ return new Filtering(fcf, flf, frf);
+ }
+
+ public static Filtering of(DoubleSeq cf, Matrix lf) {
+ int l = lf.getColumnsCount();
+ if (cf.length() != 2 * l + 1) {
+ throw new IllegalArgumentException();
+ }
+ FiniteFilter fcf = new FiniteFilter(Polynomial.of(cf.toArray()), -l);
+ IFiniteFilter[] flf = new IFiniteFilter[l];
+ IFiniteFilter[] frf = new IFiniteFilter[l];
+ for (int i = 0; i < l; ++i) {
+ FiniteFilter f = new FiniteFilter(lfilter(lf.column(i)), i - l + 1);
+ flf[i] = f;
+ frf[i] = f.mirror();
+ }
+ return new Filtering(fcf, flf, frf);
+ }
+
+ private static Polynomial lfilter(DoubleSeq col) {
+ int n = col.length(), pos = n - 1;
+ while (pos > 0) {
+ double cur = col.get(pos);
+ if (cur != 0) {
+ break;
+ }
+ --pos;
+ }
+ return Polynomial.raw(col.extract(0, pos + 1).toArray());
+ }
+
+ private static Polynomial rfilter(DoubleSeq col) {
+ int n = col.length(), pos = 0;
+ while (pos < n) {
+ double cur = col.get(pos);
+ if (cur != 0) {
+ break;
+ }
+ ++pos;
+ }
+ return Polynomial.raw(col.range(pos, n).toArray());
+ }
+
+ @Override
+ public IFiniteFilter centralFilter() {
+ return cf;
+ }
+
+ @Override
+ public IFiniteFilter[] leftEndPointsFilters() {
+ return lf.clone();
+ }
+
+ @Override
+ public IFiniteFilter[] rightEndPointsFilters() {
+ return rf.clone();
+ }
+
+}
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/linearfilters/FiltersToolkit.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/linearfilters/FiltersToolkit.java
new file mode 100644
index 00000000..8a8be06b
--- /dev/null
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/linearfilters/FiltersToolkit.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright 2023 National Bank of Belgium
+ *
+ * Licensed under the EUPL, Version 1.2 or – as soon they will be approved
+ * by the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ *
+ * https://joinup.ec.europa.eu/software/page/eupl
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ */
+package jdplus.toolkit.base.core.math.linearfilters;
+
+import java.util.HashMap;
+import jdplus.toolkit.base.api.information.InformationMapping;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.function.DoubleUnaryOperator;
+import java.util.function.Function;
+import java.util.function.IntToDoubleFunction;
+import jdplus.toolkit.base.api.information.GenericExplorable;
+import jdplus.toolkit.base.api.math.linearfilters.FilterSpec;
+import jdplus.toolkit.base.api.math.linearfilters.HendersonSpec;
+import jdplus.toolkit.base.api.math.linearfilters.LocalPolynomialFilterSpec;
+import jdplus.toolkit.base.api.math.linearfilters.UserDefinedFilterSpec;
+import jdplus.toolkit.base.api.math.linearfilters.UserDefinedSymmetricFilterSpec;
+
+/**
+ *
+ * @author Jean Palate
+ */
+@lombok.experimental.UtilityClass
+public class FiltersToolkit {
+
+ private final Map< Class, Function> map = new HashMap<>();
+
+ static {
+ map.put(HendersonSpec.class, spec -> HendersonFilters.of((HendersonSpec) spec));
+ map.put(LocalPolynomialFilterSpec.class, spec -> LocalPolynomialFilters.of((LocalPolynomialFilterSpec) spec));
+ map.put(UserDefinedSymmetricFilterSpec.class, spec ->{
+ if (spec instanceof UserDefinedSymmetricFilterSpec uspec){
+ return Filtering.of(uspec.getCentralFilter(), uspec.getEndPointsFilters());
+ }else
+ return null;
+ } );
+ map.put(UserDefinedFilterSpec.class, spec ->{
+ if (spec instanceof UserDefinedFilterSpec uspec){
+ return Filtering.of(uspec.getCentralFilter(), uspec.getLFilters(), uspec.getUFilters());
+ }else
+ return null;
+ } );
+ }
+
+ public void register(Class spec, Function fn) {
+ synchronized (map) {
+ map.put(spec, (Function) fn);
+ }
+ }
+
+ public void unregister(Class spec) {
+ synchronized (map) {
+ map.remove(spec);
+ }
+ }
+
+ public IFiltering of(FilterSpec spec){
+ synchronized(map){
+ Function fn=map.get(spec.getClass());
+ if (fn == null)
+ throw new LinearFilterException("Filter spec not registered");
+ return fn.apply(spec);
+ }
+ }
+
+ @lombok.Value
+ @lombok.AllArgsConstructor
+ @lombok.Builder
+ public static class FiniteFilters implements GenericExplorable {
+
+ private SymmetricFilter filter;
+ private IFiniteFilter[] afilters;
+
+ private static final InformationMapping MAPPING = new InformationMapping() {
+ @Override
+ public Class getSourceClass() {
+ return FiniteFilters.class;
+ }
+ };
+
+ public static final InformationMapping getMapping() {
+ return MAPPING;
+ }
+
+ @Override
+ public boolean contains(String id) {
+ return MAPPING.contains(id);
+ }
+
+ @Override
+ public Map getDictionary() {
+ Map dic = new LinkedHashMap<>();
+ MAPPING.fillDictionary(null, dic, true);
+ return dic;
+ }
+
+ @Override
+ public T getData(String id, Class tclass) {
+ return MAPPING.getData(this, id, tclass);
+ }
+
+ static {
+ MAPPING.set("svariancereduction", Double.class, source -> varianceReduction(source.filter));
+ MAPPING.setArray("avariancereduction", 0, Double.class, (source, i)
+ -> i < source.afilters[i].length() ? varianceReduction(source.afilters[i]) : Double.NaN);
+ MAPPING.set("sbias2", Double.class, source -> bias2(source.filter));
+ MAPPING.setArray("abias0", 0, Double.class, (source, i)
+ -> i < source.afilters[i].length() ? bias0(source.afilters[i]) : Double.NaN);
+ MAPPING.setArray("abias1", 0, Double.class, (source, i)
+ -> i < source.afilters[i].length() ? bias1(source.afilters[i]) : Double.NaN);
+ MAPPING.setArray("abias2", 0, Double.class, (source, i)
+ -> i < source.afilters[i].length() ? bias2(source.afilters[i]) : Double.NaN);
+ MAPPING.set("sweights", double[].class, source -> source.filter.weightsToArray());
+ MAPPING.setArray("aweights", 0, double[].class, (source, i) -> i < source.afilters[i].length() ? source.afilters[i].weightsToArray() : null);
+ MAPPING.set("sgain", double[].class, source -> gain(source.filter));
+ MAPPING.setArray("again", 0, double[].class, (source, i) -> i < source.afilters[i].length() ? gain(source.afilters[i]) : null);
+ MAPPING.setArray("aphase", 0, double[].class, (source, i) -> i < source.afilters[i].length() ? phase(source.afilters[i]) : null);
+ }
+ }
+
+ public double[] gain(IFilter filter) {
+ DoubleUnaryOperator gainFunction = filter.gainFunction();
+ int RES = 600;
+ double[] g = new double[RES + 1];
+ for (int i = 0; i <= RES; ++i) {
+ g[i] = gainFunction.applyAsDouble(i * Math.PI / 600);
+ }
+ return g;
+ }
+
+ public double varianceReduction(IFiniteFilter filter) {
+ double s = 0;
+ int l = filter.getLowerBound(), u = filter.getUpperBound();
+ IntToDoubleFunction weights = filter.weights();
+ for (int i = l; i <= u; ++i) {
+ double w = weights.applyAsDouble(i);
+ s += w * w;
+ }
+ return s;
+ }
+
+ public double bias0(IFiniteFilter filter) {
+ double s = 0;
+ int l = filter.getLowerBound(), u = filter.getUpperBound();
+ IntToDoubleFunction weights = filter.weights();
+ for (int i = l; i <= u; ++i) {
+ double w = weights.applyAsDouble(i);
+ s += w;
+ }
+ return s;
+ }
+
+ public double bias1(IFiniteFilter filter) {
+ double s = 0;
+ int l = filter.getLowerBound(), u = filter.getUpperBound();
+ IntToDoubleFunction weights = filter.weights();
+ for (int i = l; i <= u; ++i) {
+ double w = i * weights.applyAsDouble(i);
+ s += w;
+ }
+ return s;
+ }
+
+ public double bias2(IFiniteFilter filter) {
+ double s = 0;
+ int l = filter.getLowerBound(), u = filter.getUpperBound();
+ IntToDoubleFunction weights = filter.weights();
+ for (int i = l; i <= u; ++i) {
+ double w = i * i * weights.applyAsDouble(i);
+ s += w;
+ }
+ return s;
+ }
+
+ public double[] phase(IFilter filter) {
+ DoubleUnaryOperator phaseFunction = filter.phaseFunction();
+ int RES = 600;
+ double[] g = new double[RES + 1];
+ for (int i = 0; i <= RES; ++i) {
+ g[i] = phaseFunction.applyAsDouble(i * Math.PI / 600);
+ }
+ return g;
+ }
+}
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/linearfilters/HendersonFilters.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/linearfilters/HendersonFilters.java
index 088deb5a..da95117b 100644
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/linearfilters/HendersonFilters.java
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/linearfilters/HendersonFilters.java
@@ -19,6 +19,7 @@
import nbbrd.design.Development;
import java.util.HashMap;
import java.util.Map;
+import jdplus.toolkit.base.api.math.linearfilters.HendersonSpec;
/**
*
@@ -64,4 +65,12 @@ public synchronized SymmetricFilter ofLength(int length) {
FILTERSTORE.put(length, filter);
return filter;
}
+
+ public IQuasiSymmetricFiltering of(HendersonSpec spec){
+
+ SymmetricFilter sf=ofLength(1+2*spec.getFilterHorizon());
+ IFiniteFilter[] rf = AsymmetricFiltersFactory.musgraveFilters(sf, spec.getRightIcRatio());
+ IFiniteFilter[] lf = ISymmetricFiltering.mirror(spec.isSymmetric() ? rf :AsymmetricFiltersFactory.musgraveFilters(sf, spec.getLeftIcRatio()));
+ return new QuasiSymmetricFiltering(sf, lf, rf);
+ }
}
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/linearfilters/IFiltering.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/linearfilters/IFiltering.java
new file mode 100644
index 00000000..1503233e
--- /dev/null
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/linearfilters/IFiltering.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2023 National Bank of Belgium.
+ *
+ * Licensed under the EUPL, Version 1.2 or – as soon they will be approved
+ * by the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ *
+ * https://joinup.ec.europa.eu/software/page/eupl
+ *
+ * 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 jdplus.toolkit.base.core.math.linearfilters;
+
+import jdplus.toolkit.base.api.data.DoubleSeq;
+import jdplus.toolkit.base.core.data.DataBlock;
+
+/**
+ *
+ * @author Jean Palate
+ */
+public interface IFiltering {
+ /**
+ * Applies a filter on an input to produce an output.
+ * The input and the output must have the same length
+ * @param in
+ * @return
+ */
+ default DoubleSeq process(DoubleSeq in) {
+ return FilterUtility.filter(in, centralFilter(), leftEndPointsFilters(), rightEndPointsFilters());
+ }
+
+ default void inPlaceProcess(DoubleSeq in, DataBlock out) {
+ FilterUtility.inPlaceFilter(in, out, centralFilter(), leftEndPointsFilters(), rightEndPointsFilters());
+ }
+
+ IFiniteFilter centralFilter();
+
+ IFiniteFilter[] leftEndPointsFilters();
+ IFiniteFilter[] rightEndPointsFilters();
+}
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/linearfilters/IQuasiSymmetricFiltering.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/linearfilters/IQuasiSymmetricFiltering.java
new file mode 100644
index 00000000..d4f0c4b3
--- /dev/null
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/linearfilters/IQuasiSymmetricFiltering.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2023 National Bank of Belgium.
+ *
+ * Licensed under the EUPL, Version 1.2 or – as soon they will be approved
+ * by the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ *
+ * https://joinup.ec.europa.eu/software/page/eupl
+ *
+ * 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 jdplus.toolkit.base.core.math.linearfilters;
+
+/**
+ *
+ * @author Jean Palate
+ */
+public interface IQuasiSymmetricFiltering extends IFiltering{
+
+ @Override
+ SymmetricFilter centralFilter();
+
+
+}
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/linearfilters/ISymmetricFiltering.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/linearfilters/ISymmetricFiltering.java
new file mode 100644
index 00000000..36a72581
--- /dev/null
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/linearfilters/ISymmetricFiltering.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2023 National Bank of Belgium.
+ *
+ * Licensed under the EUPL, Version 1.2 or – as soon they will be approved
+ * by the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ *
+ * https://joinup.ec.europa.eu/software/page/eupl
+ *
+ * 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 jdplus.toolkit.base.core.math.linearfilters;
+
+import jdplus.toolkit.base.api.data.DoubleSeq;
+import jdplus.toolkit.base.core.data.DataBlock;
+
+/**
+ *
+ * Same (mirror) end points filters
+ * @author Jean Palate
+ */
+public interface ISymmetricFiltering extends IQuasiSymmetricFiltering{
+
+ @Override
+ default DoubleSeq process(DoubleSeq in) {
+ return FilterUtility.filter(in, centralFilter(), endPointsFilters());
+ }
+
+
+ @Override
+ default void inPlaceProcess(DoubleSeq in, DataBlock out) {
+ FilterUtility.inPlaceFilter(in, out, centralFilter(), endPointsFilters());
+ }
+
+ IFiniteFilter[] endPointsFilters();
+
+ @Override
+ default IFiniteFilter[] leftEndPointsFilters(){
+ return mirror(endPointsFilters());
+ }
+
+ @Override
+ default IFiniteFilter[] rightEndPointsFilters(){
+ return endPointsFilters();
+ }
+
+ public static IFiniteFilter[] mirror(IFiniteFilter[] rightEndPoints){
+ IFiniteFilter[] lf=rightEndPoints.clone();
+ for (int i=0; i
+ DiscreteKernel.biweight(len);
+ case TriWeight ->
+ DiscreteKernel.triweight(len);
+ case Uniform ->
+ DiscreteKernel.uniform(len);
+ case Triangular ->
+ DiscreteKernel.triangular(len);
+ case Epanechnikov ->
+ DiscreteKernel.epanechnikov(len);
+ case Henderson ->
+ DiscreteKernel.henderson(len);
+ default ->
+ null;
+ };
+ }
+
+ private static class SFilter implements ISymmetricFiltering {
+
+ private final SymmetricFilter symmetricFilter;
+ private final IFiniteFilter[] asymmetricFilters;
+
+ private SFilter(LocalPolynomialFilterSpec spec) {
+ int len = spec.getFilterHorizon();
+ symmetricFilter = ofDefault(len, spec.getPolynomialDegree(), kernel(spec));
+ asymmetricFilters = switch (spec.getAsymmetricFilters()) {
+ case CutAndNormalize ->
+ AsymmetricFiltersFactory.cutAndNormalizeFilters(symmetricFilter);
+ case MMSRE ->
+ AsymmetricFiltersFactory.mmsreFilters(symmetricFilter,
+ spec.getAsymmetricPolynomialDegree(), spec.getRightLinearModelCoefficients(), null,
+ spec.getPassBand(), spec.getTimelinessWeight());
+ default ->
+ directAsymmetricFilters(len, spec.getPolynomialDegree(), kernel(spec));
+ };
+ }
+
+ @Override
+ public DoubleSeq process(DoubleSeq in) {
+ return FilterUtility.filter(in, symmetricFilter, asymmetricFilters);
+ }
+
+ @Override
+ public SymmetricFilter centralFilter() {
+ return symmetricFilter;
+ }
+
+ @Override
+ public IFiniteFilter[] endPointsFilters() {
+ return asymmetricFilters;
+ }
+ }
+
+ private static class Filter implements IQuasiSymmetricFiltering {
+
+ private final SymmetricFilter symmetricFilter;
+ private final IFiniteFilter[] leftAsymmetricFilters, rightAsymmetricFilters;
+
+ private Filter(LocalPolynomialFilterSpec spec) {
+ int len = spec.getFilterHorizon();
+ symmetricFilter = ofDefault(len, spec.getPolynomialDegree(), kernel(spec));
+ rightAsymmetricFilters = switch (spec.getAsymmetricFilters()) {
+ case CutAndNormalize ->
+ AsymmetricFiltersFactory.cutAndNormalizeFilters(symmetricFilter);
+ case MMSRE ->
+ AsymmetricFiltersFactory.mmsreFilters(symmetricFilter,
+ spec.getAsymmetricPolynomialDegree(), spec.getRightLinearModelCoefficients(), null,
+ spec.getPassBand(), spec.getTimelinessWeight());
+ default ->
+ directAsymmetricFilters(len, spec.getPolynomialDegree(), kernel(spec));
+ };
+ leftAsymmetricFilters = ISymmetricFiltering.mirror(switch (spec.getAsymmetricFilters()) {
+ case MMSRE ->
+ AsymmetricFiltersFactory.mmsreFilters(symmetricFilter,
+ spec.getAsymmetricPolynomialDegree(), spec.getLeftLinearModelCoefficients(), null,
+ spec.getPassBand(), spec.getTimelinessWeight());
+ default ->
+ rightAsymmetricFilters;
+ });
+ }
+
+ @Override
+ public DoubleSeq process(DoubleSeq in) {
+ return FilterUtility.filter(in, symmetricFilter, leftAsymmetricFilters, rightAsymmetricFilters);
+ }
+
+ @Override
+ public SymmetricFilter centralFilter() {
+ return symmetricFilter;
+ }
+
+ @Override
+ public IFiniteFilter[] leftEndPointsFilters() {
+ return leftAsymmetricFilters;
+ }
+
+ @Override
+ public IFiniteFilter[] rightEndPointsFilters() {
+ return rightAsymmetricFilters;
+ }
+ }
+
/**
*
* @param h the number of lags (-> length of the filter is 2*h+1)
@@ -46,9 +165,12 @@ public class LocalPolynomialFilters {
*/
public SymmetricFilter of(final int h, final int d, final IntToDoubleFunction k) {
return switch (d) {
- case 0, 1 -> of0_1(h, k);
- case 2, 3 -> of2_3(h, k);
- default -> ofDefault(h, d, k);
+ case 0, 1 ->
+ of0_1(h, k);
+ case 2, 3 ->
+ of2_3(h, k);
+ default ->
+ ofDefault(h, d, k);
};
}
@@ -77,9 +199,7 @@ public FiniteFilter directAsymmetricFilter(final int h, final int q, final int d
}
double[] u = new double[d + 1];
u[0] = 1;
-// Householder hous = new Householder(xkx);
-// hous.solve(DataBlock.of(u));
- LinearSystemSolver.fastSolver().solve(xkx, DataBlock.of(u));
+ LinearSystemSolver.robustSolver().solve(xkx, DataBlock.of(u));
double[] w = new double[h + q + 1];
w[h] = u[0] * k.applyAsDouble(0);
for (int i = 1; i <= q; ++i) {
@@ -107,8 +227,8 @@ public FiniteFilter directAsymmetricFilter(final int h, final int q, final int d
public FiniteFilter[] directAsymmetricFilters(int h, final int d, final IntToDoubleFunction k) {
FiniteFilter[] ff = new FiniteFilter[h];
- for (int i = 0; i < h; ++i) {
- ff[i] = directAsymmetricFilter(h, i, d, k);
+ for (int i = 0, j = h - 1; i < h; ++i, --j) {
+ ff[i] = directAsymmetricFilter(h, j, d, k);
}
return ff;
}
@@ -149,7 +269,7 @@ private static SymmetricFilter of2_3(int h, IntToDoubleFunction k) {
// SymmetricFilter ofDefault2(int h, int d, IntToDoubleFunction k) {
// // w = KX (X'K X)^-1 e1
// // (X'K X)^-1 e1 = u <-> (X'K X) u = e1
-// CanonicalMatrix xkx = CanonicalMatrix.square(d + 1);
+// FastMatrix xkx = FastMatrix.square(d + 1);
// for (int i = 0; i <= d; ++i) {
// xkx.set(i, i, S_hd(h, 2 * i, k));
// for (int j = 0; j < i; ++j) {
@@ -184,7 +304,7 @@ private static SymmetricFilter of2_3(int h, IntToDoubleFunction k) {
* @param k The kernel (a uniform kernel is used if k is null)
* @return
*/
- SymmetricFilter ofDefault(int h, int d, IntToDoubleFunction k) {
+ public SymmetricFilter ofDefault(int h, int d, IntToDoubleFunction k) {
double[] sk = new double[h + 1];
if (k == null) {
for (int i = 0; i < sk.length; ++i) {
@@ -197,6 +317,7 @@ SymmetricFilter ofDefault(int h, int d, IntToDoubleFunction k) {
sk[i] = Math.sqrt(ki);
}
}
+
}
FastMatrix Z = createZ(h, d);
DataBlockIterator rows = Z.rowsIterator();
@@ -205,8 +326,7 @@ SymmetricFilter ofDefault(int h, int d, IntToDoubleFunction k) {
rows.next().mul(sk[Math.abs(pos++)]);
}
- Householder2 hous = new Householder2();
- QRDecomposition qr = hous.decompose(Z);
+ QRDecomposition qr = new Householder2().decompose(Z);
double[] z = new double[Z.getRowsCount()];
z[0] = 1;
UpperTriangularMatrix.solvexU(qr.rawR(), DataBlock.of(z, 0, d + 1, 1));
@@ -226,6 +346,50 @@ private double S_h0(int h, IntToDoubleFunction k) {
return 2 * s + k.applyAsDouble(0);
}
+// private double S_h2(int h, IntToDoubleFunction k) {
+// double s = 0;
+// for (int i = 1; i <= h; ++i) {
+// double j = i * i;
+// s += j * k.applyAsDouble(i);
+// }
+// return 2 * s;
+// }
+//
+// private double S_h4(int h, IntToDoubleFunction k) {
+// double s = 0;
+// for (int i = 1; i <= h; ++i) {
+// double j = i * i;
+// j *= j;
+// s += j * k.applyAsDouble(i);
+// }
+// return 2 * s;
+// }
+//
+// private double S_hd(int h, int d, IntToDoubleFunction k) {
+// switch (d) {
+// case 0:
+// return S_h0(h, k);
+// case 2:
+// return S_h2(h, k);
+// case 4:
+// return S_h4(h, k);
+// }
+// if (d % 2 != 0) {
+// return 0;
+// }
+// int hd = d / 2;
+// double s = 0;
+// for (int i = 1; i <= h; ++i) {
+// double ii = i * i;
+// double j = ii;
+// for (int l = 2; l <= hd; ++l) {
+// j *= ii;
+// }
+// s += j * k.applyAsDouble(i);
+// }
+// return 2 * s;
+// }
+//
private double S_hqd(int h, int q, long d, IntToDoubleFunction k) {
if (d == 0) {
return S_hq0(h, q, k);
@@ -276,9 +440,9 @@ private double S_hq0(int h, int q, IntToDoubleFunction k) {
*/
public FastMatrix z(FastMatrix Z, int l, int u, int d0, int d1) {
int nh = Math.max(Math.abs(l), Math.abs(u));
-// if (Z == null || Z.getRowsCount() / 2 < nh || Z.getColumnsCount() < d1 + 1) {
-// Z = createZ(nh, d1);
-// }
+ if (Z == null || Z.getRowsCount() / 2 < nh || Z.getColumnsCount() < d1 + 1) {
+ Z = createZ(nh, d1);
+ }
return Z.extract(l + nh, u - l + 1, d0, d1 - d0 + 1);
}
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/linearfilters/QuasiSymmetricFiltering.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/linearfilters/QuasiSymmetricFiltering.java
new file mode 100644
index 00000000..edd70eab
--- /dev/null
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/linearfilters/QuasiSymmetricFiltering.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2023 National Bank of Belgium.
+ *
+ * Licensed under the EUPL, Version 1.2 or – as soon they will be approved
+ * by the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ *
+ * https://joinup.ec.europa.eu/software/page/eupl
+ *
+ * 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 jdplus.toolkit.base.core.math.linearfilters;
+
+/**
+ *
+ * @author PALATEJ
+ */
+public class QuasiSymmetricFiltering implements IQuasiSymmetricFiltering {
+
+ private final SymmetricFilter cf;
+ private final IFiniteFilter[] lf;
+ private final IFiniteFilter[] rf;
+
+ public QuasiSymmetricFiltering(SymmetricFilter cf, IFiniteFilter[] lf, IFiniteFilter[] rf) {
+ this.cf = cf;
+ this.lf = lf.clone();
+ this.rf = rf.clone();
+ }
+
+ @Override
+ public SymmetricFilter centralFilter() {
+ return cf;
+ }
+
+ @Override
+ public IFiniteFilter[] leftEndPointsFilters() {
+ return lf.clone();
+ }
+
+ @Override
+ public IFiniteFilter[] rightEndPointsFilters() {
+ return rf.clone();
+ }
+
+
+}
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/linearfilters/SymmetricFiltering.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/linearfilters/SymmetricFiltering.java
new file mode 100644
index 00000000..ed8707f1
--- /dev/null
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/linearfilters/SymmetricFiltering.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2023 National Bank of Belgium.
+ *
+ * Licensed under the EUPL, Version 1.2 or – as soon they will be approved
+ * by the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ *
+ * https://joinup.ec.europa.eu/software/page/eupl
+ *
+ * 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 jdplus.toolkit.base.core.math.linearfilters;
+
+import jdplus.toolkit.base.api.data.DoubleSeq;
+import jdplus.toolkit.base.core.data.DataBlock;
+
+/**
+ *
+ * @author PALATEJ
+ */
+public class SymmetricFiltering implements ISymmetricFiltering {
+
+ private final SymmetricFilter cf;
+ private final IFiniteFilter[] ff;
+
+ public SymmetricFiltering(SymmetricFilter cf, IFiniteFilter[] endPoints) {
+ this.cf = cf;
+ this.ff = endPoints.clone();
+ }
+
+ @Override
+ public SymmetricFilter centralFilter() {
+ return cf;
+ }
+
+ @Override
+ public IFiniteFilter[] endPointsFilters() {
+ return ff;
+ }
+
+
+}
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/matrices/FastMatrix.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/matrices/FastMatrix.java
index 3d26cc00..9cc201dc 100644
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/matrices/FastMatrix.java
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/math/matrices/FastMatrix.java
@@ -1079,6 +1079,10 @@ public DataBlock column(int r0, int c0, int n) {
return DataBlock.of(storage, beg, end, 1);
}
+ /**
+ *
+ * @return An array containing the sum of each rows (size=number of rows)
+ */
public DataBlock rowSums() {
if (isEmpty()) {
return DataBlock.EMPTY;
@@ -1091,6 +1095,10 @@ public DataBlock rowSums() {
return x;
}
+ /**
+ *
+ * @return An array containing the sum of each columns (size=number of columns)
+ */
public DataBlock columnSums() {
if (isEmpty()) {
return DataBlock.EMPTY;
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/regsarima/RegSarimaComputer.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/regsarima/RegSarimaComputer.java
index ee58cb66..b4fbca80 100644
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/regsarima/RegSarimaComputer.java
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/regsarima/RegSarimaComputer.java
@@ -35,7 +35,7 @@
import jdplus.toolkit.base.core.regsarima.internal.HannanRissanenInitializer;
import jdplus.toolkit.base.core.sarima.SarimaModel;
import jdplus.toolkit.base.core.sarima.estimation.SarimaFixedMapping;
-import jdplus.toolkit.base.core.sarima.estimation.SarimaMapping;
+import jdplus.toolkit.base.core.sarima.estimation.SarimaMapping2;
import jdplus.toolkit.base.core.stats.likelihood.ConcentratedLikelihoodWithMissing;
import jdplus.toolkit.base.core.stats.likelihood.LogLikelihoodFunction;
import nbbrd.design.BuilderPattern;
@@ -149,7 +149,7 @@ public RegSarimaComputer(SsqFunctionMinimizer.Builder min, final double eps, fin
public RegArimaEstimation process(RegArimaModel regs, IArimaMapping mapping) {
SarimaModel current = regs.arima();
if (mapping == null) {
- mapping = SarimaMapping.of(current.orders());
+ mapping = SarimaMapping2.of(current.orders());
}
SarimaOrders curSpec = current.orders();
if (curSpec.getParametersCount() == 0 || (mapping != null && mapping.getDim() == 0)) {
@@ -206,7 +206,7 @@ public RegArimaEstimation process(RegArimaModel regs,
public RegArimaEstimation optimize(RegArimaModel regs, IArimaMapping mapping) {
SarimaModel arima = regs.arima();
if (mapping == null) {
- mapping = SarimaMapping.of(arima.orders());
+ mapping = SarimaMapping2.of(arima.orders());
}
return estimate(regs, mapping, (SarimaModel) arima.stationaryTransformation().getStationaryModel(), eps);
}
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/regsarima/regular/ModelDescription.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/regsarima/regular/ModelDescription.java
index 53764da5..d76a6e01 100644
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/regsarima/regular/ModelDescription.java
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/regsarima/regular/ModelDescription.java
@@ -54,6 +54,7 @@
import jdplus.toolkit.base.core.sarima.SarimaModel;
import jdplus.toolkit.base.core.sarima.estimation.SarimaFixedMapping;
import jdplus.toolkit.base.core.sarima.estimation.SarimaMapping;
+import jdplus.toolkit.base.core.sarima.estimation.SarimaMapping2;
import jdplus.toolkit.base.core.stats.likelihood.ConcentratedLikelihoodWithMissing;
import jdplus.toolkit.base.core.stats.likelihood.LogLikelihoodFunction;
import jdplus.toolkit.base.core.timeseries.simplets.Transformations;
@@ -741,7 +742,7 @@ public IArimaMapping mapping() {
}
return new SarimaFixedMapping(specification(), DoubleSeq.of(p), b);
} else {
- return SarimaMapping.of(specification());
+ return SarimaMapping2.of(specification());
}
}
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/regsarima/regular/TradingDaysRegressionComparator.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/regsarima/regular/TradingDaysRegressionComparator.java
index 72f5587a..fc98d994 100644
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/regsarima/regular/TradingDaysRegressionComparator.java
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/regsarima/regular/TradingDaysRegressionComparator.java
@@ -91,7 +91,6 @@ public RegArimaEstimation[] test(ModelDescription description, ITra
cdesc.addVariable(Variable.variable("td", td[i]));
rslt[i + 2] = cdesc.estimate(processor);
}
-
return rslt;
}
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/sarima/estimation/SarimaMapping2.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/sarima/estimation/SarimaMapping2.java
index b3e44cf0..c4f7b5a7 100644
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/sarima/estimation/SarimaMapping2.java
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/sarima/estimation/SarimaMapping2.java
@@ -34,7 +34,7 @@
@lombok.Builder( toBuilder = true)
public class SarimaMapping2 implements IArimaMapping {
- public static final double ARMAX = 0.99999;
+ public static final double ARMAX = 0.99;
public static final double MAMAX = 1;
public static final double STEP = Math.sqrt(2.220446e-16);
private double arLimit;
@@ -71,7 +71,7 @@ public static SarimaModel stabilize(SarimaModel m) {
public static SarimaMapping2 of(SarimaOrders spec) {
return SarimaMapping2
.builder(spec)
- .arLimit(1)
+ .arLimit(ARMAX)
.maLimit(1)
.build();
}
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/ssf/likelihood/DiffuseLikelihood.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/ssf/likelihood/DiffuseLikelihood.java
index 7dcedd0e..01e1779f 100644
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/ssf/likelihood/DiffuseLikelihood.java
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/ssf/likelihood/DiffuseLikelihood.java
@@ -82,7 +82,7 @@ public Builder residuals(DoubleSeq residuals) {
return this;
}
if (ssqerr == 0) {
- this.ssqerr = residuals.ssq();
+ this.ssqerr = residuals.ssqWithMissing();
}
this.res = residuals.toArray();
return this;
@@ -204,6 +204,18 @@ public int dim() {
public DoubleSeq e() {
return res == null ? null : DoubleSeq.of(res);
}
+
+ @Override
+ public DoubleSeq deviances(){
+ double f = factor();
+ DoubleSeq e = e().select(x->Double.isFinite(x));
+ if (f == 1) {
+ return e;
+ } else {
+ final double sf = Math.sqrt(f);
+ return e.map(x -> x * sf);
+ }
+ }
@Override
public double logDeterminant() {
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/stats/Combinatorics.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/stats/Combinatorics.java
index b631d2e8..da600cc4 100644
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/stats/Combinatorics.java
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/stats/Combinatorics.java
@@ -5,15 +5,17 @@
*/
package jdplus.toolkit.base.core.stats;
+import jdplus.toolkit.base.api.math.MathException;
import jdplus.toolkit.base.core.math.Arithmetics;
/**
*
* @author Jean Palate
*/
+@lombok.experimental.UtilityClass
public class Combinatorics {
- public static long binomialCoefficient(final int n, final int k) {
+ public long binomialCoefficient(final int n, final int k) {
if (k > n || n <= 0 || k < 0) {
throw new IllegalArgumentException();
}
@@ -52,4 +54,187 @@ public static long binomialCoefficient(final int n, final int k) {
return result;
}
+ public long factorial(long x) {
+ if (x < l_fac.length) {
+ return l_fac[(int) x];
+ } else {
+ throw new MathException(MathException.OVERFLOW);
+ }
+ }
+
+ public double dfactorial(long x) {
+ if (x < d_fac.length) {
+ return d_fac[(int) x];
+ } else {
+ throw new MathException(MathException.OVERFLOW);
+ }
+ }
+
+ public double logFactorial(long x) {
+ if (x < d_fac.length) {
+ return Math.log(d_fac[(int) x]);
+ } else {
+ double s=LFAC_MAX;
+ for (long l=d_fac.length; l<=x; ++l)
+ s+=Math.log(l);
+ return s;
+ }
+ }
+
+ private final long[] l_fac = new long[]{1L, 1L, 2L, 6L, 24L, 120L, 720L, 5040L, 40320L, 362880L, 3628800L, 39916800L, 479001600L,
+ 6227020800L, 87178291200L, 1307674368000L, 20922789888000L, 355687428096000L, 6402373705728000L,
+ 121645100408832000L, 2432902008176640000L
+ };
+
+ private final double[] d_fac = new double[]{
+ 1.0, 1.0, 2.0, 6.0, 24.0, 120.0, 720.0, 5040.0, 40320.0, 362880.0, 3628800.0,
+ 39916800.0, 479001600.0, 6227020800.0, 87178291200.0, 1307674368000.0,
+ 20922789888000.0, 355687428096000.0, 6402373705728000.0, 121645100408832000.0,
+ 2432902008176640000.0, 51090942171709440000.0, 1124000727777607680000.0, 25852016738884976640000.0,
+ 620448401733239439360000.0, 15511210043330985984000000.0, 403291461126605635584000000.0,
+ 10888869450418352160768000000.0, 304888344611713860501504000000.0, 8841761993739701954543616000000.0, 265252859812191058636308480000000.0,
+ 8222838654177922817725562880000000.0,
+ 263130836933693530167218012160000000.0,
+ 8683317618811886495518194401280000000.0,
+ 2.95232799039604140847618609644e38,
+ 1.03331479663861449296666513375e40,
+ 3.71993326789901217467999448151e41,
+ 1.37637530912263450463159795816e43,
+ 5.23022617466601111760007224100e44,
+ 2.03978820811974433586402817399e46,
+ 8.15915283247897734345611269600e47,
+ 3.34525266131638071081700620534e49,
+ 1.40500611775287989854314260624e51,
+ 6.04152630633738356373551320685e52,
+ 2.65827157478844876804362581101e54,
+ 1.19622220865480194561963161496e56,
+ 5.50262215981208894985030542880e57,
+ 2.58623241511168180642964355154e59,
+ 1.24139155925360726708622890474e61,
+ 6.08281864034267560872252163321e62,
+ 3.04140932017133780436126081661e64,
+ 1.55111875328738228022424301647e66,
+ 8.06581751709438785716606368564e67,
+ 4.27488328406002556429801375339e69,
+ 2.30843697339241380472092742683e71,
+ 1.26964033536582759259651008476e73,
+ 7.10998587804863451854045647464e74,
+ 4.05269195048772167556806019054e76,
+ 2.35056133128287857182947491052e78,
+ 1.38683118545689835737939019720e80,
+ 8.32098711274139014427634118320e81,
+ 5.07580213877224798800856812177e83,
+ 3.14699732603879375256531223550e85,
+ 1.982608315404440064116146708360e87,
+ 1.268869321858841641034333893350e89,
+ 8.247650592082470666723170306800e90,
+ 5.443449390774430640037292402480e92,
+ 3.647111091818868528824985909660e94,
+ 2.480035542436830599600990418570e96,
+ 1.711224524281413113724683388810e98,
+ 1.197857166996989179607278372170e100,
+ 8.504785885678623175211676442400e101,
+ 6.123445837688608686152407038530e103,
+ 4.470115461512684340891257138130e105,
+ 3.307885441519386412259530282210e107,
+ 2.480914081139539809194647711660e109,
+ 1.885494701666050254987932260860e111,
+ 1.451830920282858696340707840860e113,
+ 1.132428117820629783145752115870e115,
+ 8.946182130782975286851441715400e116,
+ 7.156945704626380229481153372320e118,
+ 5.797126020747367985879734231580e120,
+ 4.753643337012841748421382069890e122,
+ 3.945523969720658651189747118010e124,
+ 3.314240134565353266999387579130e126,
+ 2.817104114380550276949479442260e128,
+ 2.422709538367273238176552320340e130,
+ 2.107757298379527717213600518700e132,
+ 1.854826422573984391147968456460e134,
+ 1.650795516090846108121691926250e136,
+ 1.485715964481761497309522733620e138,
+ 1.352001527678402962551665687590e140,
+ 1.243841405464130725547532432590e142,
+ 1.156772507081641574759205162310e144,
+ 1.087366156656743080273652852570e146,
+ 1.032997848823905926259970209940e148,
+ 9.916779348709496892095714015400e149,
+ 9.619275968248211985332842594960e151,
+ 9.426890448883247745626185743100e153,
+ 9.332621544394415268169923885600e155,
+ 9.33262154439441526816992388563e157,
+ 9.42594775983835942085162312450e159,
+ 9.61446671503512660926865558700e161,
+ 9.90290071648618040754671525458e163,
+ 1.02990167451456276238485838648e166,
+ 1.08139675824029090050410130580e168,
+ 1.146280563734708354534347384148e170,
+ 1.226520203196137939351751701040e172,
+ 1.324641819451828974499891837120e174,
+ 1.443859583202493582204882102460e176,
+ 1.588245541522742940425370312710e178,
+ 1.762952551090244663872161047110e180,
+ 1.974506857221074023536820372760e182,
+ 2.231192748659813646596607021220e184,
+ 2.543559733472187557120132004190e186,
+ 2.925093693493015690688151804820e188,
+ 3.393108684451898201198256093590e190,
+ 3.96993716080872089540195962950e192,
+ 4.68452584975429065657431236281e194,
+ 5.57458576120760588132343171174e196,
+ 6.68950291344912705758811805409e198,
+ 8.09429852527344373968162284545e200,
+ 9.87504420083360136241157987140e202,
+ 1.21463043670253296757662432419e205,
+ 1.50614174151114087979501416199e207,
+ 1.88267717688892609974376770249e209,
+ 2.37217324288004688567714730514e211,
+ 3.01266001845765954480997707753e213,
+ 3.85620482362580421735677065923e215,
+ 4.97450422247728744039023415041e217,
+ 6.46685548922047367250730439554e219,
+ 8.47158069087882051098456875820e221,
+ 1.11824865119600430744996307608e224,
+ 1.48727070609068572890845089118e226,
+ 1.99294274616151887673732419418e228,
+ 2.69047270731805048359538766215e230,
+ 3.65904288195254865768972722052e232,
+ 5.01288874827499166103492629211e234,
+ 6.91778647261948849222819828311e236,
+ 9.61572319694108900419719561353e238,
+ 1.34620124757175246058760738589e241,
+ 1.89814375907617096942852641411e243,
+ 2.69536413788816277658850750804e245,
+ 3.85437071718007277052156573649e247,
+ 5.55029383273930478955105466055e249,
+ 8.04792605747199194484902925780e251,
+ 1.17499720439091082394795827164e254,
+ 1.72724589045463891120349865931e256,
+ 2.55632391787286558858117801578e258,
+ 3.80892263763056972698595524351e260,
+ 5.71338395644585459047893286526e262,
+ 8.62720977423324043162318862650e264,
+ 1.31133588568345254560672467123e267,
+ 2.00634390509568239477828874699e269,
+ 3.08976961384735088795856467036e271,
+ 4.78914290146339387633577523906e273,
+ 7.47106292628289444708380937294e275,
+ 1.17295687942641442819215807155e278,
+ 1.85327186949373479654360975305e280,
+ 2.94670227249503832650433950735e282,
+ 4.71472363599206132240694321176e284,
+ 7.59070505394721872907517857094e286,
+ 1.22969421873944943411017892849e289,
+ 2.00440157654530257759959165344e291,
+ 3.28721858553429622726333031164e293,
+ 5.42391066613158877498449501421e295,
+ 9.00369170577843736647426172359e297,
+ 1.50361651486499904020120170784e300,
+ 2.52607574497319838753801886917e302,
+ 4.26906800900470527493925188890e304,
+ 7.25741561530799896739672821113e306
+ };
+
+ private final double LFAC_MAX=Math.log(7.25741561530799896739672821113e306);
+
}
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/stats/likelihood/Likelihood.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/stats/likelihood/Likelihood.java
index 82c057ff..cb6d5562 100644
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/stats/likelihood/Likelihood.java
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/stats/likelihood/Likelihood.java
@@ -209,7 +209,7 @@ default double factor() {
*/
default DoubleSeq deviances() {
double f = factor();
- DoubleSeq e = e();
+ DoubleSeq e = e().select(x->Double.isFinite(x));
if (f == 1) {
return e;
} else {
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/timeseries/simplets/analysis/RevisionHistory.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/timeseries/simplets/analysis/RevisionHistory.java
index d1b6cd2a..74752108 100644
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/timeseries/simplets/analysis/RevisionHistory.java
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/java/jdplus/toolkit/base/core/timeseries/simplets/analysis/RevisionHistory.java
@@ -146,7 +146,7 @@ public TsData referenceSeries(Function extractor) {
}
/**
- *
+ *
* @param start
* @param extractor
* @return
@@ -261,20 +261,12 @@ public T tsInfo(TsDomain domain) {
}
}
- // /
- // / Returns the value of the time series identified by "item" at a given
- // point ("period"),
- // / starting from a given date (start).
- // / In a formal way:
- // /
- // / Y = { Info([p0, p1])(period)}, p1 >= start
- // /
- // / The identifier of the series
- // / The period of interest
- // / The first period
- // /
/**
- *
+ * Returns the values of the time series generated by the given extractor at the given period.
+ * So, the results always refer to the same information (point in a timeseries, computed at successive moments
+ * We start to compute those values at the processing corresponding to "start.
+ * More formally, we get the series
+ * Y = { fn(P}[period] }, P = procssinge(p), p >= start
* @param period
* @param start
* @param extractor
@@ -282,8 +274,10 @@ public T tsInfo(TsDomain domain) {
*/
public TsData tsRevision(TsPeriod period, TsPeriod start, Function extractor) {
TsPeriod p0 = m_domainT.getStartPeriod();
- int pos = p0.until(period);
- double[] x = new double[start.until(m_domainT.getEndPeriod())];
+ int n = start.until(m_domainT.getEndPeriod());
+ if (n <= 0)
+ return null;
+ double[] x = new double[n];
int len = p0.until(start) + 1;
for (int i = 0; i < x.length; ++i, ++len) {
TsDomain rdom = TsDomain.of(p0, len);
@@ -291,7 +285,7 @@ public TsData tsRevision(TsPeriod period, TsPeriod start, Function ex
if (output != null) {
TsData t = extractor.apply(output);
if (t != null) {
- x[i] = t.getValue(pos);
+ x[i] = t.getDoubleValue(period);
} else {
x[i] = Double.NaN;
}
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/resources/bematrix.txt b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/resources/bematrix.txt
deleted file mode 100644
index bdc8c0ad..00000000
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/resources/bematrix.txt
+++ /dev/null
@@ -1,93 +0,0 @@
-9.673 -1.071 0.285 0.311 11.900 24.300 1.409 71527.163 11.178 1.933 n
-9.588 -1.108 0.491 0.194 -0.028 2.700 22.800 0.398 71870.248 11.183 -4.767 0.479657767
-9.673 -0.892 0.385 0.307 -0.310 0.600 23.400 -0.408 72400.798 11.190 -9.333 0.738205509
-9.832 -1.045 0.286 0.324 0.654 -4.633 22.900 -0.715 72666.355 11.194 -11.533 0.366787039
-9.866 -1.757 0.401 0.685 -0.497 -10.000 10.100 0.686 72520.090 11.192 14.474 0.900 -13.533 -0.201282792
-9.661 -1.525 0.340 0.645 0.932 -7.167 11.000 -0.544 73072.889 11.199 15.525 -0.490 7.261 -11.967 0.762269913
-9.412 -1.551 0.236 -0.216 -0.032 -8.433 7.500 0.032 73438.755 11.204 16.122 -0.976 3.846 -8.300 0.500686268
-9.222 -1.296 0.537 1.022 -0.049 -1.967 15.300 -0.589 74017.699 11.212 18.353 0.347 13.834 -5.333 0.788336061
-9.134 -0.871 0.108 0.359 0.663 -4.000 17.400 1.147 74709.604 11.221 17.956 -1.681 -2.160 -3.433 0.934783509
-9.155 0.056 0.082 0.125 -0.623 5.033 11.900 0.664 75818.633 11.236 15.788 0.913 -12.077 -1.600 1.484452958
-9.280 0.367 0.057 0.266 -0.469 4.200 6.600 1.108 76478.003 11.245 16.942 1.838 7.312 2.133 0.869666637
-9.324 0.371 0.232 0.366 -0.241 7.667 3.900 -0.667 76915.812 11.250 16.661 2.186 -1.662 4.967 0.572464911
-9.426 0.054 0.506 0.040 1.051 8.467 0.800 -0.502 77120.339 11.253 12.953 2.346 -22.255 3.100 0.26590918
-9.429 -0.204 0.157 0.498 0.081 6.233 11.600 -0.949 77376.722 11.256 12.069 1.563 -6.826 2.433 0.332445464
-9.379 -0.491 0.559 0.114 1.014 4.000 8.900 -0.902 77619.748 11.260 11.118 -0.127 -7.873 -1.000 0.314082684
-9.139 -0.854 0.032 -0.030 0.361 -5.800 3.500 -1.313 77812.205 11.262 9.425 -1.274 -15.226 -7.033 0.2479475
-8.972 -0.473 0.574 0.550 0.372 -5.300 4.100 0.467 78636.331 11.273 9.888 -1.095 4.903 -5.900 1.059121888
-8.899 0.249 -0.033 0.161 0.079 -4.800 9.500 0.652 79695.183 11.286 14.501 -1.524 46.663 -1.200 1.34651787
-8.126 1.078 0.409 0.288 0.073 0.967 17.900 1.971 80843.050 11.300 19.388 -0.738 33.700 1.167 1.440321293
-7.682 1.660 0.176 0.637 0.099 7.033 6.500 2.234 81796.510 11.312 23.170 0.430 19.503 6.100 1.179396995
-7.108 1.804 0.083 0.589 0.105 11.367 18.700 1.750 82407.648 11.319 27.141 1.261 17.140 7.900 0.747144441
-6.817 1.881 0.671 1.005 -0.460 13.400 13.200 2.390 82950.036 11.326 28.440 2.210 4.785 8.100 0.658176822
-6.877 1.706 0.137 0.807 0.625 15.867 17.000 1.780 83279.659 11.330 33.516 1.917 17.849 6.167 0.397375512
-6.649 2.037 0.499 0.957 0.752 15.900 17.400 0.752 84018.389 11.339 34.063 1.149 1.631 4.933 0.887046407
-6.096 1.464 0.306 -0.288 1.087 16.833 18.700 -0.483 83968.813 11.338 27.964 -0.576 -17.905 1.433 -0.059005693
-6.514 0.846 0.827 1.479 1.308 7.133 32.100 1.071 83919.656 11.338 31.220 -1.281 11.644 -5.600 -0.058542406
-6.324 0.079 0.581 0.241 2.027 6.567 36.200 -1.187 83748.140 11.336 28.362 -2.905 -9.154 -9.400 -0.20438127
-7.374 -0.542 0.890 0.426 1.086 -1.167 45.600 -1.526 83698.841 11.335 21.588 -3.542 -23.885 -14.233 -0.058865389
-7.349 -0.284 0.604 0.415 0.085 -3.300 22.100 -0.433 84478.433 11.344 24.131 -1.996 11.782 -9.833 0.931425269
-7.272 0.055 0.163 0.171 0.001 6.333 9.200 0.643 85220.217 11.353 27.285 -1.970 13.070 -5.900 0.878074316
-7.491 0.080 0.425 0.177 -0.662 3.867 0.900 -0.782 85669.622 11.358 27.358 0.854 0.267 -7.767 0.527345919
-7.977 -0.080 0.182 0.406 -0.003 1.300 0.600 0.170 85935.562 11.361 26.874 2.110 -1.769 -9.433 0.310425245
-8.125 -0.853 0.389 0.812 0.515 2.167 5.900 0.184 85597.110 11.357 29.285 1.711 8.972 -12.367 -0.393843724
-8.080 -1.177 0.581 -0.115 0.932 -4.367 7.900 -1.623 85682.657 11.358 22.974 1.265 -21.551 -15.600 0.099941563
-8.122 -1.212 0.291 0.474 0.542 -5.867 0.000 0.204 86013.111 11.362 25.288 0.076 10.075 -12.467 0.385671612
-8.383 -0.884 0.431 0.458 -0.185 1.133 1.300 0.326 86653.501 11.370 24.738 0.357 -2.176 -6.267 0.744526447
-8.550 0.418 0.247 0.361 -0.874 4.633 11.400 0.566 88004.295 11.385 25.566 1.950 3.345 -3.767 1.558845205
-7.744 0.940 0.282 0.686 -0.763 4.133 8.000 2.383 88867.459 11.395 29.462 3.033 15.240 -0.667 0.980820232
-8.895 1.303 0.270 0.435 -0.047 6.533 17.400 1.331 89643.858 11.404 34.037 3.814 15.530 0.733 0.873659225
-8.348 1.053 0.255 0.797 1.156 12.400 18.600 -0.003 89930.131 11.407 34.027 2.403 -0.029 -0.967 0.31934485
-8.455 0.617 0.390 0.464 -0.466 8.067 13.000 0.831 90286.001 11.411 36.330 1.770 6.768 -3.800 0.395717902
-8.473 0.529 0.206 0.716 0.682 4.667 19.900 0.707 90736.578 11.416 40.983 0.797 12.807 -7.233 0.499055256
-8.499 0.361 0.317 0.822 0.965 2.033 16.900 1.929 91087.986 11.420 50.454 -0.191 23.109 -6.167 0.387283891
-8.442 0.635 0.631 0.464 0.021 4.267 17.900 3.147 91816.680 11.428 47.908 1.414 -5.046 -0.867 0.799988929
-8.553 0.833 0.260 0.585 0.775 5.133 15.300 0.765 92393.698 11.434 51.496 0.157 7.489 2.167 0.628445617
-8.669 0.669 0.455 0.663 0.976 7.667 17.500 -1.189 92695.744 11.437 55.498 -0.414 7.772 5.600 0.326912021
-7.902 1.026 0.393 0.484 -0.159 9.767 19.600 0.256 93476.876 11.445 55.005 0.717 -0.887 6.433 0.84268455
-7.913 1.626 0.194 0.203 0.289 11.567 15.300 -0.540 94484.444 11.456 46.344 0.054 -15.746 6.300 1.077879424
-7.830 2.462 0.457 0.411 0.269 14.633 20.500 -0.268 95699.671 11.469 44.306 1.068 -4.398 5.333 1.286165497
-7.993 2.374 0.421 0.326 1.491 9.100 24.000 1.834 96075.901 11.473 50.984 0.486 15.072 6.533 0.393136801
-7.067 2.670 0.286 0.376 -0.531 11.233 25.500 1.993 96818.042 11.481 54.623 0.221 7.139 5.467 0.772452315
-7.066 2.691 0.211 1.613 0.793 10.633 33.500 1.837 97306.664 11.486 61.443 -0.535 12.484 2.400 0.504680873
-6.914 2.639 0.578 1.452 1.464 13.367 29.800 2.455 97869.146 11.491 64.552 -1.796 5.060 1.700 0.578050599
-6.626 2.361 0.377 1.443 0.967 11.800 16.600 1.912 98025.350 11.493 78.399 -0.866 21.452 -0.733 0.159604793
-7.491 1.462 0.768 0.994 2.045 19.233 22.800 1.804 97532.100 11.488 76.812 -2.948 -2.025 -5.100 -0.503185507
-6.833 -0.984 0.659 -0.357 2.868 6.367 6.400 -4.429 95489.925 11.467 42.404 -5.569 -44.795 -20.733 -2.093849308
-7.768 -2.240 0.366 -0.573 0.382 -3.533 -11.200 -5.280 94392.167 11.455 34.524 -5.129 -18.582 -30.300 -1.149606236
-7.838 -2.621 0.662 -0.243 -0.178 -7.267 -11.100 -1.824 94288.967 11.454 43.373 -4.520 25.630 -27.000 -0.10933084
-7.972 -1.822 0.351 0.071 -0.703 -9.000 -11.500 0.375 95338.652 11.465 47.801 -1.654 10.208 -19.400 1.113263993
-8.087 -1.287 0.276 0.535 -0.292 -6.067 -1.700 0.397 96143.844 11.474 50.724 1.265 6.115 -10.533 0.844559578
-8.567 -1.155 -0.038 0.753 -0.677 -8.033 5.400 2.751 96600.951 11.478 55.429 2.695 9.276 -5.967 0.475440714
-8.417 -0.457 0.533 1.058 0.293 6.700 10.200 3.131 97576.043 11.488 61.910 3.479 11.693 -5.033 1.009402367
-8.379 -0.313 0.189 0.262 0.215 8.467 8.600 1.630 98007.288 11.493 59.181 2.379 -4.408 -4.900 0.441957763
-7.878 -0.191 0.567 1.027 1.033 14.433 19.300 0.781 98411.752 11.497 63.901 1.780 7.975 0.467 0.412687739
-7.083 0.167 0.334 1.002 0.850 17.567 31.100 1.603 99062.700 11.504 76.680 0.380 19.998 5.033 0.661453318
-6.915 0.181 0.243 0.830 0.135 22.567 31.300 1.219 99349.115 11.506 81.388 -0.350 6.140 0.533 0.289125073
-7.516 0.143 0.520 0.676 1.349 10.467 31.800 0.379 99570.800 11.509 79.616 -1.781 -2.177 -6.567 0.223137023
-7.062 -0.041 0.368 0.725 0.507 2.833 26.700 0.929 99637.691 11.509 81.084 -1.139 1.845 -10.333 0.067179305
-7.147 -0.068 0.718 0.962 0.825 10.833 44.000 0.979 99832.306 11.511 90.433 -0.515 11.529 -9.700 0.195322789
-7.294 -0.495 0.340 0.205 1.293 2.367 29.400 0.655 99639.009 11.509 84.984 -2.030 -6.025 -11.000 -0.193621463
-7.508 -0.762 0.367 0.496 0.504 2.300 22.500 0.319 99601.311 11.509 87.946 -1.382 3.485 -11.800 -0.037834178
-8.269 -1.106 0.391 0.591 0.705 -0.333 27.300 -0.018 99481.208 11.508 85.172 -1.568 -3.155 -13.100 -0.120584529
-8.392 -1.613 0.335 0.190 0.493 10.767 29.500 -0.214 99163.244 11.505 85.470 -2.020 0.351 -13.333 -0.319621673
-8.421 -1.365 0.366 0.076 0.300 3.033 25.200 -0.696 99640.153 11.509 78.856 -0.866 -7.739 -13.233 0.480932825
-8.465 -1.117 0.428 0.373 0.236 2.533 23.800 -0.090 100126.819 11.514 83.146 -0.823 5.441 -9.367 0.488424265
-8.498 -1.064 0.448 0.269 0.157 3.167 11.400 -0.421 100423.472 11.517 80.381 -0.087 -3.326 -6.333 0.296276996
-8.637 -1.020 0.197 0.231 -0.062 7.733 11.100 -0.135 100687.738 11.520 78.802 0.077 -1.964 -4.833 0.263151308
-8.551 -1.025 0.489 -0.214 -0.530 2.000 9.700 -1.215 100915.214 11.522 80.088 0.457 1.632 -5.933 0.22592207
-8.457 -0.896 0.304 0.075 0.367 2.233 19.000 -0.922 101297.863 11.526 77.009 1.252 -3.844 -7.233 0.379179237
-8.538 -0.849 0.367 -0.091 0.069 1.667 5.300 -0.416 101617.480 11.529 60.775 0.673 -21.081 -7.000 0.315522152
-8.673 -0.651 0.456 -0.128 -0.524 -2.600 -1.400 -1.783 102057.423 11.533 47.992 1.286 -21.033 -7.500 0.432940166
-8.643 -0.473 0.360 0.818 -0.006 2.100 8.500 0.227 102545.604 11.538 56.184 1.148 17.069 -5.067 0.478338908
-7.978 -0.721 0.405 0.219 -0.344 4.033 14.000 -1.491 102605.770 11.539 45.007 2.012 -19.895 -4.633 0.058672729
-8.721 -0.576 0.582 0.440 0.312 6.433 23.200 -1.872 103081.559 11.543 39.644 2.091 -11.915 -3.733 0.463706228
-8.248 -0.713 0.487 0.065 0.220 -0.867 18.400 -0.390 103345.028 11.546 31.177 0.654 -21.357 -3.700 0.25559217
-8.204 -0.327 0.360 0.889 -0.912 6.467 29.100 -0.394 104090.314 11.553 40.694 2.918 30.523 -1.633 0.721162791
-7.667 -0.562 0.439 0.528 0.511 6.867 19.700 0.462 104191.221 11.554 41.017 1.532 0.796 -1.233 0.09694179
-7.249 -0.645 0.145 0.479 0.284 7.433 18.600 0.768 104458.483 11.557 46.414 1.549 13.156 -1.300 0.256511007
-7.654 -0.291 0.454 1.039 0.160 5.933 25.000 2.064 105208.920 11.564 50.825 2.656 9.504 -0.800 0.718407611
-7.326 -0.167 0.448 -0.042 0.979 8.000 22.200 -0.355 105710.021 11.568 45.617 -0.216 -10.246 -1.267 0.476291443
-7.047 -0.315 0.488 0.438 0.456 8.167 18.500 -0.421 105891.125 11.570 44.049 -0.211 -3.437 -1.800 0.171321474
-6.394 -0.223 0.063 0.556 0.078 10.333 19.600 0.510 106472.210 11.576 52.207 -0.046 18.521 0.700 0.548756513
- 0.597 106816.202 11.579 54.467 4.328 1.433 0.323081895
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/resources/mssf1 b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/resources/mssf1
deleted file mode 100644
index bcc44948..00000000
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/main/resources/mssf1
+++ /dev/null
@@ -1,93 +0,0 @@
-9.673 -1.071 0.285 0.311 11.9 24.3 1.409 71527.163 11.178 n n n 1.933 n
-9.588 -1.108 0.491 0.194 -0.028 2.7 22.8 0.398 71870.248 11.183 -4.767 0.479657767
-9.673 -0.892 0.385 0.307 -0.31 0.6 23.4 -0.408 72400.798 11.19 -9.333 0.738205509
-9.832 -1.045 0.286 0.324 0.654 -4.633 22.9 -0.715 72666.355 11.194 -11.533 0.366787039
-9.866 -1.757 0.401 0.685 -0.497 -10 10.1 0.686 72520.09 11.192 14.474 0.9 -13.533 -0.201282792
-9.661 -1.525 0.34 0.645 0.932 -7.167 11 -0.544 73072.889 11.199 15.525 -0.49 7.261 -11.967 0.762269913
-9.412 -1.551 0.236 -0.216 -0.032 -8.433 7.5 0.032 73438.755 11.204 16.122 -0.976 3.846 -8.3 0.500686268
-9.222 -1.296 0.537 1.022 -0.049 -1.967 15.3 -0.589 74017.699 11.212 18.353 0.347 13.834 -5.333 0.788336061
-9.134 -0.871 0.108 0.359 0.663 -4 17.4 1.147 74709.604 11.221 17.956 -1.681 -2.16 -3.433 0.934783509
-9.155 0.056 0.082 0.125 -0.623 5.033 11.9 0.664 75818.633 11.236 15.788 0.913 -12.077 -1.6 1.484452958
-9.28 0.367 0.057 0.266 -0.469 4.2 6.6 1.108 76478.003 11.245 16.942 1.838 7.312 2.133 0.869666637
-9.324 0.371 0.232 0.366 -0.241 7.667 3.9 -0.667 76915.812 11.25 16.661 2.186 -1.662 4.967 0.572464911
-9.426 0.054 0.506 0.04 1.051 8.467 0.8 -0.502 77120.339 11.253 12.953 2.346 -22.255 3.1 0.26590918
-9.429 -0.204 0.157 0.498 0.081 6.233 11.6 -0.949 77376.722 11.256 12.069 1.563 -6.826 2.433 0.332445464
-9.379 -0.491 0.559 0.114 1.014 4 8.9 -0.902 77619.748 11.26 11.118 -0.127 -7.873 -1 0.314082684
-9.139 -0.854 0.032 -0.03 0.361 -5.8 3.5 -1.313 77812.205 11.262 9.425 -1.274 -15.226 -7.033 0.2479475
-8.972 -0.473 0.574 0.55 0.372 -5.3 4.1 0.467 78636.331 11.273 9.888 -1.095 4.903 -5.9 1.059121888
-8.899 0.249 -0.033 0.161 0.079 -4.8 9.5 0.652 79695.183 11.286 14.501 -1.524 46.663 -1.2 1.34651787
-8.126 1.078 0.409 0.288 0.073 0.967 17.9 1.971 80843.05 11.3 19.388 -0.738 33.7 1.167 1.440321293
-7.682 1.66 0.176 0.637 0.099 7.033 6.5 2.234 81796.51 11.312 23.17 0.43 19.503 6.1 1.179396995
-7.108 1.804 0.083 0.589 0.105 11.367 18.7 1.75 82407.648 11.319 27.141 1.261 17.14 7.9 0.747144441
-6.817 1.881 0.671 1.005 -0.46 13.4 13.2 2.39 82950.036 11.326 28.44 2.21 4.785 8.1 0.658176822
-6.877 1.706 0.137 0.807 0.625 15.867 17 1.78 83279.659 11.33 33.516 1.917 17.849 6.167 0.397375512
-6.649 2.037 0.499 0.957 0.752 15.9 17.4 0.752 84018.389 11.339 34.063 1.149 1.631 4.933 0.887046407
-6.096 1.464 0.306 -0.288 1.087 16.833 18.7 -0.483 83968.813 11.338 27.964 -0.576 -17.905 1.433 -0.059005693
-6.514 0.846 0.827 1.479 1.308 7.133 32.1 1.071 83919.656 11.338 31.22 -1.281 11.644 -5.6 -0.058542406
-6.324 0.079 0.581 0.241 2.027 6.567 36.2 -1.187 83748.14 11.336 28.362 -2.905 -9.154 -9.4 -0.20438127
-7.374 -0.542 0.89 0.426 1.086 -1.167 45.6 -1.526 83698.841 11.335 21.588 -3.542 -23.885 -14.233 -0.058865389
-7.349 -0.284 0.604 0.415 0.085 -3.3 22.1 -0.433 84478.433 11.344 24.131 -1.996 11.782 -9.833 0.931425269
-7.272 0.055 0.163 0.171 0.001 6.333 9.2 0.643 85220.217 11.353 27.285 -1.97 13.07 -5.9 0.878074316
-7.491 0.08 0.425 0.177 -0.662 3.867 0.9 -0.782 85669.622 11.358 27.358 0.854 0.267 -7.767 0.527345919
-7.977 -0.08 0.182 0.406 -0.003 1.3 0.6 0.17 85935.562 11.361 26.874 2.11 -1.769 -9.433 0.310425245
-8.125 -0.853 0.389 0.812 0.515 2.167 5.9 0.184 85597.11 11.357 29.285 1.711 8.972 -12.367 -0.393843724
-8.08 -1.177 0.581 -0.115 0.932 -4.367 7.9 -1.623 85682.657 11.358 22.974 1.265 -21.551 -15.6 0.099941563
-8.122 -1.212 0.291 0.474 0.542 -5.867 0 0.204 86013.111 11.362 25.288 0.076 10.075 -12.467 0.385671612
-8.383 -0.884 0.431 0.458 -0.185 1.133 1.3 0.326 86653.501 11.37 24.738 0.357 -2.176 -6.267 0.744526447
-8.55 0.418 0.247 0.361 -0.874 4.633 11.4 0.566 88004.295 11.385 25.566 1.95 3.345 -3.767 1.558845205
-7.744 0.94 0.282 0.686 -0.763 4.133 8 2.383 88867.459 11.395 29.462 3.033 15.24 -0.667 0.980820232
-8.895 1.303 0.27 0.435 -0.047 6.533 17.4 1.331 89643.858 11.404 34.037 3.814 15.53 0.733 0.873659225
-8.348 1.053 0.255 0.797 1.156 12.4 18.6 -0.003 89930.131 11.407 34.027 2.403 -0.029 -0.967 0.31934485
-8.455 0.617 0.39 0.464 -0.466 8.067 13 0.831 90286.001 11.411 36.33 1.77 6.768 -3.8 0.395717902
-8.473 0.529 0.206 0.716 0.682 4.667 19.9 0.707 90736.578 11.416 40.983 0.797 12.807 -7.233 0.499055256
-8.499 0.361 0.317 0.822 0.965 2.033 16.9 1.929 91087.986 11.42 50.454 -0.191 23.109 -6.167 0.387283891
-8.442 0.635 0.631 0.464 0.021 4.267 17.9 3.147 91816.68 11.428 47.908 1.414 -5.046 -0.867 0.799988929
-8.553 0.833 0.26 0.585 0.775 5.133 15.3 0.765 92393.698 11.434 51.496 0.157 7.489 2.167 0.628445617
-8.669 0.669 0.455 0.663 0.976 7.667 17.5 -1.189 92695.744 11.437 55.498 -0.414 7.772 5.6 0.326912021
-7.902 1.026 0.393 0.484 -0.159 9.767 19.6 0.256 93476.876 11.445 55.005 0.717 -0.887 6.433 0.84268455
-7.913 1.626 0.194 0.203 0.289 11.567 15.3 -0.54 94484.444 11.456 46.344 0.054 -15.746 6.3 1.077879424
-7.83 2.462 0.457 0.411 0.269 14.633 20.5 -0.268 95699.671 11.469 44.306 1.068 -4.398 5.333 1.286165497
-7.993 2.374 0.421 0.326 1.491 9.1 24 1.834 96075.901 11.473 50.984 0.486 15.072 6.533 0.393136801
-7.067 2.67 0.286 0.376 -0.531 11.233 25.5 1.993 96818.042 11.481 54.623 0.221 7.139 5.467 0.772452315
-7.066 2.691 0.211 1.613 0.793 10.633 33.5 1.837 97306.664 11.486 61.443 -0.535 12.484 2.4 0.504680873
-6.914 2.639 0.578 1.452 1.464 13.367 29.8 2.455 97869.146 11.491 64.552 -1.796 5.06 1.7 0.578050599
-6.626 2.361 0.377 1.443 0.967 11.8 16.6 1.912 98025.35 11.493 78.399 -0.866 21.452 -0.733 0.159604793
-7.491 1.462 0.768 0.994 2.045 19.233 22.8 1.804 97532.1 11.488 76.812 -2.948 -2.025 -5.1 -0.503185507
-6.833 -0.984 0.659 -0.357 2.868 6.367 6.4 -4.429 95489.925 11.467 42.404 -5.569 -44.795 -20.733 -2.093849308
-7.768 -2.24 0.366 -0.573 0.382 -3.533 -11.2 -5.28 94392.167 11.455 34.524 -5.129 -18.582 -30.3 -1.149606236
-7.838 -2.621 0.662 -0.243 -0.178 -7.267 -11.1 -1.824 94288.967 11.454 43.373 -4.52 25.63 -27 -0.10933084
-7.972 -1.822 0.351 0.071 -0.703 -9 -11.5 0.375 95338.652 11.465 47.801 -1.654 10.208 -19.4 1.113263993
-8.087 -1.287 0.276 0.535 -0.292 -6.067 -1.7 0.397 96143.844 11.474 50.724 1.265 6.115 -10.533 0.844559578
-8.567 -1.155 -0.038 0.753 -0.677 -8.033 5.4 2.751 96600.951 11.478 55.429 2.695 9.276 -5.967 0.475440714
-8.417 -0.457 0.533 1.058 0.293 6.7 10.2 3.131 97576.043 11.488 61.91 3.479 11.693 -5.033 1.009402367
-8.379 -0.313 0.189 0.262 0.215 8.467 8.6 1.63 98007.288 11.493 59.181 2.379 -4.408 -4.9 0.441957763
-7.878 -0.191 0.567 1.027 1.033 14.433 19.3 0.781 98411.752 11.497 63.901 1.78 7.975 0.467 0.412687739
-7.083 0.167 0.334 1.002 0.85 17.567 31.1 1.603 99062.7 11.504 76.68 0.38 19.998 5.033 0.661453318
-6.915 0.181 0.243 0.83 0.135 22.567 31.3 1.219 99349.115 11.506 81.388 -0.35 6.14 0.533 0.289125073
-7.516 0.143 0.52 0.676 1.349 10.467 31.8 0.379 99570.8 11.509 79.616 -1.781 -2.177 -6.567 0.223137023
-7.062 -0.041 0.368 0.725 0.507 2.833 26.7 0.929 99637.691 11.509 81.084 -1.139 1.845 -10.333 0.067179305
-7.147 -0.068 0.718 0.962 0.825 10.833 44 0.979 99832.306 11.511 90.433 -0.515 11.529 -9.7 0.195322789
-7.294 -0.495 0.34 0.205 1.293 2.367 29.4 0.655 99639.009 11.509 84.984 -2.03 -6.025 -11 -0.193621463
-7.508 -0.762 0.367 0.496 0.504 2.3 22.5 0.319 99601.311 11.509 87.946 -1.382 3.485 -11.8 -0.037834178
-8.269 -1.106 0.391 0.591 0.705 -0.333 27.3 -0.018 99481.208 11.508 85.172 -1.568 -3.155 -13.1 -0.120584529
-8.392 -1.613 0.335 0.19 0.493 10.767 29.5 -0.214 99163.244 11.505 85.47 -2.02 0.351 -13.333 -0.319621673
-8.421 -1.365 0.366 0.076 0.3 3.033 25.2 -0.696 99640.153 11.509 78.856 -0.866 -7.739 -13.233 0.480932825
-8.465 -1.117 0.428 0.373 0.236 2.533 23.8 -0.09 100126.819 11.514 83.146 -0.823 5.441 -9.367 0.488424265
-8.498 -1.064 0.448 0.269 0.157 3.167 11.4 -0.421 100423.472 11.517 80.381 -0.087 -3.326 -6.333 0.296276996
-8.637 -1.02 0.197 0.231 -0.062 7.733 11.1 -0.135 100687.738 11.52 78.802 0.077 -1.964 -4.833 0.263151308
-8.551 -1.025 0.489 -0.214 -0.53 2 9.7 -1.215 100915.214 11.522 80.088 0.457 1.632 -5.933 0.22592207
-8.457 -0.896 0.304 0.075 0.367 2.233 19 -0.922 101297.863 11.526 77.009 1.252 -3.844 -7.233 0.379179237
-8.538 -0.849 0.367 -0.091 0.069 1.667 5.3 -0.416 101617.48 11.529 60.775 0.673 -21.081 -7 0.315522152
-8.673 -0.651 0.456 -0.128 -0.524 -2.6 -1.4 -1.783 102057.423 11.533 47.992 1.286 -21.033 -7.5 0.432940166
-8.643 -0.473 0.36 0.818 -0.006 2.1 8.5 0.227 102545.604 11.538 56.184 1.148 17.069 -5.067 0.478338908
-7.978 -0.721 0.405 0.219 -0.344 4.033 14 -1.491 102605.77 11.539 45.007 2.012 -19.895 -4.633 0.058672729
-8.721 -0.576 0.582 0.44 0.312 6.433 23.2 -1.872 103081.559 11.543 39.644 2.091 -11.915 -3.733 0.463706228
-8.248 -0.713 0.487 0.065 0.22 -0.867 18.4 -0.39 103345.028 11.546 31.177 0.654 -21.357 -3.7 0.25559217
-8.204 -0.327 0.36 0.889 -0.912 6.467 29.1 -0.394 104090.314 11.553 40.694 2.918 30.523 -1.633 0.721162791
-7.667 -0.562 0.439 0.528 0.511 6.867 19.7 0.462 104191.221 11.554 41.017 1.532 0.796 -1.233 0.09694179
-7.249 -0.645 0.145 0.479 0.284 7.433 18.6 0.768 104458.483 11.557 46.414 1.549 13.156 -1.3 0.256511007
-7.654 -0.291 0.454 1.039 0.16 5.933 25 2.064 105208.92 11.564 50.825 2.656 9.504 -0.8 0.718407611
-7.326 -0.167 0.448 -0.042 0.979 8 22.2 -0.355 105710.021 11.568 45.617 -0.216 -10.246 -1.267 0.476291443
-7.047 -0.315 0.488 0.438 0.456 8.167 18.5 -0.421 105891.125 11.57 44.049 -0.211 -3.437 -1.8 0.171321474
-6.394 -0.223 0.063 0.556 0.078 10.333 19.6 0.51 106472.21 11.576 52.207 -0.046 18.521 0.7 0.548756513
- 0.597 106816.202 11.579 54.467 4.328 1.433 0.323081895
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/test/java/jdplus/toolkit/base/core/dstats/PoissonTest.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/test/java/jdplus/toolkit/base/core/dstats/PoissonTest.java
new file mode 100644
index 00000000..9e7058e8
--- /dev/null
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-core/src/test/java/jdplus/toolkit/base/core/dstats/PoissonTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2022 National Bank of Belgium
+ *
+ * Licensed under the EUPL, Version 1.2 or – as soon they will be approved
+ * by the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ *
+ * https://joinup.ec.europa.eu/software/page/eupl
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ */
+package jdplus.toolkit.base.core.dstats;
+
+import jdplus.toolkit.base.api.dstats.RandomNumberGenerator;
+import jdplus.toolkit.base.core.random.MersenneTwister;
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ *
+ * @author palatej
+ */
+public class PoissonTest {
+
+ public PoissonTest() {
+ }
+
+ @Test
+ public void testProb() {
+ Poisson p=new Poisson(10);
+ double s=0;
+ for (int i=0; i<100; ++i){
+ s+=p.getProbability(i);
+ }
+ assertEquals(1, s, 1e-9);
+ }
+
+ @Test
+ public void testRandom() {
+ RandomNumberGenerator rnd=MersenneTwister.fromSystemNanoTime();
+ Poisson p=new Poisson(20);
+ int[] h=new int[100];
+ long N=10000;
+ for (long i=0; i
eu.europa.ec.joinup.sat
jdplus-toolkit-base-parent
- 3.0.2
+ 3.1.0
jdplus-toolkit-base-information
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-protobuf/pom.xml b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-protobuf/pom.xml
index 748fb856..8d757b1f 100644
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-protobuf/pom.xml
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-protobuf/pom.xml
@@ -6,7 +6,7 @@
eu.europa.ec.joinup.sat
jdplus-toolkit-base-parent
- 3.0.2
+ 3.1.0
jdplus-toolkit-base-protobuf
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-protobuf/src/main/java/jdplus/toolkit/base/protobuf/toolkit/ModellingContextProto.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-protobuf/src/main/java/jdplus/toolkit/base/protobuf/toolkit/ModellingContextProto.java
index 4290e70e..e0f74e18 100644
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-protobuf/src/main/java/jdplus/toolkit/base/protobuf/toolkit/ModellingContextProto.java
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-protobuf/src/main/java/jdplus/toolkit/base/protobuf/toolkit/ModellingContextProto.java
@@ -19,7 +19,6 @@
import jdplus.toolkit.base.api.timeseries.DynamicTsDataSupplier;
import jdplus.toolkit.base.api.timeseries.StaticTsDataSupplier;
import jdplus.toolkit.base.api.timeseries.TsDataSupplier;
-import jdplus.toolkit.base.api.timeseries.TsMoniker;
import jdplus.toolkit.base.api.timeseries.calendars.CalendarDefinition;
import jdplus.toolkit.base.api.timeseries.calendars.CalendarManager;
import jdplus.toolkit.base.api.timeseries.regression.ModellingContext;
@@ -36,25 +35,14 @@ public class ModellingContextProto {
public final String R = "r", RPREFIX = "r@";
- public ToolkitProtos.TsMoniker convert(TsMoniker moniker) {
- return ToolkitProtos.TsMoniker.newBuilder()
- .setSource(moniker.getSource())
- .setId(moniker.getId())
- .build();
- }
-
- public TsMoniker convert(ToolkitProtos.TsMoniker moniker) {
- return TsMoniker.of(moniker.getSource(), moniker.getId());
- }
-
- public ToolkitProtos.TsDataSuppliers.Item convert(String name, TsDataSupplier supplier) {
+ public ToolkitProtos.TsDataSuppliers.Item convert(String name, TsDataSupplier supplier) {
ToolkitProtos.TsDataSuppliers.Item.Builder builder = ToolkitProtos.TsDataSuppliers.Item.newBuilder();
builder.setName(name);
if (supplier instanceof StaticTsDataSupplier s) {
builder.setData(ToolkitProtosUtility.convert(s.getData()));
} else if (supplier instanceof DynamicTsDataSupplier s) {
ToolkitProtos.DynamicTsData.Builder dbuilder=ToolkitProtos.DynamicTsData.newBuilder();
- dbuilder.setMoniker(convert(s.getMoniker()));
+ dbuilder.setMoniker(ToolkitProtosUtility.convert(s.getMoniker()));
dbuilder.setCurrent(ToolkitProtosUtility.convert(s.get()));
builder.setDynamicData(dbuilder.build());
}
@@ -73,7 +61,7 @@ public TsDataSupplier convert(ToolkitProtos.TsDataSuppliers.Item supplier) {
if (supplier.hasData()) {
return new StaticTsDataSupplier(ToolkitProtosUtility.convert(supplier.getData()));
} else if (supplier.hasDynamicData()) {
- return new DynamicTsDataSupplier(convert(supplier.getDynamicData().getMoniker()), ToolkitProtosUtility.convert(supplier.getDynamicData().getCurrent()));
+ return new DynamicTsDataSupplier(ToolkitProtosUtility.convert(supplier.getDynamicData().getMoniker()), ToolkitProtosUtility.convert(supplier.getDynamicData().getCurrent()));
} else {
return null;
}
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-protobuf/src/main/java/jdplus/toolkit/base/protobuf/toolkit/ToolkitProtosUtility.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-protobuf/src/main/java/jdplus/toolkit/base/protobuf/toolkit/ToolkitProtosUtility.java
index 52159ae9..6b9e8e3d 100644
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-protobuf/src/main/java/jdplus/toolkit/base/protobuf/toolkit/ToolkitProtosUtility.java
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-protobuf/src/main/java/jdplus/toolkit/base/protobuf/toolkit/ToolkitProtosUtility.java
@@ -37,6 +37,9 @@
import jdplus.toolkit.base.protobuf.modelling.ModellingProtos;
import org.checkerframework.checker.nullness.qual.NonNull;
import jdplus.toolkit.base.api.math.matrices.Matrix;
+import jdplus.toolkit.base.api.timeseries.Ts;
+import jdplus.toolkit.base.api.timeseries.TsCollection;
+import jdplus.toolkit.base.api.timeseries.TsMoniker;
/**
*
@@ -284,6 +287,86 @@ public ToolkitProtos.TsData convert(TsData s) {
.build();
}
+ public ToolkitProtos.TsData convert(TsData s, String name) {
+ if (s == null || s.isEmpty()) {
+ return ToolkitProtos.TsData.getDefaultInstance()
+ .toBuilder().setName(name)
+ .build();
+ }
+
+ TsPeriod start = s.getStart();
+ return ToolkitProtos.TsData.newBuilder()
+ .setAnnualFrequency(s.getAnnualFrequency())
+ .setStartYear(start.year())
+ .setStartPeriod(start.annualPosition() + 1)
+ .addAllValues(Iterables.of(s.getValues()))
+ .setName(name)
+ .build();
+ }
+
+ public ToolkitProtos.TsMoniker convert(TsMoniker moniker) {
+ return ToolkitProtos.TsMoniker.newBuilder()
+ .setSource(moniker.getSource())
+ .setId(moniker.getId())
+ .build();
+ }
+
+ public TsMoniker convert(ToolkitProtos.TsMoniker moniker) {
+ return TsMoniker.of(moniker.getSource(), moniker.getId());
+ }
+
+ public ToolkitProtos.Ts convert(Ts s) {
+ if (s == null) {
+ return ToolkitProtos.Ts.getDefaultInstance();
+ }
+
+ return ToolkitProtos.Ts.newBuilder()
+ .setName(s.getName())
+ .setMoniker(convert(s.getMoniker()))
+ .setData(convert(s.getData()))
+ .putAllMetadata(s.getMeta())
+ .build();
+ }
+
+ public ToolkitProtos.TsCollection convert(TsCollection s) {
+ if (s == null) {
+ return ToolkitProtos.TsCollection.getDefaultInstance();
+ }
+
+ return ToolkitProtos.TsCollection.newBuilder()
+ .setName(s.getName())
+ .setMoniker(convert(s.getMoniker()))
+ .putAllMetadata(s.getMeta())
+ .addAllSeries(s.getItems().stream().map(t->convert(t)).toList())
+ .build();
+ }
+
+ public Ts convert(ToolkitProtos.Ts s) {
+ if (s == null) {
+ return null;
+ }
+
+ return Ts.builder()
+ .name(s.getName())
+ .moniker(convert(s.getMoniker()))
+ .data(convert(s.getData()))
+ .meta(s.getMetadataMap())
+ .build();
+ }
+
+ public TsCollection convert(ToolkitProtos.TsCollection s) {
+ if (s == null) {
+ return null;
+ }
+
+ return TsCollection.builder()
+ .name(s.getName())
+ .moniker(convert(s.getMoniker()))
+ .meta(s.getMetadataMap())
+ .items(s.getSeriesList().stream().map(t->convert(t)).toList())
+ .build();
+ }
+
public ToolkitProtos.Matrix convert(Matrix m) {
if (m == null || m.isEmpty()) {
return ToolkitProtos.Matrix.getDefaultInstance();
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-protobuf/src/main/java/module-info.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-protobuf/src/main/java/module-info.java
index 23865731..79f48103 100644
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-protobuf/src/main/java/module-info.java
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-protobuf/src/main/java/module-info.java
@@ -6,7 +6,7 @@
requires static org.checkerframework.checker.qual;
requires jdplus.toolkit.base.core;
- requires com.google.protobuf;
+ requires protobuf.java;
exports jdplus.toolkit.base.protobuf.modelling;
exports jdplus.toolkit.base.protobuf.regarima;
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-protobuf/src/main/proto/toolkit.proto b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-protobuf/src/main/proto/toolkit.proto
index c9423396..e6c883eb 100644
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-protobuf/src/main/proto/toolkit.proto
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-protobuf/src/main/proto/toolkit.proto
@@ -351,6 +351,20 @@ message TsMoniker{
string id = 2;
}
+message Ts{
+ string name=1;
+ TsMoniker moniker = 2;
+ map metadata= 3;
+ TsData data = 4;
+}
+
+message TsCollection{
+ string name=1;
+ TsMoniker moniker = 2;
+ map metadata = 3;
+ repeated Ts series = 4;
+}
+
message DynamicTsData{
TsMoniker moniker = 1;
TsData current = 2;
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-r/pom.xml b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-r/pom.xml
index 068d9759..a618a392 100644
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-r/pom.xml
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-r/pom.xml
@@ -5,7 +5,7 @@
eu.europa.ec.joinup.sat
jdplus-toolkit-base-parent
- 3.0.2
+ 3.1.0
jdplus-toolkit-base-r
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-r/src/main/java/jdplus/toolkit/base/r/arima/SarimaModels.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-r/src/main/java/jdplus/toolkit/base/r/arima/SarimaModels.java
index 4858bf44..23f062d2 100644
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-r/src/main/java/jdplus/toolkit/base/r/arima/SarimaModels.java
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-r/src/main/java/jdplus/toolkit/base/r/arima/SarimaModels.java
@@ -12,16 +12,25 @@
import jdplus.toolkit.base.protobuf.regarima.RegArimaEstimationProto;
import java.util.function.DoubleUnaryOperator;
+import jdplus.toolkit.base.api.arima.SarimaOrders;
+import jdplus.toolkit.base.api.arima.SarmaOrders;
+import jdplus.toolkit.base.api.data.Parameter;
+import jdplus.toolkit.base.api.data.ParameterType;
import jdplus.toolkit.base.core.arima.ArimaModel;
import jdplus.toolkit.base.core.arima.ArimaSeriesGenerator;
import jdplus.toolkit.base.core.arima.AutoCovarianceFunction;
+import jdplus.toolkit.base.core.data.DataBlock;
import jdplus.toolkit.base.core.dstats.Normal;
import jdplus.toolkit.base.core.dstats.T;
+import jdplus.toolkit.base.core.math.linearfilters.BackFilter;
import jdplus.toolkit.base.core.math.matrices.FastMatrix;
+import jdplus.toolkit.base.core.random.XorshiftRNG;
import jdplus.toolkit.base.core.regarima.RegArimaEstimation;
import jdplus.toolkit.base.core.regarima.RegArimaModel;
import jdplus.toolkit.base.core.regsarima.RegSarimaComputer;
import jdplus.toolkit.base.core.sarima.SarimaModel;
+import jdplus.toolkit.base.core.sarima.SarimaUtility;
+import jdplus.toolkit.base.core.sarima.estimation.HannanRissanen;
import jdplus.toolkit.base.core.sarima.estimation.SarimaMapping;
import jdplus.toolkit.base.protobuf.regarima.RegArimaProtos;
@@ -56,12 +65,13 @@ public SarimaModel of(int period, double[] phi, int d, double[] theta, double[]
* @param btheta
* @param stde
* @param tdegree Degrees of T-Stat. O if normal is used
- * @return
+ * @param seed If seed < 0, use random seeds @return
*/
- public double[] random(int length, int period, double[] phi, int d, double[] theta, double[] bphi, int bd, double[] btheta, double stde, int tdegree) {
+ public double[] random(int length, int period, double[] phi, int d, double[] theta, double[] bphi, int bd, double[] btheta, double stde, int tdegree, int seed) {
if (stde == 0) {
stde = 1;
}
+ XorshiftRNG rnd = seed < 0 ? XorshiftRNG.fromSystemNanoTime() : new XorshiftRNG(seed);
SarimaModel sarima = SarimaModel.builder(period)
.differencing(d, bd)
.phi(phi)
@@ -69,7 +79,7 @@ public double[] random(int length, int period, double[] phi, int d, double[] the
.bphi(bphi)
.btheta(btheta)
.build();
- ArimaSeriesGenerator generator = ArimaSeriesGenerator.builder()
+ ArimaSeriesGenerator generator = ArimaSeriesGenerator.builder(rnd)
.distribution(tdegree <= 0 ? new Normal(0, stde) : new T(tdegree))
.startMean(10 * stde)
.startStdev(stde)
@@ -77,22 +87,76 @@ public double[] random(int length, int period, double[] phi, int d, double[] the
return generator.generate(sarima, length);
}
- public RegArimaEstimation estimate(double[] data, int[] regular, int period, int[] seasonal, boolean mean, Matrix X, double[] parameters, double eps) {
- SarimaSpec.Builder builder = SarimaSpec.builder()
- .period(period)
- .p(regular[0])
- .d(regular[1])
- .q(regular[2]);
+ public SarimaModel hannanRissanen(double[] data, int[] regular, int period, int[] seasonal, String initialization, boolean biasCorrection, boolean finalCorrection) {
+ SarimaOrders spec = new SarimaOrders(period);
+ spec.setRegular(regular[0], regular[1], regular[2]);
+ BackFilter ur;
if (seasonal != null) {
- builder
- .bp(seasonal[0])
- .bd(seasonal[1])
- .bq(seasonal[2]);
+ spec.setSeasonal(seasonal[0], seasonal[1], seasonal[2]);
+ ur = SarimaUtility.differencingFilter(period, regular[1], seasonal[1]);
+ } else {
+ ur = SarimaUtility.differencingFilter(1, regular[1], 0);
}
-
- // TODO. Fix parameters, if any
- if (parameters != null) {
+ SarmaOrders dspec = spec.doStationary();
+ HannanRissanen hr = HannanRissanen.builder()
+ .initialization(HannanRissanen.Initialization.valueOf(initialization))
+ .biasCorrection(biasCorrection)
+ .finalCorrection(finalCorrection)
+ .build();
+ int d = ur.getDegree();
+ DataBlock x;
+ if (d > 0) {
+ double[] tmp = new double[data.length - d];
+ x = DataBlock.of(tmp);
+ ur.apply(DataBlock.of(data), x);
+ } else {
+ x = DataBlock.of(data);
+ }
+ hr.process(x, dspec);
+ SarimaModel model = hr.getModel();
+ if (d >0)
+ model=model.toBuilder().differencing(spec.getD(), spec.getBd()).build();
+ return model;
+ }
+
+ public RegArimaEstimation estimate(double[] data, int[] regular, int period, int[] seasonal, boolean mean, Matrix X, double[] parameters, double eps) {
+ SarimaSpec.Builder builder = SarimaSpec.builder()
+ .period(period);
+
+ if (parameters != null) {
+ int cur = 0;
+ int p = regular[0];
+ if (p > 0) {
+ builder.phi(Parameter.of(DoubleSeq.of(parameters, cur, p), ParameterType.Fixed));
+ cur += p;
+ }
+ int q = regular[2];
+ if (q > 0) {
+ builder.theta(Parameter.of(DoubleSeq.of(parameters, cur, q), ParameterType.Fixed));
+ cur += q;
+ }
+ if (seasonal != null) {
+ int bp = seasonal[0];
+ if (bp > 0) {
+ builder.bphi(Parameter.of(DoubleSeq.of(parameters, cur, bp), ParameterType.Fixed));
+ cur += bp;
+ }
+ int bq = seasonal[2];
+ if (bq > 0) {
+ builder.theta(Parameter.of(DoubleSeq.of(parameters, cur, bq), ParameterType.Fixed));
+ }
+ }
+ } else {
+ builder.p(regular[0])
+ .d(regular[1])
+ .q(regular[2]);
+ if (seasonal != null) {
+ builder
+ .bp(seasonal[0])
+ .bd(seasonal[1])
+ .bq(seasonal[2]);
+ }
}
SarimaSpec sarima = builder.build();
@@ -122,8 +186,8 @@ public double[] spectrum(SarimaModel m, int n) {
}
return g;
}
-
- public ArimaModel convert(SarimaModel model){
+
+ public ArimaModel convert(SarimaModel model) {
return ArimaModel.of(model);
}
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-r/src/main/java/jdplus/toolkit/base/r/stats/Tests.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-r/src/main/java/jdplus/toolkit/base/r/stats/Tests.java
index 785afbeb..472f30f5 100644
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-r/src/main/java/jdplus/toolkit/base/r/stats/Tests.java
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-r/src/main/java/jdplus/toolkit/base/r/stats/Tests.java
@@ -10,10 +10,13 @@
import java.util.function.IntToDoubleFunction;
import jdplus.toolkit.base.api.stats.AutoCovariances;
import jdplus.toolkit.base.core.stats.InverseAutoCorrelations;
+import jdplus.toolkit.base.core.stats.RobustStandardDeviationComputer;
import jdplus.toolkit.base.core.stats.tests.BowmanShenton;
import jdplus.toolkit.base.core.stats.tests.DoornikHansen;
import jdplus.toolkit.base.core.stats.tests.JarqueBera;
+import jdplus.toolkit.base.core.stats.tests.Kurtosis;
import jdplus.toolkit.base.core.stats.tests.LjungBox;
+import jdplus.toolkit.base.core.stats.tests.Skewness;
import jdplus.toolkit.base.core.stats.tests.TestOfRuns;
import jdplus.toolkit.base.core.stats.tests.TestOfUpDownRuns;
@@ -51,6 +54,14 @@ public double[] inverseAutocorrelations(double[] data, int nar, int n){
return iac;
}
+ public StatisticalTest skewness(double[] data){
+ return new Skewness(DoubleSeq.of(data)).build();
+ }
+
+ public StatisticalTest kurtosis(double[] data){
+ return new Kurtosis(DoubleSeq.of(data)).build();
+ }
+
public StatisticalTest bowmanShenton(double[] data){
return new BowmanShenton(DoubleSeq.of(data)).build();
}
@@ -86,5 +97,9 @@ public StatisticalTest ljungBox(double[] data, int k, int lag, int nhp, int sign
.build();
}
+ public static double mad(double[] data, double centile, boolean mdedianCorrected){
+ return RobustStandardDeviationComputer.mad(centile, mdedianCorrected).compute(DoubleSeq.of(data));
+ }
+
}
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-r/src/main/java/jdplus/toolkit/base/r/timeseries/Revisions.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-r/src/main/java/jdplus/toolkit/base/r/timeseries/Revisions.java
new file mode 100644
index 00000000..f253b60a
--- /dev/null
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-r/src/main/java/jdplus/toolkit/base/r/timeseries/Revisions.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2022 National Bank of Belgium
+ *
+ * Licensed under the EUPL, Version 1.2 or – as soon they will be approved
+ * by the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ *
+ * https://joinup.ec.europa.eu/software/page/eupl
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ */
+package jdplus.toolkit.base.r.timeseries;
+
+import java.time.LocalDate;
+import java.util.List;
+import jdplus.toolkit.base.api.information.Explorable;
+import jdplus.toolkit.base.api.stats.StatisticalTest;
+import jdplus.toolkit.base.api.timeseries.TsData;
+import jdplus.toolkit.base.api.timeseries.TsDataTable;
+import jdplus.toolkit.base.api.timeseries.TsDomain;
+import jdplus.toolkit.base.api.timeseries.TsPeriod;
+import jdplus.toolkit.base.api.timeseries.TsUnit;
+import jdplus.toolkit.base.api.timeseries.regression.RegressionItem;
+import jdplus.toolkit.base.core.timeseries.simplets.analysis.DiagnosticInfo;
+import jdplus.toolkit.base.core.timeseries.simplets.analysis.RevisionHistory;
+
+/**
+ *
+ * @author palatej
+ * @param
+ */
+@lombok.Value
+public class Revisions {
+
+ RevisionHistory revisions;
+
+ public TsDomain referenceDomain() {
+ return revisions.getReferenceDomain();
+ }
+
+ public T result(String period) {
+ LocalDate date = LocalDate.parse(period);
+ TsDomain referenceDomain = revisions.getReferenceDomain();
+ int id = referenceDomain.indexOf(date.atStartOfDay());
+ if (id < 0) {
+ return null;
+ }
+ TsDomain cur = referenceDomain.range(0, id + 1);
+ return revisions.tsInfo(cur);
+ }
+
+ public TsData history(String id, String start) {
+ LocalDate date = LocalDate.parse(start);
+ TsDomain referenceDomain = revisions.getReferenceDomain();
+ TsPeriod pstart = TsPeriod.of(referenceDomain.getTsUnit(), date);
+ return revisions.revision(pstart, rslt -> toDouble(rslt.getData(id, Object.class)));
+ }
+
+ public TsData tsHistory(String id, String period, String start) {
+ LocalDate date = LocalDate.parse(start), refDate = LocalDate.parse(period);
+ TsDomain referenceDomain = revisions.getReferenceDomain();
+ TsPeriod pstart = TsPeriod.of(referenceDomain.getTsUnit(), date),
+ pref = TsPeriod.of(referenceDomain.getTsUnit(), refDate);
+ return revisions.tsRevision(pref, pstart, rslt -> rslt.getData(id, TsData.class));
+ }
+
+ public TsDataTable tsSelect(String id, String start, String end) {
+ LocalDate d0 = LocalDate.parse(start), d1 = LocalDate.parse(end);
+ List sel = revisions.select(d0, d1, r -> r.getData(id, TsData.class));
+ TsDataTable table = TsDataTable.of(sel);
+ return table;
+ }
+
+ public TsDomain referenceDomain(String id) {
+ TsData data = revisions.getReferenceInfo().getData(id, TsData.class);
+ return data == null ? null : data.getDomain();
+ }
+
+ public TsData diagnosticOf(String id, String start, String end, String diag) {
+ LocalDate d0 = LocalDate.parse(start), d1 = LocalDate.parse(end);
+ TsUnit unit = revisions.getReferenceDomain().getTsUnit();
+ TsPeriod p0 = TsPeriod.of(unit, d0), p1 = TsPeriod.of(unit, d1);
+ TsDomain domain = TsDomain.of(p0, p0.until(p1) + 1);
+ if (domain.isEmpty()) {
+ return null;
+ }
+ DiagnosticInfo info = DiagnosticInfo.valueOf(diag);
+ double[] revs = new double[domain.length()];
+ for (int i = 0; i < revs.length; ++i) {
+ revs[i] = revisions.seriesRevision(p0.plus(i), info, rslt -> rslt.getData(id, TsData.class));
+ }
+ return TsData.ofInternal(p0, revs);
+ }
+
+ public static double toDouble(Object obj) {
+ if (obj == null) {
+ return Double.NaN;
+ }
+ if (obj instanceof Double dobj) {
+ return dobj;
+ }
+ if (obj instanceof Integer iobj) {
+ return iobj.doubleValue();
+ }
+ if (obj instanceof Boolean bobj) {
+ return bobj ? 1 : 0;
+ }
+ if (obj instanceof StatisticalTest tobj) {
+ return tobj.getPvalue();
+ }
+ if (obj instanceof RegressionItem robj) {
+ return robj.getCoefficient();
+ }
+ if (obj instanceof double[] aobj) {
+ return aobj.length == 1 ? aobj[0] : Double.NaN;
+ }
+
+ return Double.NaN;
+ }
+}
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-r/src/main/java/jdplus/toolkit/base/r/timeseries/TsUtility.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-r/src/main/java/jdplus/toolkit/base/r/timeseries/TsUtility.java
index 96dcbace..54e55d27 100644
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-r/src/main/java/jdplus/toolkit/base/r/timeseries/TsUtility.java
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-r/src/main/java/jdplus/toolkit/base/r/timeseries/TsUtility.java
@@ -16,6 +16,7 @@
*/
package jdplus.toolkit.base.r.timeseries;
+import com.google.protobuf.InvalidProtocolBufferException;
import jdplus.toolkit.base.api.data.AggregationType;
import jdplus.toolkit.base.api.timeseries.CalendarPeriodObs;
import jdplus.toolkit.base.api.timeseries.CalendarTimeSeries;
@@ -25,8 +26,17 @@
import jdplus.toolkit.base.api.timeseries.TsUnit;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
+import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
+import jdplus.toolkit.base.api.timeseries.Ts;
+import jdplus.toolkit.base.api.timeseries.TsCollection;
+import jdplus.toolkit.base.api.timeseries.TsDataTable;
+import jdplus.toolkit.base.api.timeseries.TsFactory;
+import jdplus.toolkit.base.api.timeseries.TsInformationType;
+import jdplus.toolkit.base.api.timeseries.TsMoniker;
+import jdplus.toolkit.base.protobuf.toolkit.ToolkitProtos;
+import jdplus.toolkit.base.protobuf.toolkit.ToolkitProtosUtility;
/**
*
@@ -35,6 +45,11 @@
@lombok.experimental.UtilityClass
public class TsUtility {
+ public void updateProviders() {
+ TsFactory nfactory = TsFactory.ofServiceLoader();
+ TsFactory.setDefault(nfactory);
+ }
+
public TsData of(int freq, int year, int start, double[] data) {
switch (freq) {
case 1 -> {
@@ -84,6 +99,10 @@ public int[] startPeriod(TsData s) {
return of(s.getStart());
}
+ public int[] startPeriod(TsDataTable s) {
+ return of(s.getDomain().getStartPeriod());
+ }
+
public int[] of(TsPeriod p) {
LocalDate start = p.start().toLocalDate();
int freq = p.getUnit().getAnnualFrequency();
@@ -119,8 +138,71 @@ public CalendarTimeSeries of(String[] starts, String[] ends, double[] data) {
}
return CalendarTimeSeries.of(entries);
}
-
+
public TsData cleanExtremities(TsData s) {
return s.cleanExtremities();
}
+
+ public byte[] toBuffer(Ts s){
+ return ToolkitProtosUtility.convert(s).toByteArray();
+ }
+
+ public Ts tsOfBytes(byte[] bytes) throws InvalidProtocolBufferException{
+ return ToolkitProtosUtility.convert(ToolkitProtos.Ts.parseFrom(bytes));
+ }
+
+ public byte[] toBuffer(TsCollection s){
+ return ToolkitProtosUtility.convert(s).toByteArray();
+ }
+
+ public TsCollection tsCollectionOfBytes(byte[] bytes) throws InvalidProtocolBufferException{
+ return ToolkitProtosUtility.convert(ToolkitProtos.TsCollection.parseFrom(bytes));
+ }
+
+ private String dayOf(TsPeriod p, int pos){
+ switch (pos){
+ case 0 -> {
+ return p.start().toLocalDate().format(DateTimeFormatter.ISO_DATE);
+ }
+ case 2 -> {
+ return p.end().toLocalDate().minusDays(1).format(DateTimeFormatter.ISO_DATE);
+ }
+ default -> {
+ LocalDate d0=p.start().toLocalDate(), d1=p.end().toLocalDate();
+ return d0.plusDays(d0.until(d1, ChronoUnit.DAYS)/2).format(DateTimeFormatter.ISO_DATE);
+ }
+
+ }
+ }
+
+ /**
+ *
+ * @param domain
+ * @param pos 0 for first day, 1 for middle day, 2 for last day
+ * @return
+ */
+ public String[] daysOf(TsDomain domain, int pos){
+ String[] days=new String[domain.size()];
+ for (int i=0; i cproviders = new ArrayList<>(TsFactory.getDefault().getProviders().toList());
+ for (TsProvider p : providers) {
+ if (p != null) {
+ cproviders.add(p);
+ }
+ }
+ TsFactory.setDefault(TsFactory.of(cproviders));
+ }
+
+ public ObsGathering obsGathering(int period, String aggregationType, boolean allowPartialAggregation, boolean includeMissing) {
+ if (period <= 0 && !includeMissing) {
+ return ObsGathering.DEFAULT;
+ }
+ ObsGathering.Builder builder = ObsGathering.builder().includeMissingValues(includeMissing);
+ if (period > 0) {
+ builder.unit(TsUnit.ofAnnualFrequency(period))
+ .allowPartialAggregation(allowPartialAggregation)
+ .aggregationType(AggregationType.valueOf(aggregationType));
+ }
+ return builder.build();
+ }
+
+}
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-r/src/test/java/jdplus/toolkit/base/r/arima/SarimaModelsTest.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-r/src/test/java/jdplus/toolkit/base/r/arima/SarimaModelsTest.java
index 986e3bad..8a90e415 100644
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-r/src/test/java/jdplus/toolkit/base/r/arima/SarimaModelsTest.java
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-r/src/test/java/jdplus/toolkit/base/r/arima/SarimaModelsTest.java
@@ -23,7 +23,7 @@ public SarimaModelsTest() {
@Test
public void testRandom() {
- double[] rnd = SarimaModels.random(200, 12, new double[]{-.2, -.5}, 1, new double[]{-.5}, null, 1, new double[]{-.8}, 1, 5);
+ double[] rnd = SarimaModels.random(200, 12, new double[]{-.2, -.5}, 1, new double[]{-.5}, null, 1, new double[]{-.8}, 1, 5, -1);
// System.out.println(DoubleSeq.of(rnd));
assertTrue(rnd.length == 200);
}
@@ -35,5 +35,15 @@ public void testArima() {
byte[] buffer = SarimaModels.toBuffer(estimate);
assertTrue(buffer != null);
}
+
+ @Test
+ public void testHR(){
+ RegArimaEstimation estimate = SarimaModels.estimate(Data.ABS_RETAIL, new int[]{3, 1, 1}, 12, new int[]{0, 1, 1}, false, null, null, 1e-9);
+// System.out.println(estimate.getModel().arima());
+ SarimaModel hr = SarimaModels.hannanRissanen(Data.ABS_RETAIL, new int[]{3, 1, 1}, 12, new int[]{0, 1, 1}, "Ols", true, false);
+// System.out.println(hr);
+ hr = SarimaModels.hannanRissanen(Data.ABS_RETAIL, new int[]{3, 1, 1}, 12, new int[]{0, 1, 1}, "Ols", true, true);
+// System.out.println(hr);
+ }
}
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/pom.xml b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/pom.xml
index 5fa36c73..e2d43ea2 100644
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/pom.xml
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/pom.xml
@@ -6,7 +6,7 @@
eu.europa.ec.joinup.sat
jdplus-toolkit-base-parent
- 3.0.2
+ 3.1.0
jdplus-toolkit-base-tsp
@@ -28,6 +28,17 @@
java-io-base
${java-io-util.version}
+
+ com.github.ben-manes.caffeine
+ caffeine
+ 3.1.8
+
+
+ *
+ *
+
+
+
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/internal/toolkit/base/tsp/DefaultTsMeta.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/internal/toolkit/base/tsp/DefaultTsMeta.java
index 4bcd6beb..60b9b0d4 100644
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/internal/toolkit/base/tsp/DefaultTsMeta.java
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/internal/toolkit/base/tsp/DefaultTsMeta.java
@@ -22,6 +22,7 @@
import java.util.function.Function;
import nbbrd.io.text.Formatter;
import nbbrd.io.text.Parser;
+import org.checkerframework.checker.nullness.qual.NonNull;
/**
*
@@ -42,23 +43,23 @@ public final class DefaultTsMeta implements TsMeta {
private final Formatter formatter;
@Override
- public T load(Map meta) {
+ public T load(@NonNull Map meta) {
return load(meta::get);
}
@Override
- public T load(Function meta) {
+ public T load(@NonNull Function meta) {
String text = meta.apply(key);
return text != null ? parser.parse(text) : null;
}
@Override
- public void store(Map meta, T value) {
+ public void store(@NonNull Map meta, @NonNull T value) {
store(meta::put, value);
}
@Override
- public void store(BiConsumer meta, T value) {
+ public void store(@NonNull BiConsumer meta, @NonNull T value) {
String text = formatter.formatAsString(value);
meta.accept(key, text);
}
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/internal/toolkit/base/tsp/InternalTsProvider.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/internal/toolkit/base/tsp/InternalTsProvider.java
index 68a21ed4..3f84d265 100644
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/internal/toolkit/base/tsp/InternalTsProvider.java
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/internal/toolkit/base/tsp/InternalTsProvider.java
@@ -18,9 +18,8 @@
import jdplus.toolkit.base.api.timeseries.TsMoniker;
import jdplus.toolkit.base.tsp.*;
-import jdplus.toolkit.base.tsp.util.DataSourcePreconditions;
-import jdplus.toolkit.base.api.util.List2;
import jdplus.toolkit.base.tsp.fixme.Strings;
+import jdplus.toolkit.base.tsp.util.DataSourcePreconditions;
import nbbrd.io.text.Formatter;
import nbbrd.io.text.Parser;
import org.checkerframework.checker.nullness.qual.NonNull;
@@ -87,7 +86,7 @@ public DataDisplayNameSupport(String providerName, Formatter dataSou
}
@Override
- public String getDisplayName(DataSource dataSource) throws IllegalArgumentException {
+ public @NonNull String getDisplayName(@NonNull DataSource dataSource) throws IllegalArgumentException {
checkProvider(dataSource);
String result = dataSourceFormatter.formatAsString(dataSource);
if (result == null) {
@@ -97,7 +96,7 @@ public String getDisplayName(DataSource dataSource) throws IllegalArgumentExcept
}
@Override
- public String getDisplayName(DataSet dataSet) throws IllegalArgumentException {
+ public @NonNull String getDisplayName(@NonNull DataSet dataSet) throws IllegalArgumentException {
checkProvider(dataSet);
String result = dataSetFormatter.formatAsString(dataSet);
if (result == null) {
@@ -123,7 +122,7 @@ public DataMonikerSupport(String providerName, Formatter dataSourceF
}
@Override
- public TsMoniker toMoniker(DataSource dataSource) throws IllegalArgumentException {
+ public @NonNull TsMoniker toMoniker(@NonNull DataSource dataSource) throws IllegalArgumentException {
checkProvider(dataSource);
String id = dataSourceFormatter.formatAsString(dataSource);
if (id == null) {
@@ -133,7 +132,7 @@ public TsMoniker toMoniker(DataSource dataSource) throws IllegalArgumentExceptio
}
@Override
- public TsMoniker toMoniker(DataSet dataSet) throws IllegalArgumentException {
+ public @NonNull TsMoniker toMoniker(@NonNull DataSet dataSet) throws IllegalArgumentException {
checkProvider(dataSet);
String id = dataSetFormatter.formatAsString(dataSet);
if (id == null) {
@@ -143,13 +142,13 @@ public TsMoniker toMoniker(DataSet dataSet) throws IllegalArgumentException {
}
@Override
- public Optional toDataSet(TsMoniker moniker) throws IllegalArgumentException {
+ public @NonNull Optional toDataSet(@NonNull TsMoniker moniker) throws IllegalArgumentException {
checkProvider(moniker);
return dataSetParser.parseValue(moniker.getId());
}
@Override
- public Optional toDataSource(TsMoniker moniker) throws IllegalArgumentException {
+ public @NonNull Optional toDataSource(@NonNull TsMoniker moniker) throws IllegalArgumentException {
checkProvider(moniker);
return dataSourceParser.parseValue(moniker.getId());
}
@@ -167,12 +166,12 @@ public DataSourceBeanSupport(String providerName, DataSource.Converter param,
}
@Override
- public T newBean() {
+ public @NonNull T newBean() {
return param.getDefaultValue();
}
@Override
- public DataSource encodeBean(Object bean) throws IllegalArgumentException {
+ public @NonNull DataSource encodeBean(@NonNull Object bean) throws IllegalArgumentException {
Objects.requireNonNull(bean);
try {
DataSource.Builder result = DataSource.builder(providerName, version);
@@ -184,7 +183,7 @@ public DataSource encodeBean(Object bean) throws IllegalArgumentException {
}
@Override
- public T decodeBean(DataSource dataSource) throws IllegalArgumentException {
+ public @NonNull T decodeBean(@NonNull DataSource dataSource) throws IllegalArgumentException {
checkProvider(dataSource);
return param.get(dataSource);
}
@@ -198,31 +197,31 @@ public static final class DataSourceListSupport extends ProviderPart implements
public DataSourceListSupport(String providerName, Iterable dataSources, Consumer super DataSource> cacheCleaner) {
super(providerName);
- this.dataSources = StreamSupport.stream(dataSources.spliterator(), false).collect(List2.toUnmodifiableList());
+ this.dataSources = StreamSupport.stream(dataSources.spliterator(), false).toList();
this.eventSupport = DataSourceEventSupport.create();
this.cacheCleaner = Objects.requireNonNull(cacheCleaner);
dataSources.forEach(this::checkProvider);
}
@Override
- public void reload(DataSource dataSource) {
+ public void reload(@NonNull DataSource dataSource) {
checkProvider(dataSource);
cacheCleaner.accept(dataSource);
eventSupport.fireChanged(dataSource);
}
@Override
- public List getDataSources() {
+ public @NonNull List getDataSources() {
return dataSources;
}
@Override
- public void addDataSourceListener(DataSourceListener listener) {
+ public void addDataSourceListener(@NonNull DataSourceListener listener) {
eventSupport.add(listener);
}
@Override
- public void removeDataSourceListener(DataSourceListener listener) {
+ public void removeDataSourceListener(@NonNull DataSourceListener listener) {
eventSupport.remove(listener);
}
}
@@ -241,14 +240,14 @@ public DataSourceMutableListSupport(String providerName, LinkedHashSet getDataSources() {
+ public @NonNull List getDataSources() {
synchronized (dataSources) {
- return List2.copyOf(dataSources);
+ return List.copyOf(dataSources);
}
}
@Override
- public void addDataSourceListener(DataSourceListener listener) {
+ public void addDataSourceListener(@NonNull DataSourceListener listener) {
eventSupport.add(listener);
}
@Override
- public void removeDataSourceListener(DataSourceListener listener) {
+ public void removeDataSourceListener(@NonNull DataSourceListener listener) {
eventSupport.remove(listener);
}
}
@@ -330,13 +329,13 @@ public NoOpDataHierarchy(String providerName) {
}
@Override
- public List children(DataSource dataSource) throws IllegalArgumentException, IOException {
+ public @NonNull List children(@NonNull DataSource dataSource) throws IllegalArgumentException, IOException {
checkProvider(dataSource);
return Collections.emptyList();
}
@Override
- public List children(DataSet parent) throws IllegalArgumentException, IOException {
+ public @NonNull List children(@NonNull DataSet parent) throws IllegalArgumentException, IOException {
checkProvider(parent);
return Collections.emptyList();
}
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/internal/toolkit/base/tsp/stream/NoOpTsStream.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/internal/toolkit/base/tsp/stream/NoOpTsStream.java
index 3c5b6fc0..30c05d4a 100644
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/internal/toolkit/base/tsp/stream/NoOpTsStream.java
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/internal/toolkit/base/tsp/stream/NoOpTsStream.java
@@ -22,6 +22,7 @@
import jdplus.toolkit.base.tsp.stream.DataSetTs;
import jdplus.toolkit.base.tsp.stream.HasTsStream;
import jdplus.toolkit.base.tsp.util.DataSourcePreconditions;
+import org.checkerframework.checker.nullness.qual.NonNull;
import java.io.IOException;
import java.util.Objects;
@@ -37,14 +38,14 @@ public final class NoOpTsStream implements HasTsStream {
private final String providerName;
@Override
- public Stream getData(DataSource dataSource, TsInformationType type) throws IllegalArgumentException, IOException {
+ public @NonNull Stream getData(@NonNull DataSource dataSource, @NonNull TsInformationType type) throws IllegalArgumentException, IOException {
DataSourcePreconditions.checkProvider(providerName, dataSource);
Objects.requireNonNull(type);
return Stream.empty();
}
@Override
- public Stream getData(DataSet dataSet, TsInformationType type) throws IllegalArgumentException, IOException {
+ public @NonNull Stream getData(@NonNull DataSet dataSet, @NonNull TsInformationType type) throws IllegalArgumentException, IOException {
DataSourcePreconditions.checkProvider(providerName, dataSet);
Objects.requireNonNull(type);
return Stream.empty();
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/internal/toolkit/base/tsp/util/CaffeineCaching.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/internal/toolkit/base/tsp/util/CaffeineCaching.java
new file mode 100644
index 00000000..e1a63b48
--- /dev/null
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/internal/toolkit/base/tsp/util/CaffeineCaching.java
@@ -0,0 +1,54 @@
+package internal.toolkit.base.tsp.util;
+
+import com.github.benmanes.caffeine.cache.Cache;
+import com.github.benmanes.caffeine.cache.Caffeine;
+import com.github.benmanes.caffeine.cache.Ticker;
+import jdplus.toolkit.base.tsp.util.ShortLivedCache;
+import jdplus.toolkit.base.tsp.util.ShortLivedCaching;
+import lombok.NonNull;
+import nbbrd.design.VisibleForTesting;
+import nbbrd.service.ServiceProvider;
+
+import java.io.File;
+import java.time.Duration;
+
+@ServiceProvider
+public final class CaffeineCaching implements ShortLivedCaching {
+
+ public CaffeineCaching() {
+ this(Ticker.systemTicker());
+ }
+
+ private final @NonNull Ticker ticker;
+
+ @VisibleForTesting
+ CaffeineCaching(@NonNull Ticker ticker) {
+ this.ticker = ticker;
+ }
+
+ @Override
+ public @NonNull String getId() {
+ return "caffeine";
+ }
+
+ @Override
+ public @NonNull ShortLivedCache ofTtl(@NonNull Duration ttl) {
+ Cache result = Caffeine
+ .newBuilder()
+ .ticker(ticker)
+ .expireAfterWrite(ttl)
+ .softValues()
+ .build();
+ return new SimpleMapCache<>(result.asMap());
+ }
+
+ @Override
+ public @NonNull ShortLivedCache ofFile(@NonNull File file) {
+ Cache result = Caffeine
+ .newBuilder()
+ .ticker(ticker)
+ .softValues()
+ .build();
+ return new FileMapCache<>(result.asMap(), file);
+ }
+}
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/internal/toolkit/base/tsp/util/DefaultIOCacheFactory.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/internal/toolkit/base/tsp/util/DefaultIOCacheFactory.java
deleted file mode 100644
index 710b214b..00000000
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/internal/toolkit/base/tsp/util/DefaultIOCacheFactory.java
+++ /dev/null
@@ -1,100 +0,0 @@
-package internal.toolkit.base.tsp.util;
-
-import jdplus.toolkit.base.tsp.util.IOCache;
-import jdplus.toolkit.base.tsp.util.IOCacheFactory;
-import nbbrd.design.VisibleForTesting;
-import nbbrd.service.ServiceProvider;
-import org.checkerframework.checker.nullness.qual.NonNull;
-import org.checkerframework.checker.nullness.qual.Nullable;
-
-import java.io.File;
-import java.io.IOException;
-import java.time.Clock;
-import java.time.Duration;
-import java.time.Instant;
-import java.util.Objects;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.function.BiPredicate;
-
-@ServiceProvider
-public final class DefaultIOCacheFactory implements IOCacheFactory {
-
- @Override
- public @NonNull IOCache ofTtl(@NonNull Duration ttl) {
- return new DefaultIOCache<>(new ConcurrentHashMap<>(), Clock.systemDefaultZone(), ttlValidator(ttl));
- }
-
- @Override
- public @NonNull IOCache ofFile(@NonNull File file) {
- return new DefaultIOCache<>(new ConcurrentHashMap<>(), Clock.systemDefaultZone(), fileValidator(file));
- }
-
- @VisibleForTesting
- @FunctionalInterface
- interface Validator extends BiPredicate> {
- }
-
- @VisibleForTesting
- static Validator ttlValidator(Duration ttl) {
- Objects.requireNonNull(ttl);
- return (clock, holder) -> clock.instant().isBefore(holder.getCreationTime().plus(ttl));
- }
-
- @VisibleForTesting
- static Validator fileValidator(File file) {
- Objects.requireNonNull(file);
- return (clock, holder) -> file.exists() && file.lastModified() <= holder.getCreationTime().toEpochMilli();
- }
-
- @VisibleForTesting
- @lombok.RequiredArgsConstructor
- static final class DefaultIOCache implements IOCache {
-
- @lombok.NonNull
- private final ConcurrentMap> cache;
-
- @lombok.NonNull
- private final Clock clock;
-
- @lombok.NonNull
- private final Validator validator;
-
- @Override
- public void put(@NonNull K key, @NonNull V value) {
- Objects.requireNonNull(key);
- Objects.requireNonNull(value);
- cache.put(key, new ValueHolder<>(value, clock.instant()));
- }
-
- @Override
- public @Nullable V get(@NonNull K key) {
- Objects.requireNonNull(key);
- ValueHolder result = cache.get(key);
- if (result == null) {
- return null;
- }
- if (!validator.test(clock, result)) {
- cache.remove(key);
- return null;
- }
- return result.getValue();
- }
-
- @Override
- public void close() throws IOException {
- cache.clear();
- }
- }
-
- @VisibleForTesting
- @lombok.Value
- static class ValueHolder {
-
- @lombok.NonNull
- V value;
-
- @lombok.NonNull
- Instant creationTime;
- }
-}
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/internal/toolkit/base/tsp/util/FileMapCache.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/internal/toolkit/base/tsp/util/FileMapCache.java
new file mode 100644
index 00000000..72311d20
--- /dev/null
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/internal/toolkit/base/tsp/util/FileMapCache.java
@@ -0,0 +1,38 @@
+package internal.toolkit.base.tsp.util;
+
+import lombok.NonNull;
+import org.checkerframework.checker.nullness.qual.Nullable;
+
+import java.io.File;
+import java.util.Map;
+
+@lombok.Getter
+@lombok.RequiredArgsConstructor
+public final class FileMapCache implements MapCache {
+
+ private final @NonNull Map map;
+
+ private final @NonNull File file;
+
+ private long lastModified = Long.MIN_VALUE;
+
+ @Override
+ public void put(@NonNull K key, @NonNull V value) {
+ map.put(key, value);
+ }
+
+ @Override
+ public @Nullable V get(@NonNull K key) {
+ V result = map.get(key);
+ if (result == null) {
+ return null;
+ }
+ long timInMillis = file.lastModified();
+ if (timInMillis != lastModified) {
+ lastModified = timInMillis;
+ map.clear();
+ return null;
+ }
+ return result;
+ }
+}
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/internal/toolkit/base/tsp/util/MapCache.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/internal/toolkit/base/tsp/util/MapCache.java
new file mode 100644
index 00000000..57951b0f
--- /dev/null
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/internal/toolkit/base/tsp/util/MapCache.java
@@ -0,0 +1,13 @@
+package internal.toolkit.base.tsp.util;
+
+import jdplus.toolkit.base.tsp.util.ShortLivedCache;
+import lombok.NonNull;
+
+import java.util.Map;
+
+public sealed interface MapCache
+ extends ShortLivedCache
+ permits FileMapCache, SimpleMapCache, TtlMapCache {
+
+ @NonNull Map getMap();
+}
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/internal/toolkit/base/tsp/util/MapCaching.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/internal/toolkit/base/tsp/util/MapCaching.java
new file mode 100644
index 00000000..a871e957
--- /dev/null
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/internal/toolkit/base/tsp/util/MapCaching.java
@@ -0,0 +1,40 @@
+package internal.toolkit.base.tsp.util;
+
+import jdplus.toolkit.base.tsp.util.ShortLivedCache;
+import jdplus.toolkit.base.tsp.util.ShortLivedCaching;
+import lombok.NonNull;
+import nbbrd.design.VisibleForTesting;
+
+import java.io.File;
+import java.time.Duration;
+import java.util.HashMap;
+import java.util.function.LongSupplier;
+
+public final class MapCaching implements ShortLivedCaching {
+
+ public MapCaching() {
+ this(System::nanoTime);
+ }
+
+ private final LongSupplier ticker;
+
+ @VisibleForTesting
+ MapCaching(@NonNull LongSupplier ticker) {
+ this.ticker = ticker;
+ }
+
+ @Override
+ public @NonNull String getId() {
+ return "hashmap";
+ }
+
+ @Override
+ public @NonNull ShortLivedCache ofTtl(@NonNull Duration ttl) {
+ return new TtlMapCache<>(new HashMap<>(), ticker, ttl);
+ }
+
+ @Override
+ public @NonNull ShortLivedCache ofFile(@NonNull File file) {
+ return new FileMapCache<>(new HashMap<>(), file);
+ }
+}
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/internal/toolkit/base/tsp/util/SimpleMapCache.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/internal/toolkit/base/tsp/util/SimpleMapCache.java
new file mode 100644
index 00000000..e05ddf8a
--- /dev/null
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/internal/toolkit/base/tsp/util/SimpleMapCache.java
@@ -0,0 +1,23 @@
+package internal.toolkit.base.tsp.util;
+
+import lombok.NonNull;
+import org.checkerframework.checker.nullness.qual.Nullable;
+
+import java.util.Map;
+
+@lombok.Getter
+@lombok.RequiredArgsConstructor
+public final class SimpleMapCache implements MapCache {
+
+ private final @NonNull Map map;
+
+ @Override
+ public void put(@NonNull K key, @NonNull V value) {
+ map.put(key, value);
+ }
+
+ @Override
+ public @Nullable V get(@NonNull K key) {
+ return map.get(key);
+ }
+}
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/internal/toolkit/base/tsp/util/TtlMapCache.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/internal/toolkit/base/tsp/util/TtlMapCache.java
new file mode 100644
index 00000000..f83640ae
--- /dev/null
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/internal/toolkit/base/tsp/util/TtlMapCache.java
@@ -0,0 +1,47 @@
+package internal.toolkit.base.tsp.util;
+
+import lombok.NonNull;
+import lombok.RequiredArgsConstructor;
+import nbbrd.design.VisibleForTesting;
+import org.checkerframework.checker.nullness.qual.Nullable;
+
+import java.time.Duration;
+import java.util.Map;
+import java.util.function.LongSupplier;
+
+@lombok.Getter
+@RequiredArgsConstructor
+public final class TtlMapCache implements MapCache {
+
+ private final @NonNull Map> map;
+
+ private final @NonNull LongSupplier ticker;
+
+ private final @NonNull Duration ttl;
+
+ @Override
+ public void put(@NonNull K key, @NonNull V value) {
+ map.put(key, new Entry<>(value, ticker.getAsLong()));
+ }
+
+ @Override
+ public @Nullable V get(@NonNull K key) {
+ Entry result = map.get(key);
+ if (result == null) {
+ return null;
+ }
+ if (!validate(result.creationTime())) {
+ map.remove(key);
+ return null;
+ }
+ return result.value();
+ }
+
+ private boolean validate(long creationTime) {
+ return ticker.getAsLong() < creationTime + ttl.toNanos();
+ }
+
+ @VisibleForTesting
+ public record Entry(@NonNull V value, long creationTime) {
+ }
+}
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/jdplus/toolkit/base/tsp/DataSourceFactory.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/jdplus/toolkit/base/tsp/DataSourceFactory.java
index 3b45acb2..93008657 100644
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/jdplus/toolkit/base/tsp/DataSourceFactory.java
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/jdplus/toolkit/base/tsp/DataSourceFactory.java
@@ -101,4 +101,9 @@ default Optional getTs(@NonNull DataSet dataSet, @NonNull TsInformationType
}
});
}
+
+ default boolean open(@lombok.NonNull DataSource dataSource) {
+ return getProvider(DataSourceLoader.class, dataSource.getProviderName())
+ .map(loader -> loader.open(dataSource)).orElse(false);
+ }
}
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/jdplus/toolkit/base/tsp/DataSourceProvider.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/jdplus/toolkit/base/tsp/DataSourceProvider.java
index b4112037..af168cfe 100644
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/jdplus/toolkit/base/tsp/DataSourceProvider.java
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/jdplus/toolkit/base/tsp/DataSourceProvider.java
@@ -33,7 +33,7 @@
public interface DataSourceProvider extends TsProvider, HasDataSourceList, HasDataHierarchy, HasDataDisplayName, HasDataMoniker {
@Override
- default void reload(DataSource dataSource) {
+ default void reload(@NonNull DataSource dataSource) {
clearCache();
}
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/jdplus/toolkit/base/tsp/FileLoader.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/jdplus/toolkit/base/tsp/FileLoader.java
index 358452fe..0a8c26d7 100644
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/jdplus/toolkit/base/tsp/FileLoader.java
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/jdplus/toolkit/base/tsp/FileLoader.java
@@ -31,10 +31,12 @@
public interface FileLoader extends DataSourceLoader, FileFilter, HasFilePaths {
@Override
+ @NonNull
B newBean();
@Override
- B decodeBean(DataSource dataSource) throws IllegalArgumentException;
+ @NonNull
+ B decodeBean(@NonNull DataSource dataSource) throws IllegalArgumentException;
@NonNull
String getFileDescription();
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/jdplus/toolkit/base/tsp/HasDataSourceList.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/jdplus/toolkit/base/tsp/HasDataSourceList.java
index 995ff166..2c5fbc4f 100644
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/jdplus/toolkit/base/tsp/HasDataSourceList.java
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/jdplus/toolkit/base/tsp/HasDataSourceList.java
@@ -62,7 +62,7 @@ public interface HasDataSourceList {
void removeDataSourceListener(@NonNull DataSourceListener listener);
@NonNull
- public static HasDataSourceList of(
+ static HasDataSourceList of(
@NonNull String providerName,
@NonNull Iterable dataSources,
@NonNull Consumer super DataSource> cacheCleaner) {
@@ -70,7 +70,7 @@ public static HasDataSourceList of(
}
@NonNull
- public static HasDataSourceList of(
+ static HasDataSourceList of(
@NonNull String providerName,
@NonNull Iterable dataSources) {
return of(providerName, dataSources, InternalTsProvider.DO_NOTHING);
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/jdplus/toolkit/base/tsp/HasDataSourceMutableList.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/jdplus/toolkit/base/tsp/HasDataSourceMutableList.java
index b18f86f8..95dc0723 100644
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/jdplus/toolkit/base/tsp/HasDataSourceMutableList.java
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/jdplus/toolkit/base/tsp/HasDataSourceMutableList.java
@@ -62,12 +62,12 @@ default void closeAll() {
}
@NonNull
- public static HasDataSourceMutableList of(@NonNull String providerName, @NonNull Consumer super DataSource> cacheCleaner) {
+ static HasDataSourceMutableList of(@NonNull String providerName, @NonNull Consumer super DataSource> cacheCleaner) {
return new InternalTsProvider.DataSourceMutableListSupport(providerName, new LinkedHashSet<>(), cacheCleaner);
}
@NonNull
- public static HasDataSourceMutableList of(@NonNull String providerName) {
+ static HasDataSourceMutableList of(@NonNull String providerName) {
return of(providerName, InternalTsProvider.DO_NOTHING);
}
}
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/jdplus/toolkit/base/tsp/TsMeta.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/jdplus/toolkit/base/tsp/TsMeta.java
index 5cc8d02f..1dc6557a 100644
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/jdplus/toolkit/base/tsp/TsMeta.java
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/jdplus/toolkit/base/tsp/TsMeta.java
@@ -1,23 +1,29 @@
/*
* Copyright 2018 National Bank of Belgium
- *
- * Licensed under the EUPL, Version 1.1 or - as soon they will be approved
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved
* by the European Commission - subsequent versions of the EUPL (the "Licence");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
- *
+ *
* http://ec.europa.eu/idabc/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
+ *
+ * Unless required by applicable law or agreed to in writing, software
* distributed under the Licence is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
+ * See the Licence for the specific language governing permissions and
* limitations under the Licence.
*/
package jdplus.toolkit.base.tsp;
-import jdplus.toolkit.base.tsp.util.ObsFormat;
import internal.toolkit.base.tsp.DefaultTsMeta;
+import jdplus.toolkit.base.tsp.fixme.Strings;
+import jdplus.toolkit.base.tsp.util.ObsFormat;
+import nbbrd.io.text.Formatter;
+import nbbrd.io.text.Parser;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.checkerframework.checker.nullness.qual.Nullable;
+
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
@@ -25,16 +31,9 @@
import java.util.function.BiConsumer;
import java.util.function.Function;
-import jdplus.toolkit.base.tsp.fixme.Strings;
-import nbbrd.io.text.Formatter;
-import nbbrd.io.text.Parser;
-import org.checkerframework.checker.nullness.qual.NonNull;
-import org.checkerframework.checker.nullness.qual.Nullable;
-
/**
- *
- * @author Philippe Charles
* @param
+ * @author Philippe Charles
*/
public interface TsMeta {
@@ -82,55 +81,55 @@ static TsMeta onTimestamp() {
// from ec.tss.Ts
@Deprecated
- static final TsMeta SOURCE_OLD = onString("tsmoniker.source");
+ TsMeta SOURCE_OLD = onString("tsmoniker.source");
// from ec.tss.Ts
@Deprecated
- static final TsMeta ID_OLD = onString("tsmoniker.id");
+ TsMeta ID_OLD = onString("tsmoniker.id");
// from ec.tss.Ts
@Deprecated
- static final TsMeta DYNAMIC = onString("dynamic");
+ TsMeta DYNAMIC = onString("dynamic");
// from ec.tss.Ts
- static final TsMeta BEG = onDateTime("@beg", "yyyy-MM-dd", Locale.ROOT);
+ TsMeta BEG = onDateTime("@beg", "yyyy-MM-dd", Locale.ROOT);
// from ec.tss.Ts
- static final TsMeta END = onDateTime("@end", "yyyy-MM-dd", Locale.ROOT);
+ TsMeta END = onDateTime("@end", "yyyy-MM-dd", Locale.ROOT);
// from ec.tss.Ts
- static final TsMeta> CONFIDENTIAL = onString("@confidential");
+ TsMeta> CONFIDENTIAL = onString("@confidential");
// from ec.tstoolkit.MetaData
- static final TsMeta DESCRIPTION = onString("@description");
+ TsMeta DESCRIPTION = onString("@description");
// from ec.tstoolkit.MetaData
- static final TsMeta OWNER = onString("@owner");
+ TsMeta OWNER = onString("@owner");
// from ec.tstoolkit.MetaData
- static final TsMeta SOURCE = onString("@source");
+ TsMeta SOURCE = onString("@source");
// from ec.tstoolkit.MetaData
- static final TsMeta ID = onString("@id");
+ TsMeta ID = onString("@id");
// from ec.tstoolkit.MetaData
- static final TsMeta TIMESTAMP = onTimestamp();
+ TsMeta TIMESTAMP = onTimestamp();
// from ec.tstoolkit.MetaData
- static final TsMeta> DOCUMENT = onString("@document");
+ TsMeta> DOCUMENT = onString("@document");
// from ec.tstoolkit.MetaData
- static final TsMeta> SUMMARY = onString("@summary");
+ TsMeta> SUMMARY = onString("@summary");
// from ec.tstoolkit.MetaData
- static final TsMeta NOTE = onString("@note");
+ TsMeta NOTE = onString("@note");
// from ec.tstoolkit.MetaData
- static final TsMeta> TODO = onString("@todo");
+ TsMeta> TODO = onString("@todo");
// from ec.tstoolkit.MetaData
- static final TsMeta> ALGORITHM = onString("@algorithm");
+ TsMeta> ALGORITHM = onString("@algorithm");
// from ec.tstoolkit.MetaData
- static final TsMeta> QUALITY = onString("@quality");
+ TsMeta> QUALITY = onString("@quality");
}
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/jdplus/toolkit/base/tsp/cube/BulkCubeConnection.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/jdplus/toolkit/base/tsp/cube/BulkCubeConnection.java
index 787791c2..6a0956a4 100644
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/jdplus/toolkit/base/tsp/cube/BulkCubeConnection.java
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/jdplus/toolkit/base/tsp/cube/BulkCubeConnection.java
@@ -16,8 +16,8 @@
*/
package jdplus.toolkit.base.tsp.cube;
-import jdplus.toolkit.base.tsp.util.IOCache;
-import jdplus.toolkit.base.tsp.util.IOCacheFactory;
+import jdplus.toolkit.base.tsp.util.ShortLivedCache;
+import jdplus.toolkit.base.tsp.util.ShortLivedCaching;
import lombok.AccessLevel;
import nbbrd.io.IOIterator;
import nbbrd.io.Resource;
@@ -43,7 +43,7 @@
public final class BulkCubeConnection implements CubeConnection {
@NonNull
- public static CubeConnection of(@NonNull CubeConnection delegate, @NonNull BulkCube options, @NonNull IOCacheFactory cacheFactory) {
+ public static CubeConnection of(@NonNull CubeConnection delegate, @NonNull BulkCube options, @NonNull ShortLivedCaching cacheFactory) {
return options.isCacheEnabled()
? new BulkCubeConnection(delegate, options.getDepth(), cacheFactory.ofTtl(options.getTtl()))
: delegate;
@@ -56,14 +56,14 @@ public static CubeConnection of(@NonNull CubeConnection delegate, @NonNull BulkC
private final int depth;
@lombok.NonNull
- private final IOCache> cache;
+ private final ShortLivedCache> cache;
private int getCacheLevel() throws IOException {
return Math.max(0, delegate.getRoot().getMaxLevel() - depth);
}
@Override
- public Stream getAllSeriesWithData(CubeId ref) throws IOException {
+ public @NonNull Stream getAllSeriesWithData(@NonNull CubeId ref) throws IOException {
if (!ref.isSeries()) {
int cacheLevel = getCacheLevel();
if (ref.getLevel() == cacheLevel) {
@@ -79,7 +79,7 @@ public Stream getAllSeriesWithData(CubeId ref) throws IOExce
}
@Override
- public Optional getSeriesWithData(CubeId ref) throws IOException {
+ public @NonNull Optional getSeriesWithData(@NonNull CubeId ref) throws IOException {
if (ref.isSeries()) {
int cacheLevel = getCacheLevel();
CubeId ancestor = ref.getAncestor(cacheLevel);
@@ -93,53 +93,53 @@ public Optional getSeriesWithData(CubeId ref) throws IOExcep
}
@Override
- public Optional testConnection() {
+ public @NonNull Optional testConnection() {
return delegate.testConnection();
}
@Override
- public CubeId getRoot() throws IOException {
+ public @NonNull CubeId getRoot() throws IOException {
return delegate.getRoot();
}
@Override
- public Stream getAllSeries(CubeId id) throws IOException {
+ public @NonNull Stream getAllSeries(@NonNull CubeId id) throws IOException {
return delegate.getAllSeries(id);
}
@Override
- public Optional getSeries(CubeId id) throws IOException {
+ public @NonNull Optional getSeries(@NonNull CubeId id) throws IOException {
return delegate.getSeries(id);
}
@Override
- public Stream getChildren(CubeId id) throws IOException {
+ public @NonNull Stream getChildren(@NonNull CubeId id) throws IOException {
return delegate.getChildren(id);
}
@Override
- public String getDisplayName() throws IOException {
+ public @NonNull String getDisplayName() throws IOException {
return delegate.getDisplayName();
}
@Override
- public String getDisplayName(CubeId id) throws IOException {
+ public @NonNull String getDisplayName(@NonNull CubeId id) throws IOException {
return delegate.getDisplayName(id);
}
@Override
- public String getDisplayNodeName(CubeId id) throws IOException {
+ public @NonNull String getDisplayNodeName(@NonNull CubeId id) throws IOException {
return delegate.getDisplayNodeName(id);
}
@Override
public void close() throws IOException {
- Resource.closeBoth(cache, delegate);
+ delegate.close();
}
@NonNull
private static Stream getOrLoad(
- @NonNull IOCache> cache,
+ @NonNull ShortLivedCache> cache,
@NonNull CubeId key,
@NonNull IOFunction> loader) throws IOException {
@@ -160,7 +160,7 @@ private static Stream getOrLoad(
private static final class CachingIterator implements IOIterator, Closeable {
private final CubeId key;
- private final IOCache cache;
+ private final ShortLivedCache> cache;
private final IOIterator delegate;
private final Closeable closeable;
@@ -179,13 +179,13 @@ public CubeSeriesWithData nextWithIO() throws IOException, NoSuchElementExceptio
}
@Override
- public Stream asStream() {
+ public @lombok.NonNull Stream asStream() {
return IOIterator.super.asStream().onClose(IORunnable.unchecked(this::close));
}
@Override
public void close() throws IOException {
- Resource.closeBoth(this::flushToCache, closeable::close);
+ Resource.closeBoth(this::flushToCache, closeable);
}
private void flushToCache() throws IOException {
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/jdplus/toolkit/base/tsp/cube/BulkCubeHandler.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/jdplus/toolkit/base/tsp/cube/BulkCubeHandler.java
index 9b6918ca..15b93496 100644
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/jdplus/toolkit/base/tsp/cube/BulkCubeHandler.java
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/jdplus/toolkit/base/tsp/cube/BulkCubeHandler.java
@@ -18,7 +18,7 @@ public final class BulkCubeHandler implements PropertyHandler {
private final PropertyHandler depth;
@Override
- public @NonNull BulkCube get(@NonNull Function super String, ? extends CharSequence> properties) {
+ public @NonNull @org.checkerframework.checker.nullness.qual.NonNull BulkCube get(@NonNull @org.checkerframework.checker.nullness.qual.NonNull Function super String, ? extends CharSequence> properties) {
return BulkCube
.builder()
.ttl(ttl.get(properties))
@@ -27,7 +27,7 @@ public final class BulkCubeHandler implements PropertyHandler {
}
@Override
- public void set(@NonNull BiConsumer super String, ? super String> properties, @Nullable BulkCube value) {
+ public void set(@NonNull @org.checkerframework.checker.nullness.qual.NonNull BiConsumer super String, ? super String> properties, @Nullable BulkCube value) {
if (value != null) {
ttl.set(properties, value.getTtl());
depth.set(properties, value.getDepth());
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/jdplus/toolkit/base/tsp/cube/CubeSupport.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/jdplus/toolkit/base/tsp/cube/CubeSupport.java
index 8617f684..189c9b7c 100644
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/jdplus/toolkit/base/tsp/cube/CubeSupport.java
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/jdplus/toolkit/base/tsp/cube/CubeSupport.java
@@ -63,7 +63,7 @@ public final class CubeSupport implements HasDataHierarchy, HasTsStream, HasData
//
@Override
- public List children(DataSource dataSource) throws IOException {
+ public @NonNull List children(@NonNull DataSource dataSource) throws IOException {
DataSourcePreconditions.checkProvider(providerName, dataSource);
try (CubeConnection connection = cube.open(dataSource)) {
@@ -91,7 +91,7 @@ public List children(DataSource dataSource) throws IOException {
}
@Override
- public List children(DataSet parent) throws IOException {
+ public @NonNull List children(@NonNull DataSet parent) throws IOException {
DataSourcePreconditions.checkProvider(providerName, parent);
if (!DataSet.Kind.COLLECTION.equals(parent.getKind())) {
@@ -121,7 +121,7 @@ private static DataSet.Kind getDataSetKind(CubeId cubeId) {
//
@Override
- public Stream getData(DataSource dataSource, TsInformationType type) throws IOException {
+ public @NonNull Stream getData(@NonNull DataSource dataSource, @NonNull TsInformationType type) throws IOException {
DataSourcePreconditions.checkProvider(providerName, dataSource);
CubeConnection connection = cube.open(dataSource);
@@ -142,7 +142,7 @@ public Stream getData(DataSource dataSource, TsInformationType type)
}
@Override
- public Stream getData(DataSet dataSet, TsInformationType type) throws IOException {
+ public @NonNull Stream getData(@NonNull DataSet dataSet, @NonNull TsInformationType type) throws IOException {
DataSourcePreconditions.checkProvider(providerName, dataSet);
CubeConnection connection = cube.open(dataSet.getDataSource());
@@ -168,7 +168,7 @@ public Stream getData(DataSet dataSet, TsInformationType type) throws
//
@Override
- public String getDisplayName(DataSource dataSource) throws IllegalArgumentException {
+ public @NonNull String getDisplayName(@NonNull DataSource dataSource) throws IllegalArgumentException {
DataSourcePreconditions.checkProvider(providerName, dataSource);
try (CubeConnection connection = cube.open(dataSource)) {
@@ -179,7 +179,7 @@ public String getDisplayName(DataSource dataSource) throws IllegalArgumentExcept
}
@Override
- public String getDisplayName(DataSet dataSet) throws IllegalArgumentException {
+ public @NonNull String getDisplayName(@NonNull DataSet dataSet) throws IllegalArgumentException {
DataSourcePreconditions.checkProvider(providerName, dataSet);
try (CubeConnection connection = cube.open(dataSet.getDataSource())) {
@@ -191,7 +191,7 @@ public String getDisplayName(DataSet dataSet) throws IllegalArgumentException {
}
@Override
- public String getDisplayNodeName(DataSet dataSet) throws IllegalArgumentException {
+ public @NonNull String getDisplayNodeName(@NonNull DataSet dataSet) throws IllegalArgumentException {
DataSourcePreconditions.checkProvider(providerName, dataSet);
try (CubeConnection connection = cube.open(dataSet.getDataSource())) {
@@ -244,12 +244,12 @@ private static final class ByNameParam implements DataSet.Converter {
private final CubeId root;
@Override
- public CubeId getDefaultValue() {
+ public @NonNull CubeId getDefaultValue() {
return root;
}
@Override
- public CubeId get(DataSet config) {
+ public @NonNull CubeId get(@NonNull DataSet config) {
String[] dimValues = new String[root.getMaxLevel()];
int i = 0;
while (i < dimValues.length) {
@@ -263,7 +263,7 @@ public CubeId get(DataSet config) {
}
@Override
- public void set(DataSet.Builder builder, CubeId value) {
+ public void set(DataSet.@NonNull Builder builder, CubeId value) {
for (int i = 0; i < value.getLevel(); i++) {
builder.parameter(value.getDimensionId(i), value.getDimensionValue(i));
}
@@ -278,12 +278,12 @@ private static final class BySeparatorParam implements DataSet.Converter
private final String name;
@Override
- public CubeId getDefaultValue() {
+ public @NonNull CubeId getDefaultValue() {
return root;
}
@Override
- public CubeId get(DataSet config) {
+ public @NonNull CubeId get(@NonNull DataSet config) {
String value = config.getParameter(name);
if (value == null || value.isEmpty()) {
return getDefaultValue();
@@ -300,7 +300,7 @@ public CubeId get(DataSet config) {
}
@Override
- public void set(DataSet.Builder builder, CubeId value) {
+ public void set(DataSet.@NonNull Builder builder, CubeId value) {
if (value.getLevel() > 0) {
StringBuilder sb = new StringBuilder();
sb.append(value.getDimensionValue(0));
diff --git a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/jdplus/toolkit/base/tsp/cube/TableAsCubeConnection.java b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/jdplus/toolkit/base/tsp/cube/TableAsCubeConnection.java
index 32354f0c..9abc4091 100644
--- a/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/jdplus/toolkit/base/tsp/cube/TableAsCubeConnection.java
+++ b/jdplus-main-base/jdplus-toolkit-base-parent/jdplus-toolkit-base-tsp/src/main/java/jdplus/toolkit/base/tsp/cube/TableAsCubeConnection.java
@@ -127,13 +127,13 @@ public interface ChildrenCursor extends TableCursor {
private final Resource> resource;
@Override
- public Optional testConnection() {
+ public @NonNull Optional testConnection() {
Exception result = resource.testConnection();
return result != null ? Optional.of(WrappedIOException.wrap(result)) : Optional.empty();
}
@Override
- public CubeId getRoot() throws IOException {
+ public @NonNull CubeId getRoot() throws IOException {
try {
return resource.getRoot();
} catch (Exception ex) {
@@ -142,7 +142,7 @@ public CubeId getRoot() throws IOException {
}
@Override
- public Stream getAllSeries(CubeId id) throws IOException {
+ public @NonNull Stream getAllSeries(@NonNull CubeId id) throws IOException {
try {
AllSeriesCursor cursor = resource.getAllSeriesCursor(id);
return new AllSeriesIterator(id, cursor).asStream();
@@ -152,7 +152,7 @@ public Stream getAllSeries(CubeId id) throws IOException {
}
@Override
- public Stream getAllSeriesWithData(CubeId id) throws IOException {
+ public @NonNull Stream