Skip to content

Instantly share code, notes, and snippets.

@pkofod
Created May 31, 2016 18:11
Show Gist options
  • Save pkofod/8f5a4a02abeffae2092a58c8500fd0e2 to your computer and use it in GitHub Desktop.
Save pkofod/8f5a4a02abeffae2092a58c8500fd0e2 to your computer and use it in GitHub Desktop.
julia> using Base.Test
julia> # Quadratic objective function
# For (A*x-b)^2/2
function quadratic!(x, g, AtA, Atb, tmp)
calc_grad = !(g === nothing)
A_mul_B!(tmp, AtA, x)
v = dot(x,tmp)/2 + dot(Atb,x)
if calc_grad
for i = 1:length(g)
g[i] = tmp[i] + Atb[i]
end
end
return v
end
quadratic! (generic function with 1 method)
julia> srand(1)
MersenneTwister(Base.dSFMT.DSFMT_state(Int32[1749029653,1072851681,1610647787,1072862326,1841712345,1073426746,-198061126,1073322060,-156153802,1073567984 … 1977574422,1073209915,278919868,1072835605,1290372147,18858467,1815133874,-1716870370,382,-1]),[4.83826e-316,4.86122e-316,NaN,4.83592e-316,NaN,4.83597e-316,4.83847e-316,4.86128e-316,NaN,4.83592e-316 … NaN,4.83585e-316,NaN,4.86131e-316,NaN,4.86125e-316,NaN,4.8358e-316,NaN,4.83578e-316],382,UInt32[0x00000001])
julia> N = 8
8
julia> boxl = 2.0
2.0
julia> outbox = false
false
julia> # Generate a problem where the bounds-free solution lies outside of the chosen box
global objective
julia> while !outbox
A = randn(N,N)
AtA = A'*A
b = randn(N)
x0 = randn(N)
tmp = similar(x0)
func = (x, g) -> quadratic!(x, g, AtA, A'*b, tmp)
objective = Optim.DifferentiableFunction(x->func(x, nothing), (x,g)->func(x,g), func)
results = Optim.optimize(objective, x0, method=ConjugateGradient())
results = Optim.optimize(objective, results.minimum, method=ConjugateGradient()) # restart to ensure high-precision convergence
@test Optim.converged(results)
g = similar(x0)
@test func(results.minimum, g) + dot(b,b)/2 < 1e-8
@test norm(g) < 1e-4
outbox = any(abs(results.minimum) .> boxl)
end
julia> # fminbox
l = fill(-boxl, N)
8-element Array{Float64,1}:
-2.0
-2.0
-2.0
-2.0
-2.0
-2.0
-2.0
-2.0
julia> u = fill(boxl, N)
8-element Array{Float64,1}:
2.0
2.0
2.0
2.0
2.0
2.0
2.0
2.0
julia> x0 = (rand(N)-0.5)*boxl
8-element Array{Float64,1}:
0.906414
-0.231177
-0.359978
0.73125
-0.0908605
-0.159427
-0.549698
-0.427662
julia> for _optimizer in (ConjugateGradient, GradientDescent, LBFGS, BFGS)
results = Optim.optimize(objective, x0, l, u, Fminbox(), optimizer = _optimizer)
@test Optim.converged(results)
g = similar(x0)
objective.fg!(Optim.minimizer(results), g)
for i = 1:N
@test abs(g[i]) < 3e-3 || (Optim.minimizer(results)[i] < -boxl+1e-3 && g[i] > 0) || (Optim.minimizer(results)[i] > boxl-1e-3 && g[i] < 0)
end
end
WARNING: could not attach metadata for @simd loop.
julia> # tests for #180
results = Optim.optimize(objective, x0, l, u, Fminbox(); iterations = 2)
Results of Optimization Algorithm
* Algorithm: Fminbox with Conjugate Gradient
* Starting Point: [0.9064140813027981,-0.2311772762956541, ...]
* Minimizer: [-0.5461002475508969,1.9998456519574555, ...]
* Minimum: -3.468545e+00
* Iterations: 2
* Convergence: true
* |x - x'| < 1.0e-32: false
* |f(x) - f(x')| / |f(x)| < 1.0e-08: true
* |g(x)| < 1.0e-08: false
* Reached Maximum Number of Iterations: false
* Objective Function Calls: 220
* Gradient Calls: 152
julia> @test results.iterations == 2
julia> @test results.f_minimum == objective.f(results.minimum)
julia> # might fail if changes are made to Optim.jl
# TODO: come up with a better test
results = Optim.optimize(objective, x0, l, u, Fminbox(); optimizer_o = OptimizationOptions(iterations = 2))
Results of Optimization Algorithm
* Algorithm: Fminbox with Conjugate Gradient
* Starting Point: [0.9064140813027981,-0.2311772762956541, ...]
* Minimizer: [-0.5469850981527203,1.9999999999999998, ...]
* Minimum: -3.468380e+00
* Iterations: 470
* Convergence: true
* |x - x'| < 1.0e-32: false
* |f(x) - f(x')| / |f(x)| < 1.0e-08: true
* |g(x)| < 1.0e-08: false
* Reached Maximum Number of Iterations: false
* Objective Function Calls: 3893
* Gradient Calls: 2941
julia> @test results.iterations == 470
julia>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment