1
1
export estimate!
2
2
3
3
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
4
13
5
14
function log_lik (psitilde:: Vector{T} , y:: Vector{T} , sdm:: SDM{D, T} ,
6
15
initial_params:: Vector{Vector{T}} , unknowns:: Unknowns_SDM , n:: Int ) where {D, T}
7
16
return error (" log_lik not defined for a model of type " , typeof (sdm))
8
17
end
9
18
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
+
10
27
function estimate! (sdm:: SDM{D, T} , y:: Vector{T} ;
11
28
initial_params:: Matrix{T} = DEFAULT_INITIAL_PARAM,
12
- opt_method:: AbstractOptimizationMethod = LBFGS (sdm, 3 ),
29
+ opt_method:: AbstractOptimizationMethod = LBFGS (sdm, DEFAULT_NUM_SEEDS ),
13
30
verbose:: Int = 0 ) where {D, T}
14
31
15
32
# Number of seed and number of params to estimate
16
33
nseeds = length (opt_method. seeds)
17
34
n = length (y)
18
35
19
36
unknowns = find_unknowns (sdm)
20
- len_unknowns = length (unknowns)
37
+ n_unknowns = length (unknowns)
21
38
22
39
# Check if the model has no unknowns
23
- check_model_estimated (len_unknowns ) && return sdm
40
+ check_model_estimated (n_unknowns ) && return sdm
24
41
25
42
# 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 )
28
46
optseeds = Vector {Optim.OptimizationResults} (undef, 0 )
29
47
30
48
for i = 1 : nseeds
31
49
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 ) ))
38
56
push! (loglikelihood, - optseed. minimum)
39
57
push! (psi, optseed. minimizer)
58
+ push! (numerical_hessian, Optim. hessian! (func, optseed. minimizer))
40
59
push! (optseeds, optseed)
41
60
println (" seed $i of $nseeds - $(- optseed. minimum) " )
42
61
catch err
@@ -50,15 +69,20 @@ function estimate!(sdm::SDM{D, T}, y::Vector{T};
50
69
return
51
70
end
52
71
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
+
55
78
if verbose >= 1
56
79
println (" \n Best seed optimization result:" )
57
- println (optseeds[best_llk ])
80
+ println (optseeds[best_seed ])
58
81
end
59
82
60
83
# return the estimated
61
- fill_psitilde! (sdm, bestpsi , unknowns)
84
+ fill_psitilde! (sdm, best_psi , unknowns)
62
85
63
86
println (" Finished!" )
87
+ return EstimationResults {T} (aic, bic, best_llk, best_psi, num_hessian)
64
88
end
0 commit comments