diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 969f1bf..9511050 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,7 +27,7 @@ jobs: with: version: ${{ matrix.version }} arch: ${{ matrix.arch }} - - uses: actions/cache@v1 + - uses: actions/cache@v3 env: cache-name: cache-artifacts with: diff --git a/Project.toml b/Project.toml index d9cc2ff..7aaf3dd 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "StateSpaceLearning" uuid = "971c4b7c-2c4e-4bac-8525-e842df3cde7b" authors = ["andreramosfc "] -version = "1.4.2" +version = "1.4.3" [deps] Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" diff --git a/src/models/structural_model.jl b/src/models/structural_model.jl index 8200490..1f79683 100644 --- a/src/models/structural_model.jl +++ b/src/models/structural_model.jl @@ -97,7 +97,7 @@ mutable struct StructuralModel <: StateSpaceLearningModel else @assert seasonal ? size(y, 1) > minimum(freq_seasonal) : true "Time series must be longer than the seasonal period" end - @assert 1 <= stochastic_start < length(y) "stochastic_start must be greater than or equal to 1" + @assert 1 <= stochastic_start < length(y) "stochastic_start must be greater than or equal to 1 and smaller than the length of the time series" @assert 0 < dumping_cycle <= 1 "dumping_cycle must be greater than 0 and less than or equal to 1" if cycle_period != 0 && !isempty(cycle_period) if typeof(cycle_period) <: Vector @@ -249,8 +249,14 @@ o_size(T::Int, stochastic_start::Int)::Int = T - max(1, stochastic_start) + 1 # Returns - `Int`: Size of ϕ calculated from T. """ -ϕ_size(T::Int, ζ_ω_threshold::Int, stochastic_start::Int) = - 2 * (T - max(2, stochastic_start) + 1) - (ζ_ω_threshold * 2) +function ϕ_size(T::Int, ζ_ω_threshold::Int, stochastic_start::Int) + ζ_ω_threshold = ζ_ω_threshold == 0 ? 1 : ζ_ω_threshold + if stochastic_start == 1 + return (2 * (T - max(2, stochastic_start) + 1) - (ζ_ω_threshold * 2)) - 2 + else + return (2 * (T - max(2, stochastic_start) + 1) - (ζ_ω_threshold * 2)) + end +end """ create_ξ(T::Int, steps_ahead::Int, stochastic_start::Int)::Matrix @@ -400,7 +406,12 @@ function create_ϕ( ) end - return X[:, 1:(end - (ζ_ω_threshold * 2))] + ζ_ω_threshold = ζ_ω_threshold == 0 ? 1 : ζ_ω_threshold + if stochastic_start == 1 + return X[:, 3:(end - (ζ_ω_threshold * 2))] + else + return X[:, 1:(end - (ζ_ω_threshold * 2))] + end end """ @@ -933,12 +944,12 @@ function get_innovation_simulation_X( elseif occursin("ϕ_", innovation) i = parse(Int, split(innovation, "_")[2]) deterministic_cycle_matrix = create_deterministic_cycle_matrix( - model.cycle_matrix, length(model.y), steps_ahead + model.cycle_matrix, length(model.y), steps_ahead + 1 ) return create_ϕ( deterministic_cycle_matrix[i], - length(model.y), - steps_ahead, + length(model.y) + steps_ahead + 1, + 0, model.ζ_ω_threshold, model.stochastic_start, ) diff --git a/test/models/structural_model.jl b/test/models/structural_model.jl index fe7a091..f692c54 100644 --- a/test/models/structural_model.jl +++ b/test/models/structural_model.jl @@ -99,8 +99,8 @@ end @test StateSpaceLearning.ω_size(10, 2, 0, 1) == 9 @test StateSpaceLearning.ω_size(10, 2, 2, 1) == 7 @test StateSpaceLearning.o_size(10, 1) == 10 - @test StateSpaceLearning.ϕ_size(10, 0, 1) == 18 - @test StateSpaceLearning.ϕ_size(10, 2, 1) == 14 + @test StateSpaceLearning.ϕ_size(10, 0, 1) == 14 + @test StateSpaceLearning.ϕ_size(10, 2, 1) == 12 @test StateSpaceLearning.ξ_size(10, 5) == 5 @test StateSpaceLearning.ζ_size(10, 2, 5) == 3 @@ -108,7 +108,7 @@ end @test StateSpaceLearning.ω_size(10, 2, 0, 5) == 6 @test StateSpaceLearning.ω_size(10, 2, 2, 5) == 4 @test StateSpaceLearning.o_size(10, 6) == 5 - @test StateSpaceLearning.ϕ_size(10, 0, 5) == 12 + @test StateSpaceLearning.ϕ_size(10, 0, 5) == 10 X_ξ1 = StateSpaceLearning.create_ξ(5, 0, 1) X_ξ2 = StateSpaceLearning.create_ξ(5, 2, 1) @@ -255,11 +255,11 @@ end isapprox.( X_ϕ1, [ - 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 - 0.866025 0.5 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 - 0.5 0.866025 0.866025 0.5 1.0 0.0 0.0 0.0 0.0 0.0 - 2.77556e-16 1.0 0.5 0.866025 0.866025 0.5 1.0 0.0 0.0 0.0 - -0.5 0.866025 2.77556e-16 1.0 0.5 0.866025 0.866025 0.5 1.0 0.0 + 0.0 0.0 0.0 0.0 0.0 0.0 + 1.0 0.0 0.0 0.0 0.0 0.0 + 0.866025 0.5 1.0 0.0 0.0 0.0 + 0.5 0.866025 0.866025 0.5 1.0 0.0 + 2.77556e-16 1.0 0.5 0.866025 0.866025 0.5 ], atol=1e-6, ), @@ -842,11 +842,45 @@ end isapprox.( X4, [ - 1.0 0.0 0.0 0.0 0.0 0.0 - -0.5 0.866025 1.0 0.0 0.0 0.0 - -0.5 -0.866025 -0.5 0.866025 1.0 0.0 - 1.0 -6.10623e-16 -0.5 -0.866025 -0.5 0.866025 - -0.5 0.866025 1.0 -6.10623e-16 -0.5 -0.866025 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + -0.5 0.866025 1.0 0.0 0.0 0.0 0.0 0.0 + -0.5 -0.866025 -0.5 0.866025 1.0 0.0 0.0 0.0 + 1.0 -6.10623e-16 -0.5 -0.866025 -0.5 0.866025 1.0 0.0 + -0.5 0.866025 1.0 -6.10623e-16 -0.5 -0.866025 -0.5 0.866025 + ], + atol=1e-6, + ), + ) + + model2 = StateSpaceLearning.StructuralModel( + rand(4); + level=true, + stochastic_level=true, + trend=true, + stochastic_trend=true, + seasonal=true, + stochastic_seasonal=true, + freq_seasonal=2, + outlier=true, + cycle_period=3, + stochastic_cycle=true, + ζ_ω_threshold=0, + Exogenous_X=zeros(10, 0), + stochastic_start=3, + ) + X5 = StateSpaceLearning.get_innovation_simulation_X(model2, innovation4, steps_ahead) + @assert all( + isapprox.( + X5, + [ + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + -0.5 0.866025 1.0 0.0 0.0 0.0 0.0 0.0 + -0.5 -0.866025 -0.5 0.866025 1.0 0.0 0.0 0.0 + 1.0 -6.10623e-16 -0.5 -0.866025 -0.5 0.866025 1.0 0.0 + -0.5 0.866025 1.0 -6.10623e-16 -0.5 -0.866025 -0.5 0.866025 ], atol=1e-6, ),