Skip to content

Commit 0f783b8

Browse files
authored
Merge pull request #39 from insysbio/single_par
fix single parameter issue
2 parents 6b0663a + ce5d4a5 commit 0f783b8

File tree

7 files changed

+54
-19
lines changed

7 files changed

+54
-19
lines changed

src/odeprob_utils.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ function solver_init(sciml_prob::SciMLBase.AbstractODEProblem,
2525
function affect!(integrator)
2626
set_x_fixed!(solver_state_opt.reinit_cache.p, integrator.u[idx])
2727
solver_state_opt.reinit_cache.u0 = integrator.u[1:end-1][1:end .!= idx]
28-
sol = solve!(solver_state_opt)
28+
sol = solve_optcache(solver_state_opt)
2929
for i in 1:length(integrator.u)-1
3030
i == idx && continue
3131
integrator.u[i] = sol[i - (i>idx)]

src/optprob_utils.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ function build_optprob_reduced(optprob::OptimizationProblem, optpars)
5959
else
6060
ub_reduced = zeros(eltype(ub_full), lenreduced)
6161
end
62-
62+
6363
u0_full = optprob.u0
6464
u0_reduced = zeros(eltype(u0_full), lenreduced)
6565
remake(optprob, f=optf_reduced, u0=u0_reduced, p=FixedParamCache(optprob.p, 1, u0_full[1], 1.0), lb=lb_reduced, ub=ub_reduced)

src/problem_interface.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,6 @@ function validate_profile_bound(bound)
111111
end
112112

113113
function validate_optpars(npars::Int, u)
114-
npars < 2 && throw(DimensionMismatch("`optpars` length must be ≥ 2."))
115114
!(u isa AbstractVector && npars == length(u)) &&
116115
throw(ArgumentError("OptimizationProblem initial values must be of the same type and size as `optpars`."))
117116
return nothing

src/profiler_state.jl

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -155,9 +155,14 @@ end
155155

156156
function profiler_step!(profiler::ProfilerState, method::OptimizationProfiler)
157157
stepper = get_stepper(method)
158+
optcache = get_solver_state(profiler)
159+
idx = get_idx(profiler)
158160

159161
pars_guess = compute_next_pars!(profiler, stepper)
160-
sol = solve_optcache(profiler)
162+
fill_x_reduced!(optcache.reinit_cache.u0, pars_guess, idx)
163+
set_x_fixed!(optcache.reinit_cache.p, pars_guess[idx])
164+
165+
sol = solve_optcache(optcache)
161166

162167
if SciMLBase.successful_retcode(sol.retcode)
163168
idx = get_idx(profiler)
@@ -173,15 +178,23 @@ function profiler_step!(profiler::ProfilerState, method::OptimizationProfiler)
173178

174179
end
175180

176-
function solve_optcache(profiler::ProfilerState)
177-
optcache = get_solver_state(profiler)
178-
pars_guess = get_parscache(profiler)
179-
idx = get_idx(profiler)
181+
function solve_optcache(optcache::OptimizationCache)
182+
if isempty(optcache.reinit_cache.u0)
183+
return solve_empty_optcache(optcache)
184+
else
185+
return solve!(optcache)
186+
end
187+
end
180188

181-
fill_x_reduced!(optcache.reinit_cache.u0, pars_guess, idx)
182-
set_x_fixed!(optcache.reinit_cache.p, pars_guess[idx])
189+
function solve_empty_optcache(optcache::OptimizationCache)
190+
u = optcache.reinit_cache.u0
191+
p = optcache.reinit_cache.p
192+
193+
t = @elapsed obj = optcache.f(u, p)
194+
stats = SciMLBase.OptimizationStats(; iterations = 1, time = t, fevals = 1)
183195

184-
return solve!(optcache)
196+
return SciMLBase.build_solution(optcache, optcache.opt, u, obj;
197+
retcode = ReturnCode.Success, stats)
185198
end
186199

187200

@@ -200,7 +213,7 @@ function profiler_step!(profiler::ProfilerState, method::IntegrationProfiler)
200213
profiler.numiter += 1
201214
else
202215
@warn "Solver returned $(integrator.sol.retcode) retcode at profile point x = $(get_curx(profiler)). Profiling is interrupted."
203-
profiler.solver_retcode = sol.retcode
216+
profiler.solver_retcode = integrator.sol.retcode
204217
end
205218

206219
end

test/problems/analytic_funcs.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
funcs_dict = Dict(
33

4-
#=
4+
55
:f_1p => Dict(
66
:func => (x,p) -> 5.0 + (x[1]-3.0)^2,
77
:optim => [3.],
@@ -10,7 +10,7 @@ funcs_dict = Dict(
1010
:profile_range => [(-20.,20.)],
1111
:retcode => [(:Identifiable,:Identifiable)]
1212
),
13-
=#
13+
1414
:f_1p_ex => Dict(
1515
:func => (x,p) -> 5.0 + (x[1]-1e-8)^2 + 0.0*x[2],
1616
:optim => [1e-8, 2.],

test/test_prob_interface.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ using LikelihoodProfiler, Test
33
# ParameterProfile tests
44
optprob1 = OptimizationProblem((x,p)->x[1]^2+x[2]^2, [1., 2.0])
55

6-
@test_throws DimensionMismatch PLProblem(optprob1, [0.])
76
@test_throws ArgumentError PLProblem(optprob1, [0.,0])
87
@test_throws ArgumentError PLProblem(optprob1, [0.,0, 0.])
98
@test_throws ArgumentError PLProblem(optprob1, [0.,0], (-Inf,4))

test/test_profile.jl

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1-
using LikelihoodProfiler, Test, OptimizationNLopt, Plots, OrdinaryDiffEq, ForwardDiff
1+
using LikelihoodProfiler, Test
2+
using Optimization, OptimizationNLopt, Plots, OrdinaryDiffEq, ForwardDiff
23

34
######################################### PLProblem ##########################################
45

5-
optf = OptimizationFunction((x,p) -> 5.0 + (x[1]-3.0)^2 + (x[2]-4.0)^2, Optimization.AutoForwardDiff())
6-
optprob = OptimizationProblem(optf, [0.,0.])
6+
optf = OptimizationFunction((x,p) -> 5.0 + (x[1]-3.0)^2 + (x[2]-4.0)^2, AutoForwardDiff())
7+
optprob = OptimizationProblem(optf, [0.,0.]; lb=[-3,-1], ub=[10,9])
78

89
plprob = PLProblem(optprob, [3.,4.], [(-5,20), (-2,15)]; threshold=4.0)
910

1011
#################################### OptimizationProfiler ####################################
1112

12-
method1 = OptimizationProfiler(optimizer=NLopt.LN_NELDERMEAD(), step=FixedStep(; initial_step=0.1))
13+
method1 = OptimizationProfiler(optimizer=NLopt.LN_NELDERMEAD(), stepper = FixedStep(; initial_step=0.1))
1314
sol1 = profile(plprob, method1; verbose=true)
1415

1516

@@ -22,3 +23,26 @@ sol2 = profile(plprob, method2; verbose=true)
2223

2324
method3 = CICOProfiler(optimizer=:LN_NELDERMEAD, scan_tol=1e-3)
2425
sol3 = profile(plprob, method3; verbose=true)
26+
27+
28+
######################################### PLProblem w 1 parameter ##########################################
29+
30+
optf = OptimizationFunction((x,p) -> 5.0 + (x[1]-3.0)^2, AutoForwardDiff())
31+
optprob = OptimizationProblem(optf, [0.]; lb=[-10.], ub=[50.])
32+
33+
plprob = PLProblem(optprob, [3.], (-5,20); threshold=4.0)
34+
35+
#################################### OptimizationProfiler ####################################
36+
37+
method1 = OptimizationProfiler(optimizer=Optimization.LBFGS(), stepper = FixedStep(; initial_step=0.1))
38+
sol1 = profile(plprob, method1; verbose=true)
39+
40+
#################################### IntegrationProfiler ####################################
41+
42+
method2 = IntegrationProfiler(integrator=FBDF(autodiff = AutoFiniteDiff()), integrator_opts=(dtmax=0.1,), matrix_type=:hessian)
43+
sol2 = profile(plprob, method2; verbose=true)
44+
45+
######################################## CICOProfiler #######################################
46+
47+
method3 = CICOProfiler(optimizer=:LN_NELDERMEAD, scan_tol=1e-3)
48+
sol3 = profile(plprob, method3; verbose=true)

0 commit comments

Comments
 (0)