-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Second order correction #8
base: master
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -1,28 +1,24 @@ | ||||||||||||||||||||||
module SQP | ||||||||||||||||||||||
|
||||||||||||||||||||||
module SQP | ||||||||||||||||||||||
|
||||||||||||||||||||||
export sqp | ||||||||||||||||||||||
|
||||||||||||||||||||||
|
||||||||||||||||||||||
using LinearAlgebra | ||||||||||||||||||||||
using Krylov | ||||||||||||||||||||||
using NLPModels | ||||||||||||||||||||||
using SolverTools | ||||||||||||||||||||||
using JSOSolvers | ||||||||||||||||||||||
|
||||||||||||||||||||||
|
||||||||||||||||||||||
function sqp(nlp :: AbstractNLPModel; | ||||||||||||||||||||||
x :: AbstractVector = copy(nlp.meta.x0), | ||||||||||||||||||||||
atol :: Real = sqrt(eps(eltype(x))), | ||||||||||||||||||||||
rtol :: Real = sqrt(eps(eltype(x))), | ||||||||||||||||||||||
max_eval :: Int = -1, | ||||||||||||||||||||||
max_iter :: Int = 25, | ||||||||||||||||||||||
max_iter :: Int = 1000, | ||||||||||||||||||||||
max_time :: Float64 = 30.0, | ||||||||||||||||||||||
relax_param :: Float64 = 0.6, | ||||||||||||||||||||||
trust_reg :: Float64 = 1.0, | ||||||||||||||||||||||
μ0 :: Float64 = 1.0) | ||||||||||||||||||||||
|
||||||||||||||||||||||
|
||||||||||||||||||||||
if bound_constrained(nlp) | ||||||||||||||||||||||
return tron(nlp, x = copy(nlp.meta.x0), max_time = max_time, atol = atol, rtol = rtol, max_eval = max_eval) | ||||||||||||||||||||||
end | ||||||||||||||||||||||
|
@@ -39,21 +35,19 @@ function sqp(nlp :: AbstractNLPModel; | |||||||||||||||||||||
start_time = time() | ||||||||||||||||||||||
n = nlp.meta.nvar | ||||||||||||||||||||||
m = nlp.meta.ncon | ||||||||||||||||||||||
y = copy(nlp.meta.y0) | ||||||||||||||||||||||
fx = obj(nlp, x) | ||||||||||||||||||||||
cx = cons(nlp, x) - nlp.meta.ucon | ||||||||||||||||||||||
gx = grad(nlp, x) | ||||||||||||||||||||||
A = jac(nlp, x) | ||||||||||||||||||||||
LSMR_dual = lsmr(A', gx) | ||||||||||||||||||||||
y = LSMR_dual[1] | ||||||||||||||||||||||
maior_y = norm(y, Inf) | ||||||||||||||||||||||
W = Symmetric(hess(nlp, x, y), :L) | ||||||||||||||||||||||
Z = nullspace(Matrix(A)) | ||||||||||||||||||||||
norm_cx = norm(cx) | ||||||||||||||||||||||
tr = TrustRegion(trust_reg) | ||||||||||||||||||||||
ρ = 0.0 | ||||||||||||||||||||||
μ = μ0 | ||||||||||||||||||||||
last_accepted_μ = μ0 # for the first iteration | ||||||||||||||||||||||
last_accepted_norm_c = norm_cx | ||||||||||||||||||||||
last_rejected = false # the information from the last two steps is needed for the μ update | ||||||||||||||||||||||
last_but_one_rejected = false | ||||||||||||||||||||||
|
||||||||||||||||||||||
exitflag = :unknow | ||||||||||||||||||||||
dual = A'*y - gx | ||||||||||||||||||||||
|
@@ -65,7 +59,7 @@ function sqp(nlp :: AbstractNLPModel; | |||||||||||||||||||||
Δt = time() - start_time | ||||||||||||||||||||||
tired = Δt > max_time || iter > max_iter || neval_obj(nlp) > max_eval > 0 | ||||||||||||||||||||||
if tired | ||||||||||||||||||||||
if Δt > max_time | ||||||||||||||||||||||
if Δt > max_time | ||||||||||||||||||||||
exitflag = :max_time | ||||||||||||||||||||||
elseif iter > max_iter | ||||||||||||||||||||||
exitflag = :max_iter | ||||||||||||||||||||||
|
@@ -78,91 +72,93 @@ function sqp(nlp :: AbstractNLPModel; | |||||||||||||||||||||
@info log_row(Any[iter, Δt, normdual, norm_cx, tr.radius, ρ]) | ||||||||||||||||||||||
|
||||||||||||||||||||||
while !(success || tired) | ||||||||||||||||||||||
v = lsmr(A, -cx, radius = relax_param * tr.radius, atol = atol, rtol = rtol, itmax = max(2 * n, 50))[1] | ||||||||||||||||||||||
ZWZ = Z' * W * Z | ||||||||||||||||||||||
LSMR = lsmr(A, -cx, radius = relax_param * tr.radius, atol = atol, rtol = rtol, itmax = max(2 * n, 50)) | ||||||||||||||||||||||
v = LSMR[1] | ||||||||||||||||||||||
ZWZ = Z' * W * Z | ||||||||||||||||||||||
ZWv = Z' * (W*v + gx) | ||||||||||||||||||||||
u = cg(ZWZ, -ZWv, radius = sqrt(tr.radius^2 - norm(v)^2), atol = atol, rtol = 0.0, itmax = max(2 * n, 50))[1] | ||||||||||||||||||||||
Zu = Z * u | ||||||||||||||||||||||
CG = cg(ZWZ, -ZWv, radius = sqrt(tr.radius^2 - norm(v)^2), atol = atol, rtol= 0.0, itmax = max(2 * n, 50)) | ||||||||||||||||||||||
u = CG[1] | ||||||||||||||||||||||
Zu = Z * u | ||||||||||||||||||||||
d = v + Zu | ||||||||||||||||||||||
norm_v = norm(v) | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||
|
||||||||||||||||||||||
next_x = x + d | ||||||||||||||||||||||
next_f = obj(nlp, next_x) | ||||||||||||||||||||||
next_c = cons(nlp, next_x) - nlp.meta.ucon | ||||||||||||||||||||||
next_norm_c = norm(next_c) | ||||||||||||||||||||||
next_norm_c = norm(next_c, 1) | ||||||||||||||||||||||
vpred = norm_cx - norm(A*v + cx) | ||||||||||||||||||||||
upred = 0.5 * (u'*ZWZ*u)[1] + dot(ZWv,u) | ||||||||||||||||||||||
μ_bar = 0.1 + upred / vpred # auxiliary variable for μ update | ||||||||||||||||||||||
|
||||||||||||||||||||||
μ_plus = max(μ, μ_bar) # another auxiliary variable | ||||||||||||||||||||||
if μ_plus > μ && μ_plus < 5 * μ && μ > last_accepted_μ && norm_cx > 0.2 * last_accepted_norm_c && (last_rejected || last_but_one_rejected) | ||||||||||||||||||||||
μ_plus = min(5 * μ, μ_plus + 25 * (μ_plus - last_accepted_μ)) | ||||||||||||||||||||||
end | ||||||||||||||||||||||
if μ_plus == μ && norm(v) < relax_param * tr.radius/10 && norm_cx < 1e4 * atol | ||||||||||||||||||||||
μ_plus = max(μ0, μ_bar, norm(y)) | ||||||||||||||||||||||
D = dot(d, gx) | ||||||||||||||||||||||
dWd = (d'*W*d)[1] | ||||||||||||||||||||||
dpred = 0.5 * dWd + D | ||||||||||||||||||||||
|
||||||||||||||||||||||
μ_bar = maior_y + 0.1 | ||||||||||||||||||||||
if(dWd >= 0) | ||||||||||||||||||||||
if(μ > μ_bar) | ||||||||||||||||||||||
μ_plus = μ | ||||||||||||||||||||||
else | ||||||||||||||||||||||
μ_plus = μ_bar | ||||||||||||||||||||||
end | ||||||||||||||||||||||
else | ||||||||||||||||||||||
μ_plus = μ_bar - dWd / norm_cx | ||||||||||||||||||||||
end | ||||||||||||||||||||||
|
||||||||||||||||||||||
#ϕ(x) = obj(nlp, x) + μ_plus * norm(cons(nlp, x)) | ||||||||||||||||||||||
#nlp_aux = ADNLPModel(ϕ, x) | ||||||||||||||||||||||
ϕx = fx + μ_plus * norm_cx | ||||||||||||||||||||||
ϕn = next_f + μ_plus * next_norm_c | ||||||||||||||||||||||
Δm = μ * vpred - upred | ||||||||||||||||||||||
μ = max(μ_plus, dpred / (0.7 * vpred) + 0.1) | ||||||||||||||||||||||
|
||||||||||||||||||||||
ϕx = fx + μ * norm_cx | ||||||||||||||||||||||
ϕn = next_f + μ * next_norm_c | ||||||||||||||||||||||
Δm = μ * vpred - dpred | ||||||||||||||||||||||
μ_norm_cx = μ * norm_cx | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||
|
||||||||||||||||||||||
ared, pred = aredpred(nlp, ϕn, ϕx, Δm, next_x, d, dot(d, gx) - μ_plus * norm_cx) | ||||||||||||||||||||||
ared, pred = aredpred(nlp, ϕn, ϕx, Δm, next_x, d, D - μ_norm_cx) | ||||||||||||||||||||||
ρ = ared / pred | ||||||||||||||||||||||
set_property!(tr, :ratio, ρ) | ||||||||||||||||||||||
|
||||||||||||||||||||||
norm_v = norm(v) | ||||||||||||||||||||||
norm_Zu = norm(Zu) | ||||||||||||||||||||||
|
||||||||||||||||||||||
|
||||||||||||||||||||||
if acceptable(tr) | ||||||||||||||||||||||
x = next_x | ||||||||||||||||||||||
fx = next_f | ||||||||||||||||||||||
cx = next_c | ||||||||||||||||||||||
norm_cx = next_norm_c | ||||||||||||||||||||||
A = jac(nlp, x) | ||||||||||||||||||||||
gx = grad(nlp, x) | ||||||||||||||||||||||
y = lsmr(A', gx)[1] | ||||||||||||||||||||||
W = Symmetric(hess(nlp, x, y), :L) | ||||||||||||||||||||||
Z = nullspace(Matrix(A)) | ||||||||||||||||||||||
last_but_one_rejected = last_rejected | ||||||||||||||||||||||
last_rejected = false | ||||||||||||||||||||||
last_accepted_μ = μ | ||||||||||||||||||||||
last_accepted_norm_c = norm_cx | ||||||||||||||||||||||
elseif norm_v < 0.8 * relax_param * tr.radius && norm_v < 0.1 * norm_Zu | ||||||||||||||||||||||
aux_sist = cg(A*A', next_c)[1] | ||||||||||||||||||||||
d -= A'*aux_sist | ||||||||||||||||||||||
next_x = x + d | ||||||||||||||||||||||
next_f = obj(nlp, next_x) | ||||||||||||||||||||||
next_cx = cons(nlp, next_x) - nlp.meta.ucon | ||||||||||||||||||||||
next_norm_c = norm(next_cx) | ||||||||||||||||||||||
ϕx = fx + μ_plus * norm_cx | ||||||||||||||||||||||
ϕn = next_f + μ_plus * next_norm_c | ||||||||||||||||||||||
Δm = μ * vpred - upred | ||||||||||||||||||||||
ared, pred = aredpred(nlp, ϕn, ϕx, Δm, next_x, d, dot(d, gx) - μ_plus * norm_cx) | ||||||||||||||||||||||
ρ = ared / pred | ||||||||||||||||||||||
set_property!(tr, :ratio, ρ) | ||||||||||||||||||||||
x = next_x | ||||||||||||||||||||||
fx = next_f | ||||||||||||||||||||||
cx = next_c | ||||||||||||||||||||||
norm_cx = next_norm_c | ||||||||||||||||||||||
A = jac(nlp, x) | ||||||||||||||||||||||
gx = grad(nlp, x) | ||||||||||||||||||||||
y = lsmr(A', gx)[1] | ||||||||||||||||||||||
W = Symmetric(hess(nlp, x, y), :L) | ||||||||||||||||||||||
Z = nullspace(Matrix(A)) | ||||||||||||||||||||||
last_but_one_rejected = last_rejected | ||||||||||||||||||||||
last_rejected = false | ||||||||||||||||||||||
last_accepted_μ = μ | ||||||||||||||||||||||
last_accepted_norm_c = norm_cx | ||||||||||||||||||||||
else | ||||||||||||||||||||||
last_but_one_rejected = last_rejected | ||||||||||||||||||||||
last_rejected = true | ||||||||||||||||||||||
normv = norm(v) | ||||||||||||||||||||||
normu = norm(Zu) | ||||||||||||||||||||||
|
||||||||||||||||||||||
if acceptable(tr) | ||||||||||||||||||||||
x = next_x | ||||||||||||||||||||||
fx = next_f | ||||||||||||||||||||||
cx = next_c | ||||||||||||||||||||||
norm_cx = next_norm_c | ||||||||||||||||||||||
A = jac(nlp, x) | ||||||||||||||||||||||
gx = grad(nlp, x) | ||||||||||||||||||||||
LSMR_dual = lsmr(A', gx) | ||||||||||||||||||||||
y = LSMR_dual[1] | ||||||||||||||||||||||
W = Symmetric(hess(nlp, x, y), :L) | ||||||||||||||||||||||
Z = nullspace(Matrix(A)) | ||||||||||||||||||||||
elseif (normv <= 0.1 * normu) && (normv <= 0.8 * relax_param * tr.radius) | ||||||||||||||||||||||
LSMR_aux = lsmr(A, next_c, atol = atol, rtol = rtol) | ||||||||||||||||||||||
w = LSMR_aux[1] | ||||||||||||||||||||||
d_soc = d + w | ||||||||||||||||||||||
next_x = x + d_soc | ||||||||||||||||||||||
next_f = obj(nlp, next_x) | ||||||||||||||||||||||
next_cx = cons(nlp, next_x) - nlp.meta.ucon | ||||||||||||||||||||||
next_norm_c = norm(next_cx) | ||||||||||||||||||||||
ϕx = fx + μ * norm_cx | ||||||||||||||||||||||
ϕn = next_f + μ * next_norm_c | ||||||||||||||||||||||
D = dot(d_soc, gx) | ||||||||||||||||||||||
Δm = μ * (norm_cx - norm(A*d_soc + cx)) - 0.5 * (d_soc'*W*d_soc)[1] - D | ||||||||||||||||||||||
|
||||||||||||||||||||||
ared, pred = aredpred(nlp, ϕn, ϕx, Δm, next_x, d, D - μ_norm_cx) | ||||||||||||||||||||||
ρ = ared / pred | ||||||||||||||||||||||
set_property!(tr, :ratio, ρ) | ||||||||||||||||||||||
|
||||||||||||||||||||||
if acceptable(tr) | ||||||||||||||||||||||
x = next_x | ||||||||||||||||||||||
fx = next_f | ||||||||||||||||||||||
cx = next_c | ||||||||||||||||||||||
norm_cx = next_norm_c | ||||||||||||||||||||||
A = jac(nlp, x) | ||||||||||||||||||||||
gx = grad(nlp, x) | ||||||||||||||||||||||
LSMR_dual = lsmr(A', gx) | ||||||||||||||||||||||
y = LSMR_dual[1] | ||||||||||||||||||||||
W = Symmetric(hess(nlp, x, y), :L) | ||||||||||||||||||||||
Z = nullspace(Matrix(A)) | ||||||||||||||||||||||
end | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Diversos lugares acima. Por favor use um editor que permite a substituição de TAB por espaços ou faça manualmente. |
||||||||||||||||||||||
end | ||||||||||||||||||||||
|
||||||||||||||||||||||
μ = μ_plus | ||||||||||||||||||||||
|
||||||||||||||||||||||
update!(tr, norm(d)) | ||||||||||||||||||||||
|
||||||||||||||||||||||
update!(tr, norm(d, 2)) | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Por padrão é a 2. |
||||||||||||||||||||||
|
||||||||||||||||||||||
dual = A'*y - gx | ||||||||||||||||||||||
normdual = norm(dual) | ||||||||||||||||||||||
|
@@ -184,14 +180,11 @@ function sqp(nlp :: AbstractNLPModel; | |||||||||||||||||||||
end | ||||||||||||||||||||||
|
||||||||||||||||||||||
@info log_row(Any[iter, Δt, normdual, norm_cx, tr.radius, ρ]) | ||||||||||||||||||||||
|
||||||||||||||||||||||
end | ||||||||||||||||||||||
|
||||||||||||||||||||||
cx = cx + nlp.meta.ucon | ||||||||||||||||||||||
|
||||||||||||||||||||||
return GenericExecutionStats(exitflag, nlp, solution = x, objective = fx, dual_feas = normdual, primal_feas = norm_cx, iter = iter, elapsed_time = Δt) | ||||||||||||||||||||||
|
||||||||||||||||||||||
end | ||||||||||||||||||||||
|
||||||||||||||||||||||
|
||||||||||||||||||||||
end # module |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.