Skip to content

Commit 81610b1

Browse files
Add beta location scale and dont cheat at tests (#89)
* add beta location scale and dont cheat at tests * add test for params_sdm
1 parent f8d7c90 commit 81610b1

20 files changed

+188
-35
lines changed

src/MLE.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,15 +117,15 @@ function fit(gas::Model{D, T}, y::Vector{T};
117117
func = TwiceDifferentiable(psi_tilde -> log_lik(psi_tilde, y, gas_fit, initial_params, unknowns, n), opt_method.initial_points[i])
118118
opt_result = optimize(func, opt_method, verbose, i)
119119
update_aux_estimation!(aux_est, func, opt_result)
120-
println("initial_point $i of $n_initial_points - $(-opt_result.minimum)")
120+
println("initial point $i of $n_initial_points - Log-likelihood: $(-opt_result.minimum)")
121121
catch err
122122
println(err)
123-
println("initial_point $i diverged")
123+
println("initial point $i diverged")
124124
end
125125
end
126126

127127
if isempty(aux_est.loglikelihood)
128-
println("No initial_point converged.")
128+
println("No initial point converged.")
129129
return
130130
end
131131

@@ -146,7 +146,7 @@ end
146146

147147
function fit!(gas::Model{D, T}, y::Vector{T};
148148
initial_params::Matrix{T} = DEFAULT_INITIAL_PARAM,
149-
opt_method::AbstractOptimizationMethod = LBFGS(gas, DEFAULT_NUM_SEEDS),
149+
opt_method::AbstractOptimizationMethod = NelderMead(gas, DEFAULT_NUM_SEEDS),
150150
verbose::Int = DEFAULT_VERBOSE) where {D, T}
151151

152152
unknowns = find_unknowns(gas)

src/ScoreDrivenModels.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ include("opt_methods/NelderMead.jl")
3232
include("distributions/non_native_dists.jl")
3333
include("distributions/common_interface.jl")
3434
include("distributions/beta.jl")
35+
include("distributions/betalocationscale.jl")
3536
include("distributions/chi.jl")
3637
include("distributions/chisq.jl")
3738
include("distributions/exponential.jl")

src/distributions/beta.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ function update_dist(::Type{Beta}, param::Matrix{T}, t::Int) where T
5959
return Beta(param[t, 1], param[t, 2])
6060
end
6161

62+
function params_sdm(d::Beta)
63+
return Distributions.params(d)
64+
end
65+
6266
function num_params(::Type{Beta})
6367
return 2
6468
end
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
"""
2+
BetaLocationScale
3+
4+
* Parametrization \\mu, \\sigma, \\alpha, \\beta
5+
6+
* Score
7+
8+
* Fisher Information
9+
10+
* `time_varying_params` map.
11+
12+
* Default link
13+
"""
14+
BetaLocationScale
15+
16+
17+
# Remember for all the code that param[t, 2] is c - a
18+
# and param[t, 1] is a so to get c one must make
19+
# param[t, 2] + param[t, 1]
20+
function score!(score_til::Matrix{T}, y::T, ::Type{BetaLocationScale}, param::Matrix{T}, t::Int) where T
21+
score_til[t, 1] = -(param[t, 3] - 1)/(y - param[t, 1]) + (param[t, 4] + param[t, 3] - 1)/(param[t, 2] - param[t, 1])
22+
score_til[t, 2] = (param[t, 4] - 1)/(param[t, 2] - y) - (param[t, 4] + param[t, 3] - 1)/(param[t, 2] - param[t, 1])
23+
score_til[t, 3] = log(y - param[t, 1]) - log(param[t, 2] - param[t, 1]) +
24+
digamma(param[t, 3] + param[t, 4]) - digamma(param[t, 3])
25+
score_til[t, 4] = log(param[t, 2] - y) - log(param[t, 2] - param[t, 1]) +
26+
digamma(param[t, 3] + param[t, 4]) - digamma(param[t, 4])
27+
return
28+
end
29+
30+
function fisher_information!(aux::AuxiliaryLinAlg{T}, ::Type{BetaLocationScale}, param::Matrix{T}, t::Int) where T
31+
return error("Fisher information not implemented for BetaLocationScale distribution.")
32+
end
33+
34+
function log_likelihood(::Type{BetaLocationScale}, y::Vector{T}, param::Matrix{T}, n::Int) where T
35+
loglik = 0.0
36+
for t in 1:n
37+
loglik += (param[t, 3] - 1)*log(y[t] - param[t, 1]) + (param[t, 4] - 1) * log(param[t, 2] - y[t]) -
38+
(param[t, 3] + param[t, 4] - 1) * log(param[t, 2] - param[t, 1]) - logbeta(param[t, 3], param[t, 4])
39+
end
40+
return -loglik
41+
end
42+
43+
# Links
44+
function link!(param_tilde::Matrix{T}, ::Type{BetaLocationScale}, param::Matrix{T}, t::Int) where T
45+
param_tilde[t, 1] = link(LogLink, param[t, 1], zero(T))
46+
param_tilde[t, 2] = link(LogLink, param[t, 2], zero(T))
47+
return
48+
end
49+
function unlink!(param::Matrix{T}, ::Type{BetaLocationScale}, param_tilde::Matrix{T}, t::Int) where T
50+
param[t, 1] = unlink(LogLink, param_tilde[t, 1], zero(T))
51+
param[t, 2] = unlink(LogLink, param_tilde[t, 2], zero(T))
52+
return
53+
end
54+
function jacobian_link!(aux::AuxiliaryLinAlg{T}, ::Type{BetaLocationScale}, param::Matrix{T}, t::Int) where T
55+
aux.jac[1] = jacobian_link(LogLink, param[t, 1], zero(T))
56+
aux.jac[2] = jacobian_link(LogLink, param[t, 2], zero(T))
57+
return
58+
end
59+
60+
# utils
61+
function update_dist(::Type{BetaLocationScale}, param::Matrix{T}, t::Int) where T
62+
small_threshold!(param[:, 3:4], SMALL_NUM, t)
63+
beta = Beta(param[t, 3], param[t, 4])
64+
return LocationScale(param[t, 1], param[t, 2] - param[t, 1], beta)
65+
end
66+
67+
function params_sdm(d::BetaLocationScale)
68+
return (d.μ, d.σ + d.μ, Distributions.params(d.ρ)...)
69+
end
70+
71+
function num_params(::Type{BetaLocationScale})
72+
return 4
73+
end

src/distributions/chi.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ function update_dist(::Type{Chi}, param::Matrix{T}, t::Int) where T
5252
return Chi(param[t, 1])
5353
end
5454

55+
function params_sdm(d::Chi)
56+
return Distributions.params(d)
57+
end
58+
5559
function num_params(::Type{Chi})
5660
return 1
5761
end

src/distributions/chisq.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ function update_dist(::Type{Chisq}, param::Matrix{T}, t::Int) where T
5252
return Chisq(param[t, 1])
5353
end
5454

55+
function params_sdm(d::Chisq)
56+
return Distributions.params(d)
57+
end
58+
5559
function num_params(::Type{Chisq})
5660
return 1
5761
end

src/distributions/common_interface.jl

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Currently supported distributions
22
const DISTS = [
33
Beta,
4+
BetaLocationScale,
45
Chi,
56
Chisq,
67
Exponential,
@@ -15,6 +16,7 @@ const DISTS = [
1516
]
1617

1718
export Beta,
19+
BetaLocationScale,
1820
Chi,
1921
Chisq,
2022
Exponential,
@@ -27,35 +29,59 @@ export Beta,
2729
TDistLocationScale,
2830
Weibull
2931

30-
# Query params for generic distribution
31-
params_sdm(d::Distribution) = Distributions.params(d)
32-
# Query params for all LocationScale distributions
33-
params_sdm(d::LocationScale) = (d.μ, d.σ, Distributions.params(d.ρ)...)
34-
3532
function score!(score_til::Matrix{T}, y::T, D::Type{<:Distribution}, param::Matrix{T}, t::Int) where T
3633
return error("score! not implemented for $D distribution")
3734
end
35+
3836
function score!(score_til::Matrix{T}, y::Int, D::Type{<:Distribution}, param::Matrix{T}, t::Int) where T
3937
return error("score! not implemented for $D distribution")
4038
end
39+
4140
function fisher_information!(aux::AuxiliaryLinAlg{T}, D::Type{<:Distribution}, param::Matrix{T}, t::Int) where T
4241
return error("fisher_information! not implemented for $D distribution")
4342
end
43+
4444
function log_likelihood(D::Type{<:Distribution}, y::Vector{T}, param::Matrix{T}, n::Int) where T
4545
return error("log_likelihood not implemented for $D distribution")
4646
end
47+
4748
function link!(param_tilde::Matrix{T}, D::Type{<:Distribution}, param::Matrix{T}, t::Int) where T
4849
return error("link! not implemented for $D distribution")
4950
end
51+
5052
function unlink!(param::Matrix{T}, D::Type{<:Distribution}, param_tilde::Matrix{T}, t::Int) where T
5153
return error("unlink! not implemented for $D distribution")
5254
end
55+
5356
function jacobian_link!(aux::AuxiliaryLinAlg{T}, D::Type{<:Distribution}, param::Matrix{T}, t::Int) where T
5457
return error("jacobian_link! not implemented for $D distribution")
5558
end
59+
60+
"""
61+
update_dist(D::Type{<:Distribution}, param::Matrix{T}, t::Int) where T
62+
63+
Create a new distribution from Distributions.jl based on the parametrization used in
64+
ScoreDrivenModels.jl.
65+
"""
5666
function update_dist(D::Type{<:Distribution}, param::Matrix{T}, t::Int) where T
5767
return error("update_dist not implemented for $D distribution")
68+
end
69+
70+
"""
71+
params_sdm(d::Distribution)
72+
73+
Recover the parametrization used in ScoreDrivenModels.jl based on a Distribution from
74+
Distributions.jl.
75+
"""
76+
function params_sdm(d::Distribution)
77+
return error("params_sdm not implemented for $d distribution")
5878
end
79+
80+
"""
81+
num_params(D::Type{<:Distribution})
82+
83+
Number of parameters of a given distribution.
84+
"""
5985
function num_params(D::Type{<:Distribution})
6086
return error("num_params not implemented for $D distribution")
6187
end

src/distributions/exponential.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ function update_dist(::Type{Exponential}, param::Matrix{T}, t::Int) where T
5252
return Exponential(1/param[t, 1])
5353
end
5454

55+
function params_sdm(d::Exponential)
56+
pars = Distributions.params(d)
57+
return 1/pars[1]
58+
end
59+
5560
function num_params(::Type{Exponential})
5661
return 1
5762
end

src/distributions/gamma.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ function update_dist(::Type{Gamma}, param::Matrix{T}, t::Int) where T
5959
return Gamma(param[t, 1], param[t, 2])
6060
end
6161

62+
function params_sdm(d::Gamma)
63+
return Distributions.params(d)
64+
end
65+
6266
function num_params(::Type{Gamma})
6367
return 2
6468
end

src/distributions/logitnormal.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ function update_dist(::Type{LogitNormal}, param::Matrix{T}, t::Int) where T
6161
return LogitNormal(param[t, 1], sqrt(param[t, 2]))
6262
end
6363

64+
function params_sdm(d::LogitNormal)
65+
pars = Distributions.params(d)
66+
return (pars[1], pars[2]^2)
67+
end
68+
6469
function num_params(::Type{LogitNormal})
6570
return 2
6671
end

0 commit comments

Comments
 (0)