# Converting non-linear optimization with fmincom from Matlab to Julia

Hi,
I’m new to Julia language and I’m trying to replicate an optimization function created in Matlab using fmincom in Julia in order to improve the computation time that is quite huge in Matlab.
I’ve used the JuMP modeling language with the Ipopt solver to specify and optimize my model but i always get the error message: EXIT: Converged to a point of local infeasibility. Problem may be infeasible.
This is my objective function:

``````function Jfun(k::T...) where {T<:Real}
k0=optimization_data["k0"];
a=optimization_data["a"];
b=optimization_data["b"];
s_sweep=optimization_data["sweep"];
k1=T[k0];

for item in k
push!(k1,item);
end

ds=[s_sweep[i+1]-s_sweep[i] for i in range(start=1,stop=length(s_sweep)-1)];
ah=[0.5*(a[i+1]+a[i]) for i in range(start=1,stop=length(a)-1)];
bh=[0.5*(b[i+1]+b[i]) for i in range(start=1,stop=length(b)-1)];
kh=[0.5*(k1[i+1]+k1[i]) for i in range(start=1,stop=length(k1)-1)];
f_temp=[k1[i+1]-k1[i] for i in range(start=1,stop=length(k1)-1)];

f=[]
for i in range(start=1,stop=length(f_temp))
push!(f,f_temp[i]/ds[i]+ah[i]*kh[i]+bh[i]);
end

Jval=0;
for i in range(start=1,stop=length(f))
Jval+=(f[i]^2)*ds[i];
end
return Jval
end
``````

This is the main of the application:

``````model = Model((Ipopt.Optimizer));
@variable(model,k[i=1:length(k0guess)],upper_bound=upper_bounds[i+1],lower_bound=lower_bounds[i+1],start=k0guess[i])
register(model,:Jfun,length(k0guess),Jfun;autodiff=true)
# Objective function
@NLobjective(model, Min, Jfun(k...))
register(model,:timeConstrain,length(k0guess),timeConstrain,autodiff=true)
# Equality constraint
@NLconstraint(model,timeConstrain(k...)==0)
# Solve the optimization problem
JuMP.optimize!(model)
``````

After some debugging I found out that in my Julia code, the lower and upper bounds and the initial guess of my objective function can be only numeric values, while in Matlab, those parameters were array of numbers. So, when the optimization is running, I found out that in Matlab the objective function receives the entire array k0guess as k, while in Julia k is an array filled with zeros, because of that the objective function returns a wrong value that is different from the Matlab one.

These are the lines of codes of the objective function that gives me a different result from Matlab:

``````k1=T[k0];
for item in k
push!(k1,item);
end
``````

Is there a way to emulate the same behavior of Matlab or i have to change my objective function in order to adapt it to compute a single value at a time?
Thank you so much in advance for your help!!

Hi @Alfespo97, welcome to the forum.

I have quite a few ideas for how we can improve your model, but the biggest problem that the moment is that I don’t know what `optimization_data` or `timeConstrain` is, so I cannot reproduce your issue.

Do you have a reproducible example that you can share?

I don’t have the data so I can’t test this (or check if I made a mistake), but this should point you in the right direction:

``````using JuMP, Ipopt
k0 = optimization_data["k0"]
a = optimization_data["a"]
b = optimization_data["b"]
s_sweep = optimization_data["sweep"]
N = length(k0guess)
ds = [s_sweep[i] - s_sweep[i-1] for i in 2:length(s_sweep)]
d(x, i) = 0.5 (x[i+1] + x[i])
model = Model(Ipopt.Optimizer)
@variable(model, lower_bounds[i+1] <= k[i=1:N] <= upper_bounds[i+1], start=k0guess[i])
@variable(model, f[1:N])
k1 = T[k0, k...]
@constraint(
model,
[i in 1:N],
f[i] == (k1[i+1]-k1[i]) / ds[i] + d(a, i) * d(k1, i) + d(b, i),
)
@objective(model, Min, sum(f[i]^2 * ds[i] for i in 1:N))
``````
2 Likes

`fmincon` in Matlab is a multi-algorithm. Do you know which one(s) are used?

1 Like

Thank you really much for the quick response.
Regarding optimization_data, it is a struct that i have exported from Matlab that contains the parameters used to compute the objective and constraint function. I did this because i wanted to test the performance and computation time of the optimization in Julia before translating all my Matlab scripts.
Here is the link to the JSON file:

While this is the timeConstrain function:

``````function timeConstrain(k::T...) where {T<:Real}
k0=optimization_data["k0"]
s_sweep=optimization_data["sweep"]
tmax=optimization_data["tmax"];
m=1;
k1=T[k0];

for item in k
push!(k1,item);
end
ds=[s_sweep[i+1]-s_sweep[i] for i in range(start=1,stop=length(s_sweep)-1)];
kh=[0.5*(k1[i+1]+k1[i]) for i in range(start=1,stop=length(k1)-1)];
g=[]
for item in kh
push!(g,sqrt(m./(2*item)))
end
#c=[];  vincolo di disuglianza non lineare (in questo caso non è presente)
ceq=0;
for i in range(start=1,stop=length(g))

ceq+=g[i]*ds[i]-tmax;
end
return ceq
end
``````

However i will try to modify my code following your advices. Thank you for your help!

1 Like

Hi, thank you for the response, the algorithm used in Matlab is ‘interior point’ which is the default algorithm if none is set. Here is the Matlab code with the call to fmincon.

``````timecon=@(k)timeConstrain(k0,k,Tmax, s_sweep, m); % time constraint
nonlcon=@(k)constrainFun(k0,k,Tmax, VehicleData.FmapCoeff, s_sweep, a, b, m, Kref, Lref, mrif)
fun=@(k)Jfun(k0,k, s_sweep, a, b); % objective function
options.Display = 'off'; %'final-detailed';
options.Diagnostics='off';
options.MaxFunctionEvaluations=1e8;
options.StepTolerance=1.e-8;
options.MaxIterations=1e6;
[K1guess]=fmincon(fun,k0guess,[],[],[],[],lb(2:end),ub(2:end),timecon,options);
% Ottimizzazione con vincolo temporale e vincoli di forza
[K0guess,~,exitflag,~]=fmincon(fun,K1guess,[],[],[],[],lb(2:end),ub(2:end),nonlcon,options); %aggiunta commentando la precedente minimizzazione
``````

Thank you again for your help, appreciate it a lot!!

My understanding is that fmincon switches algorithms depending on the convergence behaviour. There is some setting that causes the algorithm to be printed in the output (‘Display’).

Edit: I can’t find it in Matlab 2023 anymore. Perhaps this was abandoned?

1 Like

`fmincon` function is still there in Matlab in the latest release (R2023b), namely in the official Optimization Toolbox for Matlab, see Find minimum of constrained nonlinear multivariable function - MATLAB fmincon. Not seeing the toolbox can mean that the toolbox just has not been installed on your machine.

Some description of implemented algorithms is in Choosing the Algorithm - MATLAB & Simulink.

1 Like

I meant I could not find the output of the used algorithm from fmincon.

1 Like

For convenience, the `Display` option is available through optimoptions. Perhaps the most detailed info is obtained by setting `opts = optimoptions('fmincon','Display','iter-detailed')` before calling the solver `x = fmincon(...,opts)`.

1 Like

I didn’t test this locally, but something like this should work:

``````using JuMP, Ipopt
k0 = optimization_data["k0"]
a = optimization_data["a"]
b = optimization_data["b"]
s_sweep = optimization_data["sweep"]
tmax = optimization_data["tmax"]
m = 1
N = length(k0guess)
ds = [s_sweep[i] - s_sweep[i-1] for i in 2:length(s_sweep)]
d(x, i) = 0.5 (x[i+1] + x[i])
model = Model(Ipopt.Optimizer)
@variable(model, lower_bounds[i+1] <= k[i=1:N] <= upper_bounds[i+1], start=k0guess[i])
@variable(model, f[1:N])
k1 = T[k0, k...]
@constraint(
model,
[i in 1:N],
f[i] == (k1[i+1]-k1[i]) / ds[i] + d(a, i) * d(k1, i) + d(b, i),
)
@constraint(model, sum(sqrt(m / (2 * d(k1, i))) * ds[i] for i in 1:N) == N * tmax)
@objective(model, Min, sum(f[i]^2 * ds[i] for i in 1:N))
``````
1 Like

Thank you for the answer and sorry for bothering you for my lack of knowledge in Julia even if i like the code syntax, it’s really cool!
However I’m still getting an error: ‘UndefVarError: `T` not defined’ on ‘k1 = T[k0, k…]’. Do you have any advice for this?
Edit: i declared T as any and i think this made the trick.

1 Like

Yeah, i tried to display it on the output console but i could only see the numeric values of each iteration, it didn’t show any info on the algorithm

Just delete the T

1 Like