Skip to content

Commit ed12e23

Browse files
return some estimation results (#44)
1 parent c9f2e4f commit ed12e23

File tree

2 files changed

+40
-16
lines changed

2 files changed

+40
-16
lines changed

src/MLE.jl

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,61 @@
11
export estimate!
22

33
const DEFAULT_INITIAL_PARAM = NaN.*ones(1, 1)
4+
const DEFAULT_NUM_SEEDS = 3
5+
6+
struct EstimationResults{T <: AbstractFloat}
7+
aic::T
8+
bic::T
9+
llk::T
10+
minimizer::Vector{T}
11+
numerical_hessian::Matrix{T}
12+
end
413

514
function log_lik(psitilde::Vector{T}, y::Vector{T}, sdm::SDM{D, T},
615
initial_params::Vector{Vector{T}}, unknowns::Unknowns_SDM, n::Int) where {D, T}
716
return error("log_lik not defined for a model of type ", typeof(sdm))
817
end
918

19+
function AIC(n_unknowns::Int, log_lik::T) where T
20+
return T(2 * n_unknowns - 2 * log_lik)
21+
end
22+
23+
function BIC(n::Int, n_unknowns::Int, log_lik::T) where T
24+
return T(log(n) * n_unknowns - 2 * log_lik)
25+
end
26+
1027
function estimate!(sdm::SDM{D, T}, y::Vector{T};
1128
initial_params::Matrix{T} = DEFAULT_INITIAL_PARAM,
12-
opt_method::AbstractOptimizationMethod = LBFGS(sdm, 3),
29+
opt_method::AbstractOptimizationMethod = LBFGS(sdm, DEFAULT_NUM_SEEDS),
1330
verbose::Int = 0) where {D, T}
1431

1532
# Number of seed and number of params to estimate
1633
nseeds = length(opt_method.seeds)
1734
n = length(y)
1835

1936
unknowns = find_unknowns(sdm)
20-
len_unknowns = length(unknowns)
37+
n_unknowns = length(unknowns)
2138

2239
# Check if the model has no unknowns
23-
check_model_estimated(len_unknowns) && return sdm
40+
check_model_estimated(n_unknowns) && return sdm
2441

2542
# optimize for each seed
26-
psi = Vector{Vector{Float64}}(undef, 0)
27-
loglikelihood = Vector{Float64}(undef, 0)
43+
psi = Vector{Vector{T}}(undef, 0)
44+
numerical_hessian = Vector{Matrix{T}}(undef, 0)
45+
loglikelihood = Vector{T}(undef, 0)
2846
optseeds = Vector{Optim.OptimizationResults}(undef, 0)
2947

3048
for i = 1:nseeds
3149
try
32-
optseed = optimize(psi_tilde -> log_lik(psi_tilde, y, sdm, initial_params, unknowns, n),
33-
opt_method.seeds[i],
34-
opt_method.method, Optim.Options(f_tol = opt_method.f_tol,
35-
g_tol = opt_method.g_tol,
36-
iterations = opt_method.iterations,
37-
show_trace = (verbose == 2 ? true : false) ))
50+
func = TwiceDifferentiable(psi_tilde -> log_lik(psi_tilde, y, sdm, initial_params, unknowns, n), opt_method.seeds[i])
51+
optseed = optimize(func, opt_method.seeds[i],
52+
opt_method.method, Optim.Options(f_tol = opt_method.f_tol,
53+
g_tol = opt_method.g_tol,
54+
iterations = opt_method.iterations,
55+
show_trace = (verbose == 2 ? true : false) ))
3856
push!(loglikelihood, -optseed.minimum)
3957
push!(psi, optseed.minimizer)
58+
push!(numerical_hessian, Optim.hessian!(func, optseed.minimizer))
4059
push!(optseeds, optseed)
4160
println("seed $i of $nseeds - $(-optseed.minimum)")
4261
catch err
@@ -50,15 +69,20 @@ function estimate!(sdm::SDM{D, T}, y::Vector{T};
5069
return
5170
end
5271

53-
best_llk = argmax(loglikelihood)
54-
bestpsi = psi[best_llk]
72+
best_llk, best_seed = findmax(loglikelihood)
73+
num_hessian = numerical_hessian[best_seed]
74+
best_psi = psi[best_seed]
75+
aic = AIC(n_unknowns, best_llk)
76+
bic = BIC(n, n_unknowns, best_llk)
77+
5578
if verbose >= 1
5679
println("\nBest seed optimization result:")
57-
println(optseeds[best_llk])
80+
println(optseeds[best_seed])
5881
end
5982

6083
# return the estimated
61-
fill_psitilde!(sdm, bestpsi, unknowns)
84+
fill_psitilde!(sdm, best_psi, unknowns)
6285

6386
println("Finished!")
87+
return EstimationResults{T}(aic, bic, best_llk, best_psi, num_hessian)
6488
end

src/gas/gas.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ function log_lik(psitilde::Vector{T}, y::Vector{T}, gas::GAS{D, T},
133133
if isnan(initial_params[1]) # Means default stationary initialization
134134
params = score_driven_recursion(gas, y)
135135
else
136-
params = score_driven_recursion(gas, y, initial_params)
136+
params = score_driven_recursion(gas, y; initial_params = initial_params)
137137
end
138138

139139
return log_likelihood(D, y, params, n)

0 commit comments

Comments
 (0)