Skip to content

Commit a0d0464

Browse files
authored
Prepare for ConstrainedProblems (#9)
* Add ConstrainedProblems module * Create MultivariateProblems module * Add the Beale unconstrained problem
1 parent 3024c55 commit a0d0464

8 files changed

+294
-84
lines changed

src/OptimTestProblems.jl

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
module OptimTestProblems
22

3-
include("optim_tests/multivariate/unconstrained.jl")
3+
export MultivariateProblems, UnivariateProblems
4+
5+
include("optim_tests/multivariate/multivariate.jl")
46
include("optim_tests/univariate/bounded.jl")
57

8+
# Deprecation stuff
9+
UnconstrainedProblems = OptimTestProblems.MultivariateProblems.UnconstrainedProblems
10+
export UnconstrainedProblems
11+
612
end # module
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
module ConstrainedProblems
2+
3+
using ..OptimizationProblem,..ConstraintData
4+
5+
examples = Dict{AbstractString, OptimizationProblem}()
6+
7+
hs9_obj(x::AbstractVector) = sin*x[1]/12) * cos*x[2]/16)
8+
hs9_c!(c::AbstractVector, x::AbstractVector) = (c[1] = 4*x[1]-3*x[2]; c)
9+
hs9_h!(h, x, λ) = h
10+
11+
function hs9_obj_g!(g::AbstractVector, x::AbstractVector)
12+
g[1] = π/12 * cos*x[1]/12) * cos*x[2]/16)
13+
g[2] = -π/16 * sin*x[1]/12) * sin*x[2]/16)
14+
g
15+
end
16+
function hs9_obj_h!(h::AbstractMatrix, x::AbstractVector)
17+
v = hs9_obj(x)
18+
h[1,1] = -π^2*v/144
19+
h[2,2] = -π^2*v/256
20+
h[1,2] = h[2,1] = -π^2 * cos*x[1]/12) * sin*x[2]/16) / 192
21+
h
22+
end
23+
24+
function hs9_jacobian!(J, x)
25+
J[1,1] = 4
26+
J[1,2] = -3
27+
J
28+
end
29+
30+
# TODO: IPNewtons gets stuck when using x0 = [0,0].
31+
# Check with Tim if this also happened before?
32+
examples["HS9"] = OptimizationProblem("HS9",
33+
hs9_obj,
34+
hs9_obj_g!,
35+
nothing,
36+
hs9_obj_h!,
37+
ConstraintData(hs9_c!, hs9_jacobian!, hs9_h!,
38+
[], [], [0.0], [0.0]),
39+
[-1.0,2.0],#[0.0, 0.0],
40+
[-3.0,-4.0],#[[12k-3, 16k-4] for k in (0, 1, -1)], # any integer k will do...
41+
hs9_obj([-3.0,-4.0]),
42+
true,
43+
true)
44+
45+
46+
end # module

src/optim_tests/multivariate/from_optim.jl

+10-1
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@ end
3131
examples["Exponential"] = OptimizationProblem("Exponential",
3232
exponential,
3333
exponential_gradient!,
34-
nothing,
34+
nothing, # fg!
3535
exponential_hessian!,
36+
nothing, # Constraints
3637
[0.0, 0.0],
3738
[2.0, 3.0],
3839
exponential([2.0, 3.0]),
@@ -122,6 +123,7 @@ examples["Fletcher-Powell"] = OptimizationProblem("Fletcher-Powell",
122123
fletcher_powell_gradient!,
123124
fletcher_powell_fun_gradient!,
124125
fletcher_powell_hessian!,
126+
nothing, # Constraints
125127
[-1.0, 0.0, 0.0], # Same as in source
126128
[1.0, 0.0, 0.0],
127129
0.0,
@@ -157,6 +159,7 @@ examples["Himmelblau"] = OptimizationProblem("Himmelblau",
157159
himmelblau_gradient!,
158160
nothing,
159161
himmelblau_hessian!,
162+
nothing, # Constraints
160163
[2.0, 2.0],
161164
[3.0, 2.0],
162165
himmelblau([3.0, 2.0]),
@@ -191,6 +194,7 @@ examples["Hosaki"] = OptimizationProblem("Hosaki",
191194
hosaki_gradient!,
192195
nothing,
193196
hosaki_hessian!,
197+
nothing, # Constraints
194198
[3.6, 1.9],
195199
[4.0, 2.0],
196200
hosaki([4.0, 2.0]),
@@ -235,6 +239,7 @@ examples["Large Polynomial"] = OptimizationProblem("Large Polynomial",
235239
large_polynomial_gradient!,
236240
nothing,
237241
large_polynomial_hessian!,
242+
nothing, # Constraints
238243
zeros(250),
239244
collect(float(1:250)),
240245
large_polynomial(collect(float(1:250))),
@@ -277,6 +282,7 @@ examples["Parabola"] = OptimizationProblem("Parabola",
277282
parabola_gradient!,
278283
nothing,
279284
parabola_hessian!,
285+
nothing, # Constraints
280286
[0.0, 0.0, 0.0, 0.0, 0.0],
281287
[1.0, 2.0, 3.0, 5.0, 8.0],
282288
parabola([1.0, 2.0, 3.0, 5.0, 8.0]),
@@ -316,6 +322,7 @@ examples["Polynomial"] = OptimizationProblem("Polynomial",
316322
polynomial_gradient!,
317323
nothing,
318324
polynomial_hessian!,
325+
nothing, # Constraints
319326
[0.0, 0.0, 0.0],
320327
[10.0, 7.0, 108.0],
321328
polynomial([10.0, 7.0, 108.0]),
@@ -366,6 +373,7 @@ examples["Powell"] = OptimizationProblem("Powell",
366373
powell_gradient!,
367374
nothing,
368375
powell_hessian!,
376+
nothing, # Constraints
369377
[3.0, -1.0, 0.0, 1.0],
370378
[0.0, 0.0, 0.0, 0.0],
371379
powell([0.0, 0.0, 0.0, 0.0]),
@@ -402,6 +410,7 @@ examples["Rosenbrock"] = OptimizationProblem("Rosenbrock",
402410
rosenbrock_gradient!,
403411
nothing,
404412
rosenbrock_hessian!,
413+
nothing, # Constraints
405414
[-1.2, 1.0],
406415
[1.0, 1.0],
407416
rosenbrock([1.0, 1.0]),

src/optim_tests/multivariate/more_testing.jl

+73-2
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ function _extrosenbrockproblem(N::Int;
6363
extrosenbrock_gradient!,
6464
extrosenbrock_fun_gradient!,
6565
extrosenbrock_hessian!,
66+
nothing, # Constraints
6667
initial_x,
6768
ones(initial_x),
6869
zero(T),
@@ -155,6 +156,7 @@ function _extpowellproblem(N::Int;
155156
extpowell_gradient!,
156157
extpowell_fun_gradient!,
157158
extpowell_hessian!,
159+
nothing, # Constraints
158160
initial_x,
159161
zeros(initial_x),
160162
zero(T),
@@ -194,7 +196,7 @@ function penfunI_gradient!(storage::AbstractArray,
194196
end
195197

196198
function penfunI_fun_gradient!(storage::AbstractArray,
197-
x::AbstractArray, param)
199+
x::AbstractArray, param)
198200
# TODO: we could do this without the xt storage holder
199201
xt = param.xt
200202
@. xt = param.alpha*(x-one(eltype(x)))
@@ -231,6 +233,7 @@ function _penfunIproblem(N::Int;
231233
penfunI_gradient!,
232234
penfunI_fun_gradient!,
233235
penfunI_hessian!,
236+
nothing, # Constraints
234237
initial_x,
235238
xsol,
236239
fsol,
@@ -273,7 +276,7 @@ function trigonometric_gradient!(storage::AbstractArray,
273276
end
274277

275278
function trigonometric_fun_gradient!(storage::AbstractArray,
276-
x::AbstractArray, param)
279+
x::AbstractArray, param)
277280
# TODO: we could do this without the xt storage holder
278281
n = length(x)
279282
xt = param.vec
@@ -298,6 +301,7 @@ function _trigonometricproblem(N::Int;
298301
trigonometric_gradient!,
299302
trigonometric_fun_gradient!,
300303
trigonometric_hessian!,
304+
nothing, # Constraints
301305
initial_x,
302306
zeros(initial_x),
303307
zero(T),
@@ -307,3 +311,70 @@ function _trigonometricproblem(N::Int;
307311
end
308312

309313
examples["Trigonometric"] = _trigonometricproblem(100)
314+
315+
316+
##########################################################################
317+
###
318+
### Beale (2D)
319+
###
320+
### Problem 5 in [3]
321+
###
322+
### Sum-of-squares objective, non-convex with g'*inv(H)*g == 0 at the
323+
### initial position.
324+
###
325+
##########################################################################
326+
327+
### General utilities for sum-of-squares functions
328+
# TODO: Update the other problems that are not Beale to use sumsq as well?
329+
330+
# Requires f(x) and J(x) computes the values and jacobian at x of a set of functions, and
331+
# that H(x, i) computes the hessian of the ith function
332+
333+
sumsq_obj(f, x) = sum(f(x).^2)
334+
335+
function sumsq_gradient!(g::AbstractVector, f, J, x::AbstractVector)
336+
copy!(g, sum((2.0 .* f(x)) .* J(x), 1))
337+
end
338+
339+
function sumsq_hessian!(h::AbstractMatrix, f, J, H, x::AbstractVector)
340+
fx = f(x)
341+
Jx = J(x)
342+
htmp = 2.0 .* (Jx' * Jx)
343+
for i = 1:length(fx)
344+
htmp += (2.0 * fx[i]) * H(x, i)
345+
end
346+
copy!(h, htmp)
347+
end
348+
349+
const beale_y = [1.5, 2.25, 2.625]
350+
351+
beale_f(x) = [beale_y[i] - x[1]*(1-x[2]^i) for i = 1:3]
352+
beale_J(x) = hcat([-(1-x[2]^i) for i = 1:3],
353+
[i*x[1]*x[2]^(i-1) for i = 1:3])
354+
function beale_H(x, i)
355+
od = i*x[2]^(i-1)
356+
d2 = i > 1 ? i*(i-1)*x[1]*x[2]^(i-2) : zero(x[2])
357+
[0 od; od d2]
358+
end
359+
360+
beale(x::AbstractVector) = sumsq_obj(beale_f, x)
361+
362+
function beale_gradient!(g::AbstractVector, x::AbstractVector)
363+
sumsq_gradient!(g, beale_f, beale_J, x)
364+
end
365+
366+
function beale_hessian!(h::AbstractMatrix, x::AbstractVector)
367+
sumsq_hessian!(h, beale_f, beale_J, beale_H, x)
368+
end
369+
370+
examples["Beale"] = OptimizationProblem("Beale",
371+
beale,
372+
beale_gradient!,
373+
nothing,
374+
beale_hessian!,
375+
nothing, # Constraints
376+
[1.0, 1.0],
377+
[3.0, 0.5],
378+
beale([3.0, 0.5]),
379+
true,
380+
true)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
module MultivariateProblems
2+
3+
import Base.gradient
4+
5+
export UnconstrainedProblems
6+
7+
export OptimizationProblem, objective, gradient, objective_gradient, hessian
8+
9+
struct ConstraintData{F,J,H,Tx,Tc}
10+
c!::F
11+
jacobian!::J
12+
h!::H
13+
lx::Vector{Tx}
14+
ux::Vector{Tx}
15+
lc::Vector{Tc}
16+
uc::Vector{Tc}
17+
end
18+
19+
immutable OptimizationProblem{P, Tfg, Tf <: Real, TS <: AbstractString,
20+
CT <: Union{Void,ConstraintData}}
21+
name::TS
22+
f::Function
23+
g!::Function
24+
fg!::Tfg
25+
h!::Function
26+
constraintdata::CT
27+
initial_x::Vector
28+
solutions::Vector
29+
minimum::Tf
30+
isdifferentiable::Bool
31+
istwicedifferentiable::Bool
32+
parameters::P
33+
end
34+
35+
OptimizationProblem(name::AbstractString,
36+
f::Function,
37+
g!::Function,
38+
fg!::Tfg,
39+
h!::Function,
40+
constraints::Union{Void,ConstraintData},
41+
initial_x::Vector,
42+
solutions::Vector,
43+
minimum::Tf,
44+
isdifferentiable::Bool,
45+
istwicedifferentiable::Bool) where Tf where Tfg =
46+
OptimizationProblem(name, f, g!, fg!, h!, constraints,
47+
initial_x, solutions, minimum,
48+
isdifferentiable,
49+
istwicedifferentiable,
50+
nothing)
51+
52+
objective(p::OptimizationProblem{P}) where P<:Void = p.f
53+
gradient(p::OptimizationProblem{P}) where P<:Void = p.g!
54+
objective_gradient(p::OptimizationProblem{P}) where P<:Void = p.fg!
55+
hessian(p::OptimizationProblem{P}) where P<:Void = p.h!
56+
57+
objective(p::OptimizationProblem{P}) where P = x-> p.f(x,p.parameters)
58+
gradient(p::OptimizationProblem{P}) where P = (out,x)-> p.g!(out,x,p.parameters)
59+
objective_gradient(p::OptimizationProblem{P}) where P = (out,x)-> p.fg!(out,x,p.parameters)
60+
hessian(p::OptimizationProblem{P}) where P = (out,x)-> p.h!(out,x,p.parameters)
61+
62+
function objective_gradient(p::OptimizationProblem{P,Tfg}) where P where Tfg <: Void
63+
(out,x) -> begin
64+
gradient(p)(out,x)
65+
return objective(p)(x)
66+
end
67+
end
68+
69+
function objective_gradient(p::OptimizationProblem{P,Tfg}) where P <: Void where Tfg <: Void
70+
(out,x) -> begin
71+
gradient(p)(out,x)
72+
return objective(p)(x)
73+
end
74+
end
75+
76+
77+
include("unconstrained.jl")
78+
include("constrained.jl")
79+
80+
end

src/optim_tests/multivariate/quad_transforms.jl

+2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ function _quadraticproblem(N::Int; mat::AbstractArray{T,2} = spdiagm(float(1:N))
4343
quad_gradient!,
4444
quad_fun_gradient!,
4545
quad_hessian!,
46+
nothing, # Constraints
4647
initial_x,
4748
x0,
4849
zero(T),
@@ -113,6 +114,7 @@ function _paraboloidproblem(N::Int; mat::AbstractArray{T,2} = spdiagm(float(1:N)
113114
paraboloid_gradient!,
114115
paraboloid_fun_gradient!,
115116
paraboloid_hessian!,
117+
nothing, # Constraints
116118
initial_x,
117119
x0, # x0 means the solution ...
118120
zero(T),

0 commit comments

Comments
 (0)