diff --git a/Project.toml b/Project.toml index 4f88133..386f1ba 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "StateSpaceLearning" uuid = "971c4b7c-2c4e-4bac-8525-e842df3cde7b" authors = ["andreramosfc "] -version = "0.2.0" +version = "0.2.1" [deps] Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" diff --git a/src/StateSpaceLearning.jl b/src/StateSpaceLearning.jl index 07d8b4b..bf4a835 100644 --- a/src/StateSpaceLearning.jl +++ b/src/StateSpaceLearning.jl @@ -11,7 +11,7 @@ include("datasets.jl") const DEFAULT_COMPONENTS_PARAMETERS = ["level", "stochastic_level", "trend", "stochastic_trend", "seasonal", "stochastic_seasonal", "freq_seasonal"] -export fit_model, forecast +export fit_model, forecast, simulate """ fit_model(y::Vector{Fl}; @@ -82,20 +82,20 @@ function fit_model(y::Vector{Fl}; end """ - forecast(output::Output, steps_ahead::Int64; Exogenous_Forecast::Union{Matrix{Fl}, Missing}=missing)::Vector{Float64} where Fl + forecast(output::Output, steps_ahead::Int; Exogenous_Forecast::Union{Matrix{Fl}, Missing}=missing)::Vector{Float64} where Fl Returns the forecast for a given number of steps ahead using the provided StateSpaceLearning output and exogenous forecast data. # Arguments - `output::Output`: Output object obtained from model fitting. - - `steps_ahead::Int64`: Number of steps ahead for forecasting. + - `steps_ahead::Int`: Number of steps ahead for forecasting. - `Exogenous_Forecast::Matrix{Fl}`: Exogenous variables forecast (default: zeros(steps_ahead, 0)) # Returns - `Vector{Float64}`: Vector containing forecasted values. """ -function forecast(output::Output, steps_ahead::Int64; Exogenous_Forecast::Matrix{Fl}=zeros(steps_ahead, 0))::Vector{Float64} where Fl +function forecast(output::Output, steps_ahead::Int; Exogenous_Forecast::Matrix{Fl}=zeros(steps_ahead, 0))::Vector{Float64} where Fl @assert length(output.components["Exogenous_X"]["Indexes"]) == size(Exogenous_Forecast, 2) "If an exogenous matrix was utilized in the estimation procedure, it must be provided its prediction for the forecast procedure. If no exogenous matrix was utilized, Exogenous_Forecast must be missing" @assert size(Exogenous_Forecast, 1) == steps_ahead "Exogenous_Forecast must have the same number of rows as steps_ahead" @@ -107,21 +107,21 @@ function forecast(output::Output, steps_ahead::Int64; Exogenous_Forecast::Matrix end """ -simulate(output::Output, steps_ahead::Int64; N_scenarios::Int64 = 1000, simulate_outliers::Bool = true, Exogenous_Forecast::Matrix{Fl}=zeros(steps_ahead, 0))::Matrix{Float64} where Fl +simulate(output::Output, steps_ahead::Int; N_scenarios::Int = 1000, simulate_outliers::Bool = true, Exogenous_Forecast::Matrix{Fl}=zeros(steps_ahead, 0))::Matrix{Float64} where Fl Generate simulations for a given number of steps ahead using the provided StateSpaceLearning output and exogenous forecast data. # Arguments - `output::Output`: Output object obtained from model fitting. - - `steps_ahead::Int64`: Number of steps ahead for simulation. - - `N_scenarios::Int64`: Number of scenarios to simulate (default: 1000). + - `steps_ahead::Int`: Number of steps ahead for simulation. + - `N_scenarios::Int`: Number of scenarios to simulate (default: 1000). - `simulate_outliers::Bool`: If true, simulate outliers (default: true). - `Exogenous_Forecast::Matrix{Fl}`: Exogenous variables forecast (default: zeros(steps_ahead, 0)) # Returns - `Matrix{Float64}`: Matrix containing simulated values. """ -function simulate(output::Output, steps_ahead::Int64, N_scenarios::Int64; simulate_outliers::Bool = true, +function simulate(output::Output, steps_ahead::Int, N_scenarios::Int; simulate_outliers::Bool = true, innovation_functions::Dict = Dict("stochastic_level" => Dict("create_X" => create_ξ, "component" => "ξ", "args" => (length(output.ε) + steps_ahead + 1, 0)), "stochastic_trend" => Dict("create_X" => create_ζ, "component" => "ζ", "args" => (length(output.ε) + steps_ahead + 1, 0, 1)), "stochastic_seasonal" => Dict("create_X" => create_ω, "component" => "ω", "args" => (length(output.ε) + steps_ahead + 1, output.model_input["freq_seasonal"], 0, 1))), diff --git a/src/estimation_procedure/default_estimation_procedure.jl b/src/estimation_procedure/default_estimation_procedure.jl index 29e8e17..c098710 100644 --- a/src/estimation_procedure/default_estimation_procedure.jl +++ b/src/estimation_procedure/default_estimation_procedure.jl @@ -25,19 +25,19 @@ function get_dummy_indexes(Exogenous_X::Matrix{Fl}) where{Fl} end """ - get_outlier_duplicate_columns(Estimation_X::Matrix{Tl}, components_indexes::Dict{String, Vector{Int64}}) where{Tl} + get_outlier_duplicate_columns(Estimation_X::Matrix{Tl}, components_indexes::Dict{String, Vector{Int}}) where{Tl} Identifies and returns the indexes of outlier columns that are duplicates of dummy variables in the exogenous matrix. # Arguments - `Estimation_X::Matrix{Tl}`: Matrix used for estimation. - - `components_indexes::Dict{String, Vector{Int64}}`: Dictionary containing indexes for different components. + - `components_indexes::Dict{String, Vector{Int}}`: Dictionary containing indexes for different components. # Returns - `Vector{Int}`: Vector containing the indexes of outlier columns that are duplicates of dummy variables in the exogenous matrix. """ -function get_outlier_duplicate_columns(Estimation_X::Matrix{Tl}, components_indexes::Dict{String, Vector{Int64}}) where{Tl} +function get_outlier_duplicate_columns(Estimation_X::Matrix{Tl}, components_indexes::Dict{String, Vector{Int}}) where{Tl} if !haskey(components_indexes, "o") return [] else @@ -115,7 +115,7 @@ end """ fit_lasso(Estimation_X::Matrix{Tl}, estimation_y::Vector{Fl}, α::Float64, information_criteria::String, - penalize_exogenous::Bool, components_indexes::Dict{String, Vector{Int64}}, penalty_factor::Vector{Float64}; + penalize_exogenous::Bool, components_indexes::Dict{String, Vector{Int}}, penalty_factor::Vector{Float64}; rm_average::Bool = false)::Tuple{Vector{Float64}, Vector{Float64}} where {Tl, Fl} Fits a Lasso regression model to the provided data and returns coefficients and residuals based on selected criteria. @@ -126,7 +126,7 @@ end - `α::Float64`: Elastic net control factor between ridge (α=0) and lasso (α=1) (default: 0.1). - `information_criteria::String`: Information Criteria method for hyperparameter selection (default: aic). - `penalize_exogenous::Bool`: Flag for selecting exogenous variables. When false the penalty factor for these variables will be set to 0. - - `components_indexes::Dict{String, Vector{Int64}}`: Dictionary containing indexes for different components. + - `components_indexes::Dict{String, Vector{Int}}`: Dictionary containing indexes for different components. - `penalty_factor::Vector{Float64}`: Penalty factors for each predictor. - `rm_average::Bool`: Flag to consider if the intercept will be calculated is the average of the time series (default: false). @@ -134,7 +134,7 @@ end - `Tuple{Vector{Float64}, Vector{Float64}}`: Tuple containing coefficients and residuals of the fitted Lasso model. """ -function fit_lasso(Estimation_X::Matrix{Tl}, estimation_y::Vector{Fl}, α::Float64, information_criteria::String, penalize_exogenous::Bool, components_indexes::Dict{String, Vector{Int64}}, penalty_factor::Vector{Float64}; rm_average::Bool = false)::Tuple{Vector{Float64}, Vector{Float64}} where {Tl, Fl} +function fit_lasso(Estimation_X::Matrix{Tl}, estimation_y::Vector{Fl}, α::Float64, information_criteria::String, penalize_exogenous::Bool, components_indexes::Dict{String, Vector{Int}}, penalty_factor::Vector{Float64}; rm_average::Bool = false)::Tuple{Vector{Float64}, Vector{Float64}} where {Tl, Fl} outlier_duplicate_columns = get_outlier_duplicate_columns(Estimation_X, components_indexes) penalty_factor[outlier_duplicate_columns] .= Inf @@ -168,7 +168,7 @@ end """ fit_adalasso(Estimation_X::Matrix{Tl}, estimation_y::Vector{Fl}, α::Float64, information_criteria::String, - components_indexes::Dict{String, Vector{Int64}}, + components_indexes::Dict{String, Vector{Int}}, ε::Float64, penalize_exogenous::Bool)::Tuple{Vector{Float64}, Vector{Float64}} where {Tl, Fl} Fits an Adaptive Lasso (AdaLasso) regression model to the provided data and returns coefficients and residuals. @@ -176,7 +176,7 @@ end # Arguments - `Estimation_X::Matrix{Tl}`: Matrix of predictors for estimation. - `estimation_y::Vector{Fl}`: Vector of response values for estimation. - - `components_indexes::Dict{String, Vector{Int64}}`: Dictionary containing indexes for different components. + - `components_indexes::Dict{String, Vector{Int}}`: Dictionary containing indexes for different components. - `estimation_input::Dict`: Dictionary containing the estimation input parameters. # Returns @@ -184,7 +184,7 @@ end """ function default_estimation_procedure(Estimation_X::Matrix{Tl}, estimation_y::Vector{Fl}, - components_indexes::Dict{String, Vector{Int64}}, estimation_input::Dict)::Tuple{Vector{Float64}, Vector{Float64}} where {Tl, Fl} + components_indexes::Dict{String, Vector{Int}}, estimation_input::Dict)::Tuple{Vector{Float64}, Vector{Float64}} where {Tl, Fl} @assert all([key in keys(estimation_input) for key in ["α", "information_criteria", "ϵ", "penalize_exogenous", "penalize_initial_states"]]) "All estimation input parameters must be set" α = estimation_input["α"]; information_criteria = estimation_input["information_criteria"]; diff --git a/src/information_criteria.jl b/src/information_criteria.jl index 8594a34..fb1e2a9 100644 --- a/src/information_criteria.jl +++ b/src/information_criteria.jl @@ -1,21 +1,20 @@ """ - get_information(T::Int64, K::Int64, ε::Vector{Float64}; - information_criteria::String = "bic", p::Int64 = 0)::Float64 + get_information(T::Int, K::Int, ε::Vector{Float64}; + information_criteria::String = "bic")::Float64 Calculates information criterion value based on the provided parameters and residuals. # Arguments - - `T::Int64`: Number of observations. - - `K::Int64`: Number of selected predictors. + - `T::Int`: Number of observations. + - `K::Int`: Number of selected predictors. - `ε::Vector{Float64}`: Vector of residuals. - `information_criteria::String`: Method for hyperparameter selection (default: "aic"). - - `p::Int64`: Number of total predictors (default: 0). # Returns - `Float64`: Information criterion value. """ -function get_information(T::Int64, K::Int64, ε::Vector{Float64}; information_criteria::String = "aic")::Float64 +function get_information(T::Int, K::Int, ε::Vector{Float64}; information_criteria::String = "aic")::Float64 if information_criteria == "bic" return T*log(var(ε)) + K*log(T) elseif information_criteria == "aic" diff --git a/src/models/default_model.jl b/src/models/default_model.jl index 09bd76e..9e4e747 100644 --- a/src/models/default_model.jl +++ b/src/models/default_model.jl @@ -1,61 +1,61 @@ """ - ξ_size(T::Int64)::Int64 + ξ_size(T::Int)::Int Calculates the size of ξ innovation matrix based on the input T. # Arguments - - `T::Int64`: Length of the original time series. + - `T::Int`: Length of the original time series. # Returns - - `Int64`: Size of ξ calculated from T. + - `Int`: Size of ξ calculated from T. """ -ξ_size(T::Int64)::Int64 = T - 2 +ξ_size(T::Int)::Int = T - 2 """ -ζ_size(T::Int64, ζ_ω_threshold::Int64)::Int64 +ζ_size(T::Int, ζ_ω_threshold::Int)::Int Calculates the size of ζ innovation matrix based on the input T. # Arguments - - `T::Int64`: Length of the original time series. - - `ζ_ω_threshold::Int64`: Stabilize parameter ζ. + - `T::Int`: Length of the original time series. + - `ζ_ω_threshold::Int`: Stabilize parameter ζ. # Returns - - `Int64`: Size of ζ calculated from T. + - `Int`: Size of ζ calculated from T. """ -ζ_size(T::Int64, ζ_ω_threshold::Int64)::Int64 = T-ζ_ω_threshold-2 +ζ_size(T::Int, ζ_ω_threshold::Int)::Int = T-ζ_ω_threshold-2 """ -ω_size(T::Int64, s::Int64)::Int64 +ω_size(T::Int, s::Int)::Int Calculates the size of ω innovation matrix based on the input T. # Arguments - - `T::Int64`: Length of the original time series. - - `s::Int64`: Seasonal period. + - `T::Int`: Length of the original time series. + - `s::Int`: Seasonal period. # Returns - - `Int64`: Size of ω calculated from T. + - `Int`: Size of ω calculated from T. """ -ω_size(T::Int64, s::Int64, ζ_ω_threshold::Int64)::Int64 = T - ζ_ω_threshold - s + 1 +ω_size(T::Int, s::Int, ζ_ω_threshold::Int)::Int = T - ζ_ω_threshold - s + 1 """ - create_ξ(T::Int64, steps_ahead::Int64)::Matrix + create_ξ(T::Int, steps_ahead::Int)::Matrix Creates a matrix of innovations ξ based on the input sizes, and the desired steps ahead (this is necessary for the forecast function) # Arguments - - `T::Int64`: Length of the original time series. - - `steps_ahead::Int64`: Number of steps ahead (for estimation purposes this should be set at 0). + - `T::Int`: Length of the original time series. + - `steps_ahead::Int`: Number of steps ahead (for estimation purposes this should be set at 0). # Returns - `Matrix`: Matrix of innovations ξ constructed based on the input sizes. """ -function create_ξ(T::Int64, steps_ahead::Int64)::Matrix +function create_ξ(T::Int, steps_ahead::Int)::Matrix ξ_matrix = Matrix{Float64}(undef, T+steps_ahead, T - 1) for t in 1:T+steps_ahead ξ_matrix[t, :] = t < T ? vcat(ones(t-1), zeros(T-t)) : ones(T-1) @@ -65,20 +65,20 @@ function create_ξ(T::Int64, steps_ahead::Int64)::Matrix end """ -create_ζ(T::Int64, steps_ahead::Int64, ζ_ω_threshold::Int64)::Matrix +create_ζ(T::Int, steps_ahead::Int, ζ_ω_threshold::Int)::Matrix Creates a matrix of innovations ζ based on the input sizes, and the desired steps ahead (this is necessary for the forecast function). # Arguments - - `T::Int64`: Length of the original time series. - - `steps_ahead::Int64`: Number of steps ahead (for estimation purposes this should be set at 0). - - `ζ_ω_threshold::Int64`: Stabilize parameter ζ. + - `T::Int`: Length of the original time series. + - `steps_ahead::Int`: Number of steps ahead (for estimation purposes this should be set at 0). + - `ζ_ω_threshold::Int`: Stabilize parameter ζ. # Returns - `Matrix`: Matrix of innovations ζ constructed based on the input sizes. """ -function create_ζ(T::Int64, steps_ahead::Int64, ζ_ω_threshold::Int64)::Matrix +function create_ζ(T::Int, steps_ahead::Int, ζ_ω_threshold::Int)::Matrix ζ_matrix = Matrix{Float64}(undef, T+steps_ahead, T - 2) for t in 1:T+steps_ahead ζ_matrix[t, :] = t < T ? vcat(collect(t-2:-1:1), zeros(T-2-length(collect(t-2:-1:1)))) : collect(t-2:-1:t-T+1) @@ -87,25 +87,25 @@ function create_ζ(T::Int64, steps_ahead::Int64, ζ_ω_threshold::Int64)::Matrix end """ -create_ω(T::Int64, s::Int64, steps_ahead::Int64)::Matrix +create_ω(T::Int, s::Int, steps_ahead::Int)::Matrix Creates a matrix of innovations ω based on the input sizes, and the desired steps ahead (this is necessary for the forecast function). # Arguments - - `T::Int64`: Length of the original time series. - - `freq_seasonal::Int64`: Seasonal period. - - `steps_ahead::Int64`: Number of steps ahead (for estimation purposes this should be set at 0). + - `T::Int`: Length of the original time series. + - `freq_seasonal::Int`: Seasonal period. + - `steps_ahead::Int`: Number of steps ahead (for estimation purposes this should be set at 0). # Returns - `Matrix`: Matrix of innovations ω constructed based on the input sizes. """ -function create_ω(T::Int64, freq_seasonal::Int64, steps_ahead::Int64, ζ_ω_threshold::Int64)::Matrix +function create_ω(T::Int, freq_seasonal::Int, steps_ahead::Int, ζ_ω_threshold::Int)::Matrix ω_matrix_size = ω_size(T, freq_seasonal, ζ_ω_threshold) + ζ_ω_threshold ω_matrix = zeros(T+steps_ahead, ω_matrix_size) for t in freq_seasonal+1:T+steps_ahead ωₜ_coefs = zeros(ω_matrix_size) - Mₜ = Int64(floor((t-1)/freq_seasonal)) + Mₜ = Int(floor((t-1)/freq_seasonal)) lag₁ = [t - j*freq_seasonal for j in 0:Mₜ-1] lag₂ = [t - j*freq_seasonal - 1 for j in 0:Mₜ-1] ωₜ_coefs[lag₁[lag₁.<=ω_matrix_size+(freq_seasonal - 1)] .- (freq_seasonal - 1)] .= 1 @@ -116,14 +116,14 @@ function create_ω(T::Int64, freq_seasonal::Int64, steps_ahead::Int64, ζ_ω_thr end """ - create_initial_states_Matrix(T::Int64, s::Int64, steps_ahead::Int64, level::Bool, trend::Bool, seasonal::Bool)::Matrix + create_initial_states_Matrix(T::Int, s::Int, steps_ahead::Int, level::Bool, trend::Bool, seasonal::Bool)::Matrix Creates an initial states matrix based on the input parameters. # Arguments - - `T::Int64`: Length of the original time series. - - `freq_seasonal::Int64`: Seasonal period. - - `steps_ahead::Int64`: Number of steps ahead. + - `T::Int`: Length of the original time series. + - `freq_seasonal::Int`: Seasonal period. + - `steps_ahead::Int`: Number of steps ahead. - `level::Bool`: Flag for considering level component. - `trend::Bool`: Flag for considering trend component. - `seasonal::Bool`: Flag for considering seasonal component. @@ -132,7 +132,7 @@ end - `Matrix`: Initial states matrix constructed based on the input parameters. """ -function create_initial_states_Matrix(T::Int64, freq_seasonal::Int64, steps_ahead::Int64, level::Bool, trend::Bool, seasonal::Bool)::Matrix +function create_initial_states_Matrix(T::Int, freq_seasonal::Int, steps_ahead::Int, level::Bool, trend::Bool, seasonal::Bool)::Matrix initial_states_matrix = zeros(T+steps_ahead, 0) level ? initial_states_matrix = hcat(initial_states_matrix, ones(T+steps_ahead, 1)) : nothing @@ -151,21 +151,21 @@ function create_initial_states_Matrix(T::Int64, freq_seasonal::Int64, steps_ahea end """ -create_X(model_input::Dict, Exogenous_X::Matrix{Fl}, steps_ahead::Int64=0, Exogenous_Forecast::Matrix{Fl}=zeros(steps_ahead, size(Exogenous_X, 2))) where Fl +create_X(model_input::Dict, Exogenous_X::Matrix{Fl}, steps_ahead::Int=0, Exogenous_Forecast::Matrix{Fl}=zeros(steps_ahead, size(Exogenous_X, 2))) where Fl Creates the StateSpaceLearning matrix X based on the model type and input parameters. # Arguments - `model_type::String`: Type of model. - `Exogenous_X::Matrix{Fl}`: Exogenous variables matrix. - - `steps_ahead::Int64`: Number of steps ahead (default: 0). + - `steps_ahead::Int`: Number of steps ahead (default: 0). - `Exogenous_Forecast::Matrix{Fl}`: Exogenous variables forecast matrix (default: zeros). # Returns - `Matrix`: StateSpaceLearning matrix X constructed based on the input parameters. """ function create_X(model_input::Dict, Exogenous_X::Matrix{Fl}, - steps_ahead::Int64=0, Exogenous_Forecast::Matrix{Fl}=zeros(steps_ahead, size(Exogenous_X, 2))) where Fl + steps_ahead::Int=0, Exogenous_Forecast::Matrix{Fl}=zeros(steps_ahead, size(Exogenous_X, 2))) where Fl outlier = model_input["outlier"]; ζ_ω_threshold = model_input["ζ_ω_threshold"]; T = size(Exogenous_X, 1) @@ -203,8 +203,8 @@ function get_components_indexes(Exogenous_X::Matrix{Fl}, model_input::Dict)::Dic initial_states_indexes = [1] FINAL_INDEX += length(μ1_indexes) else - μ1_indexes = Int64[] - initial_states_indexes = Int64[] + μ1_indexes = Int[] + initial_states_indexes = Int[] end if model_input["trend"] @@ -212,7 +212,7 @@ function get_components_indexes(Exogenous_X::Matrix{Fl}, model_input::Dict)::Dic initial_states_indexes = vcat(initial_states_indexes, ν1_indexes) FINAL_INDEX += length(ν1_indexes) else - ν1_indexes = Int64[] + ν1_indexes = Int[] end if model_input["seasonal"] @@ -220,35 +220,35 @@ function get_components_indexes(Exogenous_X::Matrix{Fl}, model_input::Dict)::Dic initial_states_indexes = vcat(initial_states_indexes, γ1_indexes) FINAL_INDEX += length(γ1_indexes) else - γ1_indexes = Int64[] + γ1_indexes = Int[] end if model_input["stochastic_level"] ξ_indexes = collect(FINAL_INDEX+1:FINAL_INDEX+ξ_size(T)) FINAL_INDEX += length(ξ_indexes) else - ξ_indexes = Int64[] + ξ_indexes = Int[] end if model_input["stochastic_trend"] ζ_indexes = collect(FINAL_INDEX+1:FINAL_INDEX+ζ_size(T, ζ_ω_threshold)) FINAL_INDEX += length(ζ_indexes) else - ζ_indexes = Int64[] + ζ_indexes = Int[] end if model_input["stochastic_seasonal"] ω_indexes = collect(FINAL_INDEX+1:FINAL_INDEX+ω_size(T, model_input["freq_seasonal"], ζ_ω_threshold)) FINAL_INDEX += length(ω_indexes) else - ω_indexes = Int64[] + ω_indexes = Int[] end if outlier o_indexes = collect(FINAL_INDEX+1:FINAL_INDEX+o_size(T)) FINAL_INDEX += length(o_indexes) else - o_indexes = Int64[] + o_indexes = Int[] end exogenous_indexes = collect(FINAL_INDEX + 1:FINAL_INDEX + size(Exogenous_X, 2)) @@ -259,20 +259,20 @@ function get_components_indexes(Exogenous_X::Matrix{Fl}, model_input::Dict)::Dic end """ - get_variances(ε::Vector{Fl}, coefs::Vector{Fl}, components_indexes::Dict{String, Vector{Int64}})::Dict where Fl + get_variances(ε::Vector{Fl}, coefs::Vector{Fl}, components_indexes::Dict{String, Vector{Int}})::Dict where Fl Calculates variances for each innovation component and for the residuals. # Arguments - `ε::Vector{Fl}`: Vector of residuals. - `coefs::Vector{Fl}`: Vector of coefficients. - - `components_indexes::Dict{String, Vector{Int64}}`: Dictionary containing indexes for different components. + - `components_indexes::Dict{String, Vector{Int}}`: Dictionary containing indexes for different components. # Returns - `Dict`: Dictionary containing variances for each innovation component. """ -function get_variances(ε::Vector{Fl}, coefs::Vector{Fl}, components_indexes::Dict{String, Vector{Int64}})::Dict where Fl +function get_variances(ε::Vector{Fl}, coefs::Vector{Fl}, components_indexes::Dict{String, Vector{Int}})::Dict where Fl variances = Dict() for component in ["ξ", "ζ", "ω"] diff --git a/src/structs.jl b/src/structs.jl index fe0929c..5ed9540 100644 --- a/src/structs.jl +++ b/src/structs.jl @@ -12,10 +12,10 @@ - `fitted::Vector`: Fitted values from the model. - `components::Dict`: Dictionary containing different components. - `residuals_variances::Dict`: Dictionary storing variances of residuals for different components. - - `T::Int64`: Integer representing a parameter 'T'. + - `T::Int`: Integer representing a parameter 'T'. - `outlier::Bool`: Boolean indicating the presence of outlier component. - - `valid_indexes::Vector{Int64}`: Vector containing valid indexes (non NaN) of the time series. - - `ζ_ω_threshold::Int64`: ζ_ω_threshold parameter. + - `valid_indexes::Vector{Int}`: Vector containing valid indexes (non NaN) of the time series. + - `ζ_ω_threshold::Int`: ζ_ω_threshold parameter. - `y::Vector{Fl}`: Vector of data. """ @@ -28,5 +28,5 @@ mutable struct Output fitted::Vector components::Dict residuals_variances::Dict - valid_indexes::Vector{Int64} + valid_indexes::Vector{Int} end \ No newline at end of file diff --git a/src/utils.jl b/src/utils.jl index e5cc991..20e970c 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -1,12 +1,12 @@ """ - build_components(X::Matrix{Tl}, coefs::Vector{Float64}, components_indexes::Dict{String, Vector{Int64}}) -> Dict where Tl + build_components(X::Matrix{Tl}, coefs::Vector{Float64}, components_indexes::Dict{String, Vector{Int}}) -> Dict where Tl Constructs components dict containing values, indexes and coefficients for each component. # Arguments - X::Matrix{Tl}: Input matrix. - coefs::Vector{Float64}: Coefficients. - - components_indexes::Dict{String, Vector{Int64}}: Dictionary mapping component names to their indexes. + - components_indexes::Dict{String, Vector{Int}}: Dictionary mapping component names to their indexes. # Returns - components::Dict: Dictionary containing components, each represented by a dictionary with keys: @@ -15,7 +15,7 @@ - "Values": Values computed from `X` and component coefficients. """ -function build_components(X::Matrix{Tl}, coefs::Vector{Float64}, components_indexes::Dict{String, Vector{Int64}})::Dict where Tl +function build_components(X::Matrix{Tl}, coefs::Vector{Float64}, components_indexes::Dict{String, Vector{Int}})::Dict where Tl components = Dict() for key in keys(components_indexes) components[key] = Dict() @@ -30,7 +30,7 @@ function build_components(X::Matrix{Tl}, coefs::Vector{Float64}, components_inde end """ -get_fit_and_residuals(estimation_ε::Vector{Float64}, coefs::Vector{Float64}, X::Matrix{Tl}, valid_indexes::Vector{Int64}, T::Int64) -> Tuple{Vector{Float64}, Vector{Float64}} where Tl +get_fit_and_residuals(estimation_ε::Vector{Float64}, coefs::Vector{Float64}, X::Matrix{Tl}, valid_indexes::Vector{Int}, T::Int) -> Tuple{Vector{Float64}, Vector{Float64}} where Tl Builds complete residuals and fit in sample. Residuals will contain nan values for non valid indexes. Fit in Sample will be a vector of fitted values computed from input data and coefficients (non valid indexes will also be calculated via interpolation). @@ -38,8 +38,8 @@ get_fit_and_residuals(estimation_ε::Vector{Float64}, coefs::Vector{Float64}, X: - `estimation_ε::Vector{Float64}`: Vector of estimation errors. - `coefs::Vector{Float64}`: Coefficients. - `X::Matrix{Tl}`: Input matrix. - - `valid_indexes::Vector{Int64}`: Valid indexes. - - `T::Int64`: Length of the original time series. + - `valid_indexes::Vector{Int}`: Valid indexes. + - `T::Int`: Length of the original time series. # Returns - Tuple containing: @@ -47,40 +47,40 @@ get_fit_and_residuals(estimation_ε::Vector{Float64}, coefs::Vector{Float64}, X: - `fitted::Vector{Float64}`: Vector of fitted values computed from input data and coefficients. """ -function get_fit_and_residuals(estimation_ε::Vector{Float64}, coefs::Vector{Float64}, X::Matrix{Tl}, valid_indexes::Vector{Int64}, T::Int64)::Tuple{Vector{Float64}, Vector{Float64}} where Tl +function get_fit_and_residuals(estimation_ε::Vector{Float64}, coefs::Vector{Float64}, X::Matrix{Tl}, valid_indexes::Vector{Int}, T::Int)::Tuple{Vector{Float64}, Vector{Float64}} where Tl ε = fill(NaN, T); ε[valid_indexes] = estimation_ε fitted = X*coefs return ε, fitted end """ -o_size(T::Int64)::Int64 +o_size(T::Int)::Int Calculates the size of outlier matrix based on the input T. # Arguments - - `T::Int64`: Length of the original time series. + - `T::Int`: Length of the original time series. # Returns - - `Int64`: Size of o calculated from T. + - `Int`: Size of o calculated from T. """ -o_size(T::Int64)::Int64 = T +o_size(T::Int)::Int = T """ -create_o_matrix(T::Int64, steps_ahead::Int64)::Matrix +create_o_matrix(T::Int, steps_ahead::Int)::Matrix Creates a matrix of outliers based on the input sizes, and the desired steps ahead (this is necessary for the forecast function). # Arguments - - `T::Int64`: Length of the original time series. - - `steps_ahead::Int64`: Number of steps ahead (for estimation purposes this should be set at 0). + - `T::Int`: Length of the original time series. + - `steps_ahead::Int`: Number of steps ahead (for estimation purposes this should be set at 0). # Returns - `Matrix`: Matrix of outliers constructed based on the input sizes. """ -function create_o_matrix(T::Int64, steps_ahead::Int64)::Matrix +function create_o_matrix(T::Int, steps_ahead::Int)::Matrix return vcat(Matrix(1.0 * I, T, T), zeros(steps_ahead, T)) end @@ -97,9 +97,9 @@ handle_missing_values(X::Matrix{Tl}, y::Vector{Fl}) -> Tuple{Vector{Fl}, Matrix{ - Tuple containing: - `y::Vector{Fl}`: Time series without missing values. - `X::Matrix{Tl}`: Input matrix without missing values. - - `valid_indexes::Vector{Int64}`: Vector containing valid indexes of the time series. + - `valid_indexes::Vector{Int}`: Vector containing valid indexes of the time series. """ -function handle_missing_values(X::Matrix{Tl}, y::Vector{Fl})::Tuple{Vector{Fl}, Matrix{Tl}, Vector{Int64}} where {Tl, Fl} +function handle_missing_values(X::Matrix{Tl}, y::Vector{Fl})::Tuple{Vector{Fl}, Matrix{Tl}, Vector{Int}} where {Tl, Fl} invalid_indexes = unique(vcat([i[1] for i in findall(i -> any(isnan, i), X)], findall(i -> isnan(i), y))) valid_indexes = setdiff(1:length(y), invalid_indexes) @@ -134,7 +134,7 @@ fill_innovation_coefs(component::String, output::Output)::Vector{Float64} # Returns - `Vector{Float64}`: Vector containing innovation coefficients for the given component. """ -function fill_innovation_coefs(T::Int64, component::String, output::Output)::Vector{Float64} +function fill_innovation_coefs(T::Int, component::String, output::Output)::Vector{Float64} inov_comp = zeros(T) for (i, idx) in enumerate(output.components[component]["Indexes"]) inov_comp[findfirst(i -> i != 0, output.X[:, idx])] = output.components[component]["Coefs"][i]