Hi, I’m trying to optimize a function over a disk using a transformation to polar coordinates. When I restrict the radius to non-negative values, there is no problem, but when I allow it to be negative, I get that the algorithm sometimes does not find the optimum. Although I can just restrict to non-negative values for my use-case, I’m trying to understand if there is a deeper, subtle issue here that can bite me in that case. Is the problem the non-differentiability that I’m introducing by taking the absolute value of the radius?
using GLMakie, Optim, ForwardDiff, StaticArrays, LinearAlgebra
from_polar(a::AbstractVector{<:Real}) = abs(a[1]) .* collect(sincospi(a[2]))
optimize_circle(f, r) = from_polar(Optim.optimize(x -> f(from_polar(x)), SVector(-r, -1), SVector(r, 1), [0.5*r, 0.], Fminbox(BFGS(linesearch = Optim.LineSearches.BackTracking(order=3))); autodiff = :forward).minimizer)
optimize_circle2(f, r) = from_polar(Optim.optimize(x -> f(from_polar(x)), SVector(0, -1), SVector(r, 1), [0.5*r, 0.], Fminbox(BFGS(linesearch = Optim.LineSearches.BackTracking(order=3))); autodiff = :forward).minimizer)
function test(N, r)
x_points = Matrix{Float64}(undef, 2*N + 1, 4)
for i in 0:(2*N)
x_point = r .* [cos(pi*i/N), sin(pi*i/N)]
x_points[i + 1, 1:2] = x_point
f_test = x -> norm(x .- x_point)
x_opt = optimize_circle(f_test, r)
x_opt2 = optimize_circle2(f_test, r)
x_points[i + 1, 3] = f_test(x_opt)
x_points[i + 1, 4] = f_test(x_opt2)
end
f = Figure()
ax1 = Axis3(f[1, 1], title = "Optimized norm using [-$r,$r] × [-1, 1]")
scatter!(ax1, x_points[:, 1], x_points[:, 2], x_points[:,3])
println("Optimizing over [-$r,$r] × [-1, 1] yields a maximum norm of $(maximum(x_points[:, 3]))")
ax2 = Axis3(f[1, 2], title = "Optimized norm using [0,$r] × [-1, 1]")
scatter!(ax2, x_points[:, 1], x_points[:, 2], x_points[:,4])
println("Optimizing over [0,$r] × [-1, 1] yields a maximum norm of $(maximum(x_points[:, 4]))")
display(GLMakie.Screen(), f)
end
GLMakie.closeall()
test(100, 1.)
gives
Optimizing over [-1.0,1.0] × [-1, 1] yields a maximum norm of 1.0
Optimizing over [0,1.0] × [-1, 1] yields a maximum norm of 3.3333343259534044e-10