Minimize constraint function

Hello,
im struggling to get one of the julia optimization packages (optim, NLopt, Jump etc…) to work to minimize a constrained function.

In particular, im interested to find the minimum distance between a point and a conic section. Here is a python code using scipy.minimize that works.

  from scipy.optimize import minimize  
  def distance_to_conic(point, a, b, c, d, e, f):

  x0, y0 = point

  def objective(xy):
      x, y = xy
      return (x - x0)**2 + (y - y0)**2

  def constraint(xy):
      x, y = xy
      return a*x**2 + b*x*y + c*y**2 + d*x + e*y + f

  initial_guess = np.array([x0, y0])

  cons = {'type': 'eq', 'fun': constraint}

  result = minimize(objective, initial_guess, constraints=cons)


  closest_point = result.x
  min_distance = np.sqrt(objective(closest_point))
  return min_distance, closest_point

However, the python implementation is rather slow, so i want to speed things up in julia. Has anyone proper easy to follow documentation or examples for a similar problem in julia? I kinda lost in the package documentations …

Hi there!
If I’m not mistaken this is a quadratically constrained quadratic program. This kind of problem is rather well-suited to JuMP, see e.g. the tutorial

Are you sure that your constraint is an equality and not an inequality?

Why do you say this? It seems to be the distance to a conic so the constraint enforces this.

The JuMP example would be something like:

using JuMP, Ipopt
function distance_to_conic(point, a, b, c, d, e, f)
    x0, y0 = point
    model = Model(Ipopt.Optimizer)
    set_silent(model)
    @variable(model, x, start = x0)
    @variable(model, y, start = y0)
    @objective(model, Min, (x - x0)^2 + (y - y0)^2)
    @constraint(model, a * x^2 + b * x * y + c * y^2 + d * x + e * y + f == 0)
    optimize!(model)
    @assert is_solved_and_feasible(model)
    closest_point = value(x), value(y)
    min_distance = sqrt(objective_value(model))
    return min_distance, closest_point
end

I didn’t test this, so there might be a typo, etc, but it should point you in the right direction.

1 Like

Because I’m not used to solving constrained programming problems which are not convex I guess ^^

1 Like

Here is a solution with the solver IPOPT, but where the problem is modeled entirely with Julia functions:

pkg> add NLPModelsIpopt, ADNLPModels
julia> using ADNLPModels, NLPModelsIpopt
julia> function distance_to_conic(point, a, b, c, d, e, f)
           x0, y0 = point
           obj(x) = (x[1] - x0)^2 + (x[2] - y0)^2
           lvar = [-Inf, -Inf]  # lower bounds on variables
           uvar = [Inf, Inf]  # upper bounds on variables
           con(x) = [a * x[1]^2 + b * x[1] * x[2] + c * x[2]^2 + d * x[1] + e * x[2] + f]
           lcon = [0.0]  # constraint left-hand side
           ucon = [0.0]  # constraint right-hand side
           model = ADNLPModel(obj, [0.0, 0.0], lvar, uvar, con, lcon, ucon)
           stats = ipopt(model)
           return stats.solution, sqrt(stats.objective)
       end
3 Likes