Solving system equations using Knitro


#1

I’m solving a system equation using KNITRO. For example the system takes the form:
x+3yˆ3-7+18=0
sin(y
exp(x)-1)=0

I want to use self-defined functions (instead of using ‘in-line’ functions as in JuMP). Therefore in Julia I run:

using KNITRO
using Base.Test

function eval_f(x::Vector{Float64})
  return 0
end

function eval_grad_f(x::Vector{Float64},grad::Vector{Float64})
  return [0 0]
end

function eval_g(x::Vector{Float64}, cons::Vector{Float64})
    cons[1] = (x[1]+3)*(x[2]^3-7)+18
    cons[2] = sin(x[2]*exp(x[1])-1)
end

function eval_jac_g(x::Vector{Float64}, jac::Vector{Float64})
    jac[1] = x[2]^3-7
    jac[2] = 3*x[2]^2*(x[1]+3)
    u = exp(x[1])*cos(x[2]*exp(x[1])-1)
    jac[3] = x[2]*u
    jac[4] = u
end

Then I start to setup the problem:

objGoal = KTR_OBJGOAL_MINIMIZE
objType = KTR_OBJTYPE_QUADRATIC

n = 2
x_L = -[KTR_INFBOUND,KTR_INFBOUND]
x_U = [KTR_INFBOUND,KTR_INFBOUND]

m = 2
c_Type = [KTR_CONTYPE_GENERAL,KTR_CONTYPE_GENERAL]
c_L = [0.0,0.0]
c_U = [0.0,0.0]

jac_con = Int32[0,0]
jac_var = Int32[0,1]

x       = [0.5,0.5]
lambda  = zeros(n+m)
obj     = [0.0]

kp = createProblem()

loadOptionsFile(kp, "knitro.opt")
setOption(kp, "hessopt", 6)
initializeProblem(kp, objGoal, objType, x_L, x_U, c_Type, c_L, c_U, jac_var, jac_con)

setFuncCallback(kp, eval_f, eval_g)
setGradCallback(kp, eval_grad_f, eval_jac_g)
solveProblem(kp)

However, I always encounter the problem in the eval_jac_g function saying that:

BoundsError: attempt to access 2-element Array{Float64,1} at index [3]

What’s the problem here? And what is the code jac_con = Int32[0,0]
and jac_var = Int32[0,1] doing?

I’m really new to the Knitro and probably ask a super silly question. I truly hope someone could help me out. Appreciate so much for taking time!


#2

I haven’t been through the Knitro interface (though really want to!) but since you have two equations and two unknowns, shouldn’t the jacobian be 2x2 rather than 4x1? If so, then jac[3] woudl be the culprit? Instead, are you supposed to go: jac[1,1], … jac[2,2]?

Also, in case you made a mistake in the signature of the function, it may make sense to drop the type annotations (i.e. just use x instead of x::Vector{Float64}), at least until you get it working … and maybe even after.


#3

Is this a problem you actually want to solve, or some random example you cooked up? It literally has hundreds of solutions on [-6,6] x [-6,6] according to IntervalRootFinding.jl.


#4

Thanks for the reply, jlperla!
Unfortunately dropping the type does not solve the problem. And I was following an example of knitro.jl to define the Jacobian function. It seems the Jacobian has to be reshaped into a vector if I understand correctly… But thanks anyway! :slight_smile: