Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement traits
Browse files Browse the repository at this point in the history
abelsiqueira committed Apr 6, 2021
1 parent 801464d commit b23cdcc
Showing 3 changed files with 68 additions and 4 deletions.
13 changes: 11 additions & 2 deletions src/solver.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export AbstractSolver, solve!, parameters
export AbstractSolver, solve!, parameters, are_valid_parameters

"""
AbstractSolver
@@ -43,4 +43,13 @@ Each key of `named_tuple` is the name of a parameter, and its value is a NamedTu
function parameters(::Type{AbstractSolver{T}}) where T end

parameters(::Type{S}) where S <: AbstractSolver = parameters(S{Float64})
parameters(solver :: AbstractSolver) = parameters(typeof(solver))
parameters(::S) where S <: AbstractSolver = parameters(S)

"""
are_valid_parameters(solver, args...)
Return whether the parameters given in `args` are valid for `solver`.
The order of the parameters must be the same as in `parameters(solver)`.
"""
function are_valid_parameters(::Type{AbstractSolver}, args...) end
are_valid_parameters(::S) where S <: AbstractSolver = are_valid_parameters(S)
49 changes: 49 additions & 0 deletions src/traits.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
export problem_types_handled, can_solve_type

"""
problem_types_handled(solver)
List the problem types handled by the `solver`.
"""
problem_types_handled(::Type{<:AbstractSolver}) = []


"""
can_solve_type(solver, type)
Check if the `solver` can solve problems of `type`.
Call `problem_types_handled` for a list of problem types that the `solver` can solve.
"""
function can_solve_type(::Type{S}, t :: Symbol) where S <: AbstractSolver
return t problem_types_handled(S)
end

# Optimization
const opt_problem_type = [:unc, :bnd, :equ, :bndequ, :ineq, :genopt]

# I was hoping to add these to the metaprogramming code below, but failed
can_solve_unc(::Type{S}) where S <: AbstractSolver = can_solve_type(S, :unc)
can_solve_bnd(::Type{S}) where S <: AbstractSolver = can_solve_type(S, :bnd)
can_solve_equ(::Type{S}) where S <: AbstractSolver = can_solve_type(S, :equ)
can_solve_bndequ(::Type{S}) where S <: AbstractSolver = can_solve_type(S, :bndequ)
can_solve_ineq(::Type{S}) where S <: AbstractSolver = can_solve_type(S, :ineq)
can_solve_optgen(::Type{S}) where S <: AbstractSolver = can_solve_type(S, :optgen)

for ptype in opt_problem_type
fname = Symbol("can_solve_$ptype")
help = """
$fname(solver)
Check if the `solve` can solve optimization problems of type `$ptype`.
Call `problem_types_handled` for a list of problem types that the `solver` can solve.
"""
@eval begin
@doc $help $fname
export $fname
end
end

# Linear System
const linear_problem_type = [:sym, :sqd, :gen, :lst_sqr, :lst_norm]

# Same...
10 changes: 8 additions & 2 deletions test/dummy_solver.jl
Original file line number Diff line number Diff line change
@@ -4,15 +4,20 @@ mutable struct DummySolver{T} <: AbstractOptSolver{T}
workspace
end

SolverCore.problem_types_handled(::Type{DummySolver}) = [:unc, :bnd, :equ, :bndequ, :ineq, :genopt]

function SolverCore.parameters(::Type{DummySolver{T}}) where T
(
α = (default=T(1e-2), type=:log, min=√√eps(T), max=one(T) / 2),
β = (default=T(1e-2), type=:log, min=√√eps(T), max=one(T) / 2),
δ = (default=eps(T), type=:log, min=eps(T), max=√√√eps(T)),
reboot_y = (default=false, type=:bool),
)
end

# function for validating given parameters. Instead of using constraints.
function SolverCore.are_valid_parameters(::Type{DummySolver}, α, β, δ, reboot_y)
return α + β 0.5
end

function DummySolver(::Type{T}, meta :: AbstractNLPModelMeta; kwargs...) where T
nvar, ncon = meta.nvar, meta.ncon
@@ -50,6 +55,7 @@ function SolverCore.solve!(solver::DummySolver{T}, nlp :: AbstractNLPModel;
solver.params[k] = v
end
α = solver.params[]
β = solver.params[]
δ = solver.params[]
reboot_y = solver.params[:reboot_y]

@@ -96,7 +102,7 @@ function SolverCore.solve!(solver::DummySolver{T}, nlp :: AbstractNLPModel;
ft = obj(nlp, xt)
slope = -dot(Δx, Hxy, Δx) - norm(AΔx)^2 / δ
t = 1.0
while !(ϕ(ft, ct, y) ϕx + α * t * slope)
while !(ϕ(ft, ct, y) ϕx + + β) * t * slope)
t /= 2
xt .= x + t * Δx
if ncon > 0

0 comments on commit b23cdcc

Please sign in to comment.