From 65c8842e835d6eda0f570a29ef2122953d9d9d92 Mon Sep 17 00:00:00 2001 From: elvis Date: Thu, 30 Nov 2023 15:24:11 +0100 Subject: [PATCH] fixes --- 11-09/NWTN.jl | 62 ++++++++++++++-------------- 11-09/TestFunctions/TestFunctions.jl | 12 +++--- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/11-09/NWTN.jl b/11-09/NWTN.jl index 80742e6..5165eb1 100644 --- a/11-09/NWTN.jl +++ b/11-09/NWTN.jl @@ -34,10 +34,10 @@ function NWTN(f; # # saves the point in lastx, the gradient in lastg, the Hessian in lasth, # and increases feval - + lastx = x + alpha * d phi, lastg, lastH = f(lastx) - + if Plotf > 2 if fStar > - Inf push!(gap, (phi - fStar) / max(abs(fStar), 1)) @@ -56,7 +56,7 @@ function NWTN(f; # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + function ArmijoWolfeLS(phi0, phip0, as, m1, m2, tau) # performs an Armijo-Wolfe Line Search. # @@ -70,12 +70,12 @@ function NWTN(f; # Wolfe condition is used # # returns the optimal step and the optimal f-value - + lsiter = 1 # count iterations of first phase local phips, phia - while feval ≤ MaxFeval + while feval ≤ MaxFeval phia, phips = f2phi(as, true) - + if (phia ≤ phi0 + m1 * as * phip0) && (abs(phips) ≤ - m2 * phip0) if printing @printf(" %2d", lsiter) @@ -88,29 +88,29 @@ function NWTN(f; end as = as / tau lsiter += 1 - end + end if printing @printf(" %2d ", lsiter) end lsiter = 1 # count iterations of second phase - + am = 0 a = as phipm = phip0 while (feval ≤ MaxFeval ) && (as - am) > mina && (phips > 1e-12) - + # compute the new value by safeguarded quadratic interpolation a = (am * phips - as * phipm) / (phips - phipm) a = max(am + ( as - am ) * sfgrd, min(as - ( as - am ) * sfgrd, a)) - + # compute phi(a) phia, phip = f2phi(a, true) if (phia ≤ phi0 + m1 * a * phip0) && (abs(phip) ≤ -m2 * phip0) break # Armijo + strong Wolfe satisfied, we are done end - + # restrict the interval based on sign of the derivative in a if phip < 0 am = a @@ -143,7 +143,7 @@ function NWTN(f; # m1 is satisfied # # returns the optimal step and the optimal f-value - + lsiter = 1 # count ls iterations while feval ≤ MaxFeval && as > mina phia, _ = f2phi(as) @@ -160,7 +160,7 @@ function NWTN(f; return (as, phia) end - + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -227,7 +227,7 @@ function NWTN(f; # "global" variables- - - - - - - - - - - - - - - - - - - - - - - - - - - - # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + lastx = zeros(n) # last point visited in the line search lastg = zeros(n) # gradient of lastx lastH = zeros(n, n) # Hessian of lastx @@ -235,7 +235,7 @@ function NWTN(f; feval = 0 # f() evaluations count ("common" with LSs) status = "error" - + # initializations - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -254,7 +254,7 @@ function NWTN(f; @printf("\n\n") end - + v, _ = f2phi(0) ng = norm(lastg) if eps < 0 @@ -269,7 +269,7 @@ function NWTN(f; while true # output statistics - - - - - - - - - - - - - - - - - - - - - - - - - - - + if fStar > -Inf gapk = (v - fStar) / max(abs(fStar), 1) @@ -282,7 +282,7 @@ function NWTN(f; end end prevv = v - + if Plotf > 1 if Plotf ≥ 2 push!(gap, gapk) @@ -292,7 +292,7 @@ function NWTN(f; if printing @printf("%4d\t%1.8e\t\t%1.4e", feval, v, ng) end - + if Plotf > 1 if Plotf ≥ 2 push!(gap, v) @@ -306,12 +306,12 @@ function NWTN(f; status = "optimal" break end - + if feval > MaxFeval status = "stopped" break end - + # compute Newton's direction- - - - - - - - - - - - - - - - - - - - - - lambdan = eigmin(lastH) # smallest eigenvalue @@ -327,45 +327,45 @@ function NWTN(f; end d = -lastH \ lastg phip0 = lastg' * d - + # compute step size - - - - - - - - - - - - - - - - - - - - - - - - - - # in Newton's method, the default initial stepsize is 1 - + if AWLS a, v = ArmijoWolfeLS(v, phip0, 1, m1, m2, tau) else a, v = BacktrackingLS(v, phip0, 1, m1, tau) end - + # output statistics - - - - - - - - - - - - - - - - - - - - - - - - - - if printing @printf("\t%1.2e", a) @printf("\n") end - + if a ≤ mina status = "error" break end - + if v ≤ MInf status = "unbounded" break end - + # compute new point - - - - - - - - - - - - - - - - - - - - - - - - - - - + # possibly plot the trajectory if n == 2 && Plotf == 1 PXY = hcat(PXY, hcat(x, lastx)) end - + x = lastx ng = norm(lastg) # iterate - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + if Interactive readline() end @@ -383,4 +383,4 @@ function NWTN(f; # end of main loop- - - - - - - - - - - - - - - - - - - - - - - - - - - - - # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - return (x, status) -end \ No newline at end of file +end diff --git a/11-09/TestFunctions/TestFunctions.jl b/11-09/TestFunctions/TestFunctions.jl index bb65a32..1dc14b3 100644 --- a/11-09/TestFunctions/TestFunctions.jl +++ b/11-09/TestFunctions/TestFunctions.jl @@ -307,16 +307,16 @@ function lasso(x::Union{Nothing, AbstractVecOrMat}) if isnothing(x) # informative call v = ( 2 - 1/3 )^2 + 10/9 # optimal solution [ 1/9 , 0 ] - return (v, [0, 0]) + return (v, [0., 0.], nothing) else - v = ( 3 * x( 1 ) + 2 * x( 2 ) - 2 )^2 + - 10 * ( abs( x( 1 ) ) + abs( x( 2 ) ) ) # f(x) + v = (3 * x[1] + 2 * x[2] - 2)^2 + + 10 * (abs(x[1]) + abs(x[2])) # f(x) g = zeros(2) - g[1] = 18 * x[1] + 12 * x[2] - 12 + 10 * sign( x[1] ) - g[2] = 12 * x[1] + 8 * x[2] - 8 + 10 * sign( x[2] ) + g[1] = 18 * x[1] + 12 * x[2] - 12 + 10 * sign(x[1]) + g[2] = 12 * x[1] + 8 * x[2] - 8 + 10 * sign(x[2]) - return (v, g) + return (v, g, nothing) end end # lasso