Hi there!
I am fairly new to Julia, I was converted after seeing some awesome performance compared to MATLAB, which I currently use. I tried rewriting in Julia an optimization problem that I had in MATLAB, and everything is much faster (as I hoped) except for the actual optimization. What am I doing wrong? To be clear, the optimization works, it’s just very slow compared to MATLAB. I attach both.
Also, is there in Julia something analogous to “Run and time” of MATLAB? Something showing the code, line-by-line, with the time spent in each line?
Julia:
using Optimizion, OptimizationOptimJL, Plots, Dierckx, OptimizationMOI, Ipopt, ForwardDiff, ModelingToolkit, Symbolics
# functions
function action(b::Vector{Float64},I::Vector{Float64})
hh=[I[2:1:end];0]-I
pop!(hh)
bx=I[1:length(hh)]+hh./2
bs=Spline1D(I, b; k=1)(bx)
sx=diff(b)./hh
Lag=lagrangian(bx,bs,sx)
Int=hh.*Lag
S=sum(Int)./(2*pi)
return S
end
function lagrangian(x::Vector{Float64},s::Vector{Float64},sx::Vector{Float64})
L=sqrt.(sx.^2 + s.^4)
return L
end
function interval(N::Int)
I=range(0,(L/2)^3,length=N)
I=I.^(1/3)
I=[-I[end:-1:1];I]
filter!(e->hash(e)≠hash(-0.0),I)
return I
end
# definitions
rmax = 1e2
L = 0.3
I = interval(40)
b0 = ones(length(I))
S(b, I) = action(b, I)
# optimization
cons(res, b, I) = (res .= [b[1], b[end]])
optprob = OptimizationFunction(S, Optimization.AutoFiniteDiff(), cons = cons)
prob = OptimizationProblem(optprob, b0, I, lcons = [rmax, rmax], ucons = [rmax, rmax], lb = zeros(length(I)), ub = rmax.*ones(length(I)))
sol = solve(prob, IPNewton());
MATLAB:
% parameters
h = 1e-2;
rmax = 1e2;
L = 0.3;
% creates interval, denser near the extrema
I = linspace(0,(L/2)^3,40);
I=I.^(1/3);
I=unique([-flip(I),I]);
b0 = ones(numel(I),1);
S = @(b) action(I,b);
% impose constraints
AA = zeros(length(b0)); AA(1) = 1; AA(end) = 1;
bb = zeros(size(b0)); bb(1) = rmax; bb(end) = rmax;
lb=zeros(size(b0))-h;
ub=rmax*ones(size(b0))+h;
% optimize
options = optimoptions('fmincon','Display','iter-detailed',...
'OptimalityTolerance',1e-5,'MaxIterations',1e4,'ConstraintTolerance',1e-16,'MaxFunctionEvaluations',1e6);
[bopt,Sopt,exitflag,output]=fmincon(S,b0,[],[],AA,bb,lb,ub,[],options);
%% functions
function S = action(I,b)
hh=circshift(I,-1)-I;
hh(end)=[];
bx=I(1:numel(hh))+hh./2;
bs=interp1(I,b,bx);
sx=diff(b)'./hh;
L=lagrangian(bx,bs,sx);
Int= hh .* L;
S=sum(Int)./(2*pi);
end
function L=lagrangian(~,s,sx)
L = sqrt(sx.^2 + s.^4);
end