Skip to content

Commit

Permalink
formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
mohamed82008 committed Nov 16, 2023
1 parent 5454c4b commit db6f13a
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 51 deletions.
2 changes: 1 addition & 1 deletion src/aggregations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ getdim(::AbstractAggregation) = 1
@params struct NonNegSumOfSquares <: AbstractAggregation
c::Real
end
(f::NonNegSumOfSquares)(x::AbstractVector) = f.c * sum(max.(0, x).^2)
(f::NonNegSumOfSquares)(x::AbstractVector) = f.c * sum(max.(0, x) .^ 2)

@params struct NonNegSumOfRoots <: AbstractAggregation
c::Real
Expand Down
90 changes: 59 additions & 31 deletions src/algorithm.jl
Original file line number Diff line number Diff line change
@@ -1,24 +1,31 @@

@params struct AugLag2 <: AbstractOptimizer
primaloptimizer
dualoptimizer
primaloptimizer::Any
dualoptimizer::Any
end
function AugLag2(;
primaloptimizer = Optim.ConjugateGradient(linesearch=Optim.LineSearches.BackTracking(iterations = 10)),
dualoptimizer = Optim.GradientDescent(linesearch=Optim.LineSearches.BackTracking(iterations = 10)),
primaloptimizer = Optim.ConjugateGradient(
linesearch = Optim.LineSearches.BackTracking(iterations = 10),
),
dualoptimizer = Optim.GradientDescent(
linesearch = Optim.LineSearches.BackTracking(iterations = 10),
),
)
return AugLag2(primaloptimizer, dualoptimizer)
end

@params struct AugLag2Options
primaloptions
dualoptions
maxiter
tol
quadfactor
primaloptions::Any
dualoptions::Any
maxiter::Any
tol::Any
quadfactor::Any
end
function AugLag2Options(alg::AugLag2;
primaloptions = alg.primaloptimizer isa MMA02 || alg.primaloptimizer isa MMA87 ? MMAOptions(maxiter = 100, tol = Tolerance(kkt = 1e-4)) : Optim.Options(outer_iterations = 10, iterations = 10),
function AugLag2Options(
alg::AugLag2;
primaloptions = alg.primaloptimizer isa MMA02 || alg.primaloptimizer isa MMA87 ?
MMAOptions(maxiter = 100, tol = Tolerance(kkt = 1e-4)) :
Optim.Options(outer_iterations = 10, iterations = 10),
dualoptions = Optim.Options(outer_iterations = 10, iterations = 10),
maxiter = 10,
tol = Tolerance(),
Expand All @@ -35,7 +42,17 @@ function Solution(lagmodel::AugLag2Model)
λ = copy(getlinweights(lagmodel))
g = copy(λ)
convstate = ConvergenceState()
return Solution(prevx, x, getlinweights(lagmodel), prevf, f, nothing, g, nothing, convstate)
return Solution(
prevx,
x,
getlinweights(lagmodel),
prevf,
f,
nothing,
g,
nothing,
convstate,
)
end

@params mutable struct AugLag2Workspace <: Workspace
Expand All @@ -52,7 +69,7 @@ end
trace::Trace
outer_iter::Int
iter::Int
fcalls::Int
fcalls::Int
end
function AugLag2Workspace(
model::VecModel,
Expand All @@ -63,7 +80,11 @@ function AugLag2Workspace(
plot_trace::Bool = false,
show_plot::Bool = plot_trace,
save_plot = nothing,
callback::Function = plot_trace ? LazyPlottingCallback(; show_plot = show_plot, save_plot = save_plot) : NoCallback(),
callback::Function = plot_trace ?
LazyPlottingCallback(;
show_plot = show_plot,
save_plot = save_plot,
) : NoCallback(),
kwargs...,
)
T = eltype(x0)
Expand All @@ -85,19 +106,18 @@ function AugLag2Workspace(
x0,
optimizer,
options,

solution,
convcriteria,
callback,

trace,
outer_iter,
iter,
fcalls,
)
end

Workspace(model::VecModel, alg::AugLag2, x0::AbstractVector; kwargs...) = AugLag2Workspace(model, alg, x0; kwargs...)
Workspace(model::VecModel, alg::AugLag2, x0::AbstractVector; kwargs...) =
AugLag2Workspace(model, alg, x0; kwargs...)

function optimize!(workspace::AugLag2Workspace)
@unpack lagmodel, solution, options, convcriteria = workspace
Expand All @@ -117,18 +137,19 @@ function optimize!(workspace::AugLag2Workspace)

auglag = getobjective(lagmodel)

cb = (tr; kwargs...) -> begin
solution = deepcopy(solution)
solution.prevx .= solution.x
solution.x .= getx(lagmodel)
solution.λ .= getλ(lagmodel)
solution.prevf = solution.f
solution.f = getorigobjval(lagmodel)
solution.g .= getorigconstrval(lagmodel)
assess_convergence!(solution, lagmodel, options.tol, convcriteria)
callback(solution)
return hasconverged(solution)
end
cb =
(tr; kwargs...) -> begin
solution = deepcopy(solution)
solution.prevx .= solution.x
solution.x .= getx(lagmodel)
solution.λ .= getλ(lagmodel)
solution.prevf = solution.f
solution.f = getorigobjval(lagmodel)
solution.g .= getorigconstrval(lagmodel)
assess_convergence!(solution, lagmodel, options.tol, convcriteria)
callback(solution)
return hasconverged(solution)
end

primaloptimizerfunction(λ) = begin
setlinweights!(auglag, λ)
Expand All @@ -139,7 +160,14 @@ function optimize!(workspace::AugLag2Workspace)
primalmodel = Model()
addvar!(primalmodel, xl, xu)
set_objective!(primalmodel, getprimalobjective(auglag))
result = optimize(primalmodel, primaloptimizer, clamp.(getx(lagmodel), xl .+ 1e-3, xu .- 1e-3), options = primaloptions, callback = cb, convcriteria = KKTCriteria())
result = optimize(
primalmodel,
primaloptimizer,
clamp.(getx(lagmodel), xl .+ 1e-3, xu .- 1e-3),
options = primaloptions,
callback = cb,
convcriteria = KKTCriteria(),
)
fcalls += result.fcalls
else
primalobj = getoptimobj(getprimalobjective(auglag), true)
Expand Down Expand Up @@ -173,7 +201,7 @@ function optimize!(workspace::AugLag2Workspace)
λu = fill(Inf, ni)

# Solve the dual problem by minimizing negative the dual objective value
for i in 1:maxiter
for i = 1:maxiter
setquadweight!(lagmodel, min(getquadweight(lagmodel) * quadfactor, 1e10))
if debugging[]
@show getquadweight(lagmodel)
Expand Down
30 changes: 18 additions & 12 deletions src/model.jl
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ function (obj::AugLag2Obj)(x::AbstractVector, λ::AbstractVector; penalise = tru
savefg!(obj, origobjval, origconstrval)

linepenalty = dot(λ, origconstrval)
quadpenalty = penalise ? NonNegSumOfSquares(obj.quadweight[])(origconstrval) : zero(linepenalty)
quadpenalty =
penalise ? NonNegSumOfSquares(obj.quadweight[])(origconstrval) : zero(linepenalty)

return origobjval + linepenalty + quadpenalty
end
Expand All @@ -75,7 +76,8 @@ function (obj::AugLag2Obj)(primaloptimizer::Function, λ::AbstractVector; penali
savefg!(obj, origobjval, origconstrval)

linepenalty = dot(λ, origconstrval)
quadpenalty = penalise ? NonNegSumOfSquares(obj.quadweight[])(origconstrval) : zero(linepenalty)
quadpenalty =
penalise ? NonNegSumOfSquares(obj.quadweight[])(origconstrval) : zero(linepenalty)

return origobjval + linepenalty + quadpenalty
end
Expand All @@ -95,7 +97,11 @@ function savexλ!(obj::AugLag2Obj, x::AbstractVector, λ::AbstractVector)
setλ!(obj, λ)
return obj
end
ChainRulesCore.@non_differentiable savexλ!(obj::AugLag2Obj, x::AbstractVector, λ::AbstractVector)
ChainRulesCore.@non_differentiable savexλ!(
obj::AugLag2Obj,
x::AbstractVector,
λ::AbstractVector,
)

getparent(f::AugLag2Obj) = f.model

Expand Down Expand Up @@ -159,11 +165,8 @@ end
parent::VecModel
objective::AugLag2Obj
end
function AugLag2Model(
model::VecModel;
kwargs...,
)
return AugLag2Model(model, AugLag2Obj(model; kwargs...,))
function AugLag2Model(model::VecModel; kwargs...)
return AugLag2Model(model, AugLag2Obj(model; kwargs...))
end

getparent(model::AugLag2Model) = model.parent
Expand All @@ -174,11 +177,14 @@ getmax(model::AugLag2Model) = getmax(getparent(model))

getobjective(model::AugLag2Model) = model.objective

getineqconstraints(::AugLag2Model) = throw("`getineqconstraints` is not defined for `AugLag2Model`.")
getineqconstraints(::AugLag2Model) =
throw("`getineqconstraints` is not defined for `AugLag2Model`.")

geteqconstraints(::AugLag2Model) = throw("`geteqconstraints` is not defined for `AugLag2Model`.")
geteqconstraints(::AugLag2Model) =
throw("`geteqconstraints` is not defined for `AugLag2Model`.")

getobjectiveconstraints(::AugLag2Model) = throw("`getobjectiveconstraints` is not defined for `AugLag2Model`.")
getobjectiveconstraints(::AugLag2Model) =
throw("`getobjectiveconstraints` is not defined for `AugLag2Model`.")

getlinweights(model::AugLag2Model) = getlinweights(getobjective(model))

Expand Down Expand Up @@ -224,7 +230,7 @@ end

function getresiduals(solution::Solution, model::AugLag2Model, ::GenericCriteria)
@unpack prevx, x, prevf, f, g = solution
Δx = maximum(abs(x[j] - prevx[j]) for j in 1:length(x))
Δx = maximum(abs(x[j] - prevx[j]) for j = 1:length(x))
Δf = abs(f - prevf)
infeas = max(0, maximum(g))
return Δx, Δf, infeas
Expand Down
11 changes: 4 additions & 7 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,16 @@ using NonconvexAugLagLab
using Test, LinearAlgebra

f(x::AbstractVector) = sqrt(x[2])
g(x::AbstractVector, a, b) = (a*x[1] + b)^3 - x[2]
g(x::AbstractVector, a, b) = (a * x[1] + b)^3 - x[2]

m = Model(f)
addvar!(m, [1e-4, 1e-4], [10.0, 10.0])
add_ineq_constraint!(
m,
FunctionWrapper(x -> [g(x, 2, 0), g(x, -1, 1)], 2),
)
add_ineq_constraint!(m, FunctionWrapper(x -> [g(x, 2, 0), g(x, -1, 1)], 2))
x0 = [2.0, 2.0]

#alg = AugLag2(primaloptimizer = MMA87())
alg = AugLag2()
options = AugLag2Options(alg)
r = optimize(m, alg, x0, options = options)
@test abs(r.minimum - sqrt(8/27)) < 1e-4
@test norm(r.minimizer - [1/3, 8/27]) < 1e-4
@test abs(r.minimum - sqrt(8 / 27)) < 1e-4
@test norm(r.minimizer - [1 / 3, 8 / 27]) < 1e-4

0 comments on commit db6f13a

Please sign in to comment.