In [1]:
using Optim, Dates
include("printmat.jl")
Out[1]:
In [2]:
using Plots
#pyplot(size=(600,400))
gr(size=(480,320))
default(fmt = :svg)
Running
Sol = optimize(x->fn1(x,0.5),x₀,x₁)
finds the x
value (in the interval [x₀,x₁]
) that minimizes fn1(x,0.5)
. The solution for the fn1
function below should be $x=1.1$. The x->fn1(x,0.5)
syntax makes this a function of x
only.
The output (Sol
) contains a lot of information.
In [3]:
function fn1(x,c) #notice: the function has two arguments
value = 2*(x - 1.1)^2 - c
return value
end
Out[3]:
In [4]:
x = -1:0.1:3
plot( x,fn1.(x,0.5),
linecolor = :red,
linewidth = 2,
legend = nothing,
title = "the fn1(x,0.5) function",
xlabel = "x",
ylabel = "y" )
Out[4]:
In [5]:
Sol = optimize(x->fn1(x,0.5),-2.0,3.0)
println(Sol)
printlnPs("\nThe minimum is at: ", Optim.minimizer(Sol)) #the optimal x value
println("Compare with the plot above\n")
If you prefer to give a starting guess x₀
instead of an interval, then supply it as as a vector [x₀]
:
Sol = optimize(x->fn1(x[],0.5),[x₀],LBFGS())
Notice: (a) x[]
to make it a function of the first (and only) element in the vector x
; (b) choose the LBFGS()
method since the default method does not work in the case of only one choice variable.
In [6]:
Solb = optimize(x->fn1(x[],0.5),[0.1],LBFGS())
printlnPs("The minimum is at: ", Optim.minimizer(Solb))
In [7]:
function fn2(p)
(x,y) = (p[1],p[2]) #unpack the choice variables and get nicer names
L = (x-2)^2 + (4*y+3)^2
return L
end
Out[7]:
In [8]:
nx = 2*41
ny = 2*61
x = range(1,stop=5,length=nx)
y = range(-1,stop=0,length=ny)
loss2d = fill(NaN,(nx,ny)) #matrix with loss fn values
for i = 1:nx, j = 1:ny
loss2d[i,j] = fn2([x[i];y[j]])
end
In [9]:
contour( x,y,loss2d', #notice: loss2d'
xlims = (1,5),
ylims = (-1,0),
legend = false,
levels = 21,
title = "Contour plot of loss function",
xlabel = "x",
ylabel = "y" )
scatter!([2],[-0.75],label="optimum",legend=true)
Out[9]:
In [10]:
Sol = optimize(fn2,[0.0;0.0]) #use p->lossfn(p,other arguments) if
#there are additional (non-choice) arguments
printlnPs("minimum at (x,y)= ",Optim.minimizer(Sol))
In [11]:
contour( x,y,loss2d',
xlims = (1,5),
ylims = (-1,0),
legend = false,
levels = 21,
title = "Contour plot of loss function",
xlabel = "x",
ylabel = "y",
annotation = (3.5,-0.7,text("somewhere here",8)) )
plot!([2.75,2.75],[-1,0.5],color=:red,linewidth=2,label="2.75 < x",legend = true)
plot!([1,5],[-0.3,-0.3],color=:black,linewidth=2,label="y < -0.3")
scatter!([2.75],[-0.75],color=:red,label="optimum")
Out[11]:
In [12]:
lower = [2.75, -Inf]
upper = [Inf, -0.3]
Sol = optimize(fn2,lower,upper,[3.0,-0.5])
printlnPs("The optimum is at (x,y) = ",Optim.minimizer(Sol))
In [13]:
function g2(x) #derivatives of fn2 wrt. x[1] and x[2]
G = [2*(x[1]-2), 2*4(4*x[2]+3)] #creates a new vector: use inplace = false in optimize()
return G
end
Sol3 = optimize(fn2,g2,[1.0,-0.5],inplace=false)
println(Sol3)
In [ ]: