Skip to content

Commit fe73975

Browse files
Merge pull request #342 from SciML/Vaibhavdixit02-patch-1
Incorrect `convert` call for `cons_hess_prototype` since it's a vector of matrices and make manually passed derivatives take 3 arguments
2 parents 60b6ffb + 0bc903b commit fe73975

File tree

11 files changed

+85
-56
lines changed

11 files changed

+85
-56
lines changed

docs/src/optimization_packages/optim.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ The following special keyword arguments which are not covered by the common `sol
4646
* `show_every`: Trace output is printed every `show_every`th iteration.
4747

4848

49-
For a more extensive documentation of all the algorithms and options please consult the
49+
For a more extensive documentation of all the algorithms and options please consult the
5050
[`Documentation`](https://julianlsolvers.github.io/Optim.jl/stable/#)
5151

5252
## Local Optimizer
@@ -73,7 +73,7 @@ The Rosenbrock function can optimized using the `Optim.IPNewton()` as follows:
7373

7474
```julia
7575
rosenbrock(x, p) = (p[1] - x[1])^2 + p[2] * (x[2] - x[1]^2)^2
76-
cons= (x,p) -> [x[1]^2 + x[2]^2]
76+
cons= (res,x,p) -> res .= [x[1]^2 + x[2]^2]
7777
x0 = zeros(2)
7878
p = [1.0,100.0]
7979
prob = OptimizationFunction(rosenbrock, Optimization.AutoForwardDiff();cons= cons)
@@ -345,7 +345,7 @@ The Rosenbrock function can optimized using the `Optim.KrylovTrustRegion()` as f
345345

346346
```julia
347347
rosenbrock(x, p) = (1 - x[1])^2 + 100 * (x[2] - x[1]^2)^2
348-
cons= (x,p) -> [x[1]^2 + x[2]^2]
348+
cons= (res,x,p) -> res .= [x[1]^2 + x[2]^2]
349349
x0 = zeros(2)
350350
p = [1.0,100.0]
351351
optprob = OptimizationFunction(rosenbrock, Optimization.AutoForwardDiff();cons= cons)

docs/src/tutorials/rosenbrock.md

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
# Solving the Rosenbrock Problem in >10 Ways
2-
2+
33
This tutorial is a demonstration of many different solvers to demonstrate the
44
flexibility of Optimization.jl. This is a gauntlet of many solvers to get a feel
55
for common workflows of the package and give copy-pastable starting points.
66

77
!!! note
88

99
This example uses many different solvers of Optimization.jl. Each solver
10-
subpackage needs to be installed separate. For example, for the details on
11-
the installation and usage of OptimizationOptimJL.jl package, see the
10+
subpackage needs to be installed separate. For example, for the details on
11+
the installation and usage of OptimizationOptimJL.jl package, see the
1212
[Optim.jl page](@ref optim).
1313

1414
```@example rosenbrock
@@ -39,8 +39,8 @@ sol = solve(prob, NelderMead())
3939
4040
# Now a gradient-based optimizer with forward-mode automatic differentiation
4141
42-
optf = OptimizationFunction(rosenbrock, Optimization.AutoForwardDiff())
43-
prob = OptimizationProblem(optf, x0, _p)
42+
optf = OptimizationFunction(rosenbrock, Optimization.AutoForwardDiff())
43+
prob = OptimizationProblem(optf, x0, _p)
4444
sol = solve(prob, BFGS())
4545
4646
# Now a second order optimizer using Hessians generated by forward-mode automatic differentiation
@@ -53,7 +53,7 @@ sol = solve(prob, Optim.KrylovTrustRegion())
5353
5454
# Now derivative-based optimizers with various constraints
5555
56-
cons = (x,p) -> [x[1]^2 + x[2]^2]
56+
cons = (res,x,p) -> res .= [x[1]^2 + x[2]^2]
5757
optf = OptimizationFunction(rosenbrock, Optimization.AutoForwardDiff();cons= cons)
5858
#prob = OptimizationProblem(optf, x0, _p)
5959
#sol = solve(prob, IPNewton()) # No lcons or rcons, so constraints not satisfied
@@ -64,24 +64,24 @@ sol = solve(prob, IPNewton()) # Note that -Inf < x[1]^2 + x[2]^2 < Inf is always
6464
prob = OptimizationProblem(optf, x0, _p, lcons = [-5.0], ucons = [10.0])
6565
sol = solve(prob, IPNewton()) # Again, -5.0 < x[1]^2 + x[2]^2 < 10.0
6666
67-
prob = OptimizationProblem(optf, x0, _p, lcons = [-Inf], ucons = [Inf],
67+
prob = OptimizationProblem(optf, x0, _p, lcons = [-Inf], ucons = [Inf],
6868
lb = [-500.0,-500.0], ub=[50.0,50.0])
6969
sol = solve(prob, IPNewton())
7070
71-
prob = OptimizationProblem(optf, x0, _p, lcons = [0.5], ucons = [0.5],
72-
lb = [-500.0,-500.0], ub=[50.0,50.0])
71+
prob = OptimizationProblem(optf, x0, _p, lcons = [0.5], ucons = [0.5],
72+
lb = [-500.0,-500.0], ub=[50.0,50.0])
7373
sol = solve(prob, IPNewton()) # Notice now that x[1]^2 + x[2]^2 ≈ 0.5:
7474
# cons(sol.minimizer, _p) = 0.49999999999999994
7575
76-
function con2_c(x,p)
77-
[x[1]^2 + x[2]^2, x[2]*sin(x[1])-x[1]]
76+
function con2_c(res,x,p)
77+
res .= [x[1]^2 + x[2]^2, x[2]*sin(x[1])-x[1]]
7878
end
7979
8080
optf = OptimizationFunction(rosenbrock, Optimization.AutoForwardDiff();cons= con2_c)
8181
prob = OptimizationProblem(optf, x0, _p, lcons = [-Inf,-Inf], ucons = [Inf,Inf])
8282
sol = solve(prob, IPNewton())
8383
84-
cons_circ = (x,p) -> [x[1]^2 + x[2]^2]
84+
cons_circ = (x,p) -> res .= [x[1]^2 + x[2]^2]
8585
optf = OptimizationFunction(rosenbrock, Optimization.AutoForwardDiff();cons= cons_circ)
8686
prob = OptimizationProblem(optf, x0, _p, lcons = [-Inf], ucons = [0.25^2])
8787
sol = solve(prob, IPNewton()) # -Inf < cons_circ(sol.minimizer, _p) = 0.25^2
@@ -116,7 +116,7 @@ sol = solve(prob, Opt(:LD_LBFGS, 2))
116116
## Evolutionary.jl Solvers
117117
118118
using OptimizationEvolutionary
119-
sol = solve(prob, CMAES(μ =40 , λ = 100),abstol=1e-15) # -1.0 ≤ x[1], x[2] ≤ 0.8
119+
sol = solve(prob, CMAES(μ =40 , λ = 100),abstol=1e-15) # -1.0 ≤ x[1], x[2] ≤ 0.8
120120
121121
## BlackBoxOptim.jl Solvers
122122

lib/OptimizationOptimJL/test/runtests.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ using Test
9393
sol = solve(prob, BFGS())
9494
@test 10 * sol.minimum < l1
9595

96-
function g!(G, x)
96+
function g!(G, x, p = nothing)
9797
G[1] = -2.0 * (1.0 - x[1]) - 400.0 * (x[2] - x[1]^2) * x[1]
9898
G[2] = 200.0 * (x[2] - x[1]^2)
9999
end

src/function/finitediff.jl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ function instantiate_function(f, x, adtype::AutoFiniteDiff, p, num_cons = 0)
5959
args...),
6060
θ, gradcache)
6161
else
62-
grad = f.grad
62+
grad = (G, θ, args...) -> f.grad(G, θ, p, args...)
6363
end
6464

6565
if f.hess === nothing
@@ -71,7 +71,7 @@ function instantiate_function(f, x, adtype::AutoFiniteDiff, p, num_cons = 0)
7171
updatecache(hesscache,
7272
θ))
7373
else
74-
hess = f.hess
74+
hess = (H, θ, args...) -> f.hess(H, θ, p, args...)
7575
end
7676

7777
if f.hv === nothing
@@ -102,7 +102,7 @@ function instantiate_function(f, x, adtype::AutoFiniteDiff, p, num_cons = 0)
102102
FiniteDiff.finite_difference_jacobian!(J, cons, θ, jaccache)
103103
end
104104
else
105-
cons_j = f.cons_j
105+
cons_j = (J, θ) -> f.cons_j(J, θ, p)
106106
end
107107

108108
if cons !== nothing && f.cons_h === nothing
@@ -120,13 +120,13 @@ function instantiate_function(f, x, adtype::AutoFiniteDiff, p, num_cons = 0)
120120
end
121121
end
122122
else
123-
cons_h = f.cons_h
123+
cons_h = (res, θ) -> f.cons_h(res, θ, p)
124124
end
125125

126126
return OptimizationFunction{true}(f, adtype; grad = grad, hess = hess, hv = hv,
127127
cons = cons, cons_j = cons_j, cons_h = cons_h,
128128
cons_jac_colorvec = cons_jac_colorvec,
129-
hess_prototype = nothing,
129+
hess_prototype = f.hess_prototype,
130130
cons_jac_prototype = f.cons_jac_prototype,
131-
cons_hess_prototype = nothing)
131+
cons_hess_prototype = f.cons_hess_prototype)
132132
end

src/function/forwarddiff.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,15 +51,15 @@ function instantiate_function(f::OptimizationFunction{true}, x,
5151
grad = (res, θ, args...) -> ForwardDiff.gradient!(res, x -> _f(x, args...), θ,
5252
gradcfg, Val{false}())
5353
else
54-
grad = f.grad
54+
grad = (G, θ, args...) -> f.grad(G, θ, p, args...)
5555
end
5656

5757
if f.hess === nothing
5858
hesscfg = ForwardDiff.HessianConfig(_f, x, ForwardDiff.Chunk{chunksize}())
5959
hess = (res, θ, args...) -> ForwardDiff.hessian!(res, x -> _f(x, args...), θ,
6060
hesscfg, Val{false}())
6161
else
62-
hess = f.hess
62+
hess = (H, θ, args...) -> f.hess(H, θ, p, args...)
6363
end
6464

6565
if f.hv === nothing
@@ -85,7 +85,7 @@ function instantiate_function(f::OptimizationFunction{true}, x,
8585
ForwardDiff.jacobian!(J, cons_oop, θ, cjconfig)
8686
end
8787
else
88-
cons_j = f.cons_j
88+
cons_j = (J, θ) -> f.cons_j(J, θ, p)
8989
end
9090

9191
if cons !== nothing && f.cons_h === nothing
@@ -99,12 +99,12 @@ function instantiate_function(f::OptimizationFunction{true}, x,
9999
end
100100
end
101101
else
102-
cons_h = f.cons_h
102+
cons_h = (res, θ) -> f.cons_h(res, θ, p)
103103
end
104104

105105
return OptimizationFunction{true}(f.f, adtype; grad = grad, hess = hess, hv = hv,
106106
cons = cons, cons_j = cons_j, cons_h = cons_h,
107-
hess_prototype = nothing,
107+
hess_prototype = f.hess_prototype,
108108
cons_jac_prototype = f.cons_jac_prototype,
109109
cons_hess_prototype = f.cons_hess_prototype)
110110
end

src/function/function.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ function instantiate_function(f, x, ::AbstractADType, p, num_cons = 0)
5555
cons_jac_prototype = f.cons_jac_prototype === nothing ? nothing :
5656
convert.(eltype(x), f.cons_jac_prototype)
5757
cons_hess_prototype = f.cons_hess_prototype === nothing ? nothing :
58-
convert.(eltype(x), f.cons_hess_prototype)
58+
[convert.(eltype(x), f.cons_hess_prototype[i])
59+
for i in 1:num_cons]
5960
expr = symbolify(f.expr)
6061
cons_expr = symbolify.(f.cons_expr)
6162

src/function/mtk.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@ function instantiate_function(f, x, adtype::AutoModelingToolkit, p, num_cons = 0
1515
grad_oop, grad_iip = ModelingToolkit.generate_gradient(sys, expression = Val{false})
1616
grad(J, u) = (grad_iip(J, u, p); J)
1717
else
18-
grad = f.grad
18+
grad = (G, θ, args...) -> f.grad(G, θ, p, args...)
1919
end
2020

2121
if f.hess === nothing
2222
hess_oop, hess_iip = ModelingToolkit.generate_hessian(sys, expression = Val{false},
2323
sparse = adtype.obj_sparse)
2424
hess(H, u) = (hess_iip(H, u, p); H)
2525
else
26-
hess = f.hess
26+
hess = (H, θ, args...) -> f.hess(H, θ, p, args...)
2727
end
2828

2929
if f.hv === nothing
@@ -69,7 +69,7 @@ function instantiate_function(f, x, adtype::AutoModelingToolkit, p, num_cons = 0
6969
jac_iip(J, θ, p)
7070
end
7171
else
72-
cons_j = f.cons_j
72+
cons_j = (J, θ) -> f.cons_j(J, θ, p)
7373
end
7474

7575
if f.cons !== nothing && f.cons_h === nothing
@@ -82,7 +82,7 @@ function instantiate_function(f, x, adtype::AutoModelingToolkit, p, num_cons = 0
8282
cons_hess_iip(res, θ, p)
8383
end
8484
else
85-
cons_h = f.cons_h
85+
cons_h = (res, θ) -> f.cons_h(res, θ, p)
8686
end
8787

8888
if adtype.obj_sparse

src/function/reversediff.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ function instantiate_function(f, x, adtype::AutoReverseDiff, p = SciMLBase.NullP
5353
grad = (res, θ, args...) -> ReverseDiff.gradient!(res, x -> _f(x, args...), θ,
5454
ReverseDiff.GradientConfig(θ))
5555
else
56-
grad = f.grad
56+
grad = (G, θ, args...) -> f.grad(G, θ, p, args...)
5757
end
5858

5959
if f.hess === nothing
@@ -70,7 +70,7 @@ function instantiate_function(f, x, adtype::AutoReverseDiff, p = SciMLBase.NullP
7070
end
7171
end
7272
else
73-
hess = f.hess
73+
hess = (H, θ, args...) -> f.hess(H, θ, p, args...)
7474
end
7575

7676
if f.hv === nothing
@@ -86,7 +86,7 @@ function instantiate_function(f, x, adtype::AutoReverseDiff, p = SciMLBase.NullP
8686

8787
return OptimizationFunction{false}(f, adtype; grad = grad, hess = hess, hv = hv,
8888
cons = nothing, cons_j = nothing, cons_h = nothing,
89-
hess_prototype = nothing,
89+
hess_prototype = f.hess_prototype,
9090
cons_jac_prototype = nothing,
9191
cons_hess_prototype = nothing)
9292
end

src/function/tracker.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,13 @@ function instantiate_function(f, x, adtype::AutoTracker, p, num_cons = 0)
3636
res .= Tracker.data(Tracker.gradient(x -> _f(x, args...),
3737
θ)[1])
3838
else
39-
grad = f.grad
39+
grad = (G, θ, args...) -> f.grad(G, θ, p, args...)
4040
end
4141

4242
if f.hess === nothing
4343
hess = (res, θ, args...) -> error("Hessian based methods not supported with Tracker backend, pass in the `hess` kwarg")
4444
else
45-
hess = f.hess
45+
hess = (H, θ, args...) -> f.hess(H, θ, p, args...)
4646
end
4747

4848
if f.hv === nothing
@@ -53,7 +53,7 @@ function instantiate_function(f, x, adtype::AutoTracker, p, num_cons = 0)
5353

5454
return OptimizationFunction{false}(f, adtype; grad = grad, hess = hess, hv = hv,
5555
cons = nothing, cons_j = nothing, cons_h = nothing,
56-
hess_prototype = nothing,
56+
hess_prototype = f.hess_prototype,
5757
cons_jac_prototype = nothing,
5858
cons_hess_prototype = nothing)
5959
end

src/function/zygote.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ function instantiate_function(f, x, adtype::AutoZygote, p, num_cons = 0)
3636
θ)[1]) :
3737
res .= Zygote.gradient(x -> _f(x, args...), θ)[1]
3838
else
39-
grad = f.grad
39+
grad = (G, θ, args...) -> f.grad(G, θ, p, args...)
4040
end
4141

4242
if f.hess === nothing
@@ -52,7 +52,7 @@ function instantiate_function(f, x, adtype::AutoZygote, p, num_cons = 0)
5252
end
5353
end
5454
else
55-
hess = f.hess
55+
hess = (H, θ, args...) -> f.hess(H, θ, p, args...)
5656
end
5757

5858
if f.hv === nothing
@@ -68,7 +68,7 @@ function instantiate_function(f, x, adtype::AutoZygote, p, num_cons = 0)
6868

6969
return OptimizationFunction{false}(f, adtype; grad = grad, hess = hess, hv = hv,
7070
cons = nothing, cons_j = nothing, cons_h = nothing,
71-
hess_prototype = nothing,
71+
hess_prototype = f.hess_prototype,
7272
cons_jac_prototype = nothing,
7373
cons_hess_prototype = nothing)
7474
end

0 commit comments

Comments
 (0)