Skip to content

Commit b23cdcc

Browse files
committed
Implement traits
1 parent 801464d commit b23cdcc

File tree

3 files changed

+68
-4
lines changed

3 files changed

+68
-4
lines changed

src/solver.jl

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export AbstractSolver, solve!, parameters
1+
export AbstractSolver, solve!, parameters, are_valid_parameters
22

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

4545
parameters(::Type{S}) where S <: AbstractSolver = parameters(S{Float64})
46-
parameters(solver :: AbstractSolver) = parameters(typeof(solver))
46+
parameters(::S) where S <: AbstractSolver = parameters(S)
47+
48+
"""
49+
are_valid_parameters(solver, args...)
50+
51+
Return whether the parameters given in `args` are valid for `solver`.
52+
The order of the parameters must be the same as in `parameters(solver)`.
53+
"""
54+
function are_valid_parameters(::Type{AbstractSolver}, args...) end
55+
are_valid_parameters(::S) where S <: AbstractSolver = are_valid_parameters(S)

src/traits.jl

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
export problem_types_handled, can_solve_type
2+
3+
"""
4+
problem_types_handled(solver)
5+
6+
List the problem types handled by the `solver`.
7+
"""
8+
problem_types_handled(::Type{<:AbstractSolver}) = []
9+
10+
11+
"""
12+
can_solve_type(solver, type)
13+
14+
Check if the `solver` can solve problems of `type`.
15+
Call `problem_types_handled` for a list of problem types that the `solver` can solve.
16+
"""
17+
function can_solve_type(::Type{S}, t :: Symbol) where S <: AbstractSolver
18+
return t problem_types_handled(S)
19+
end
20+
21+
# Optimization
22+
const opt_problem_type = [:unc, :bnd, :equ, :bndequ, :ineq, :genopt]
23+
24+
# I was hoping to add these to the metaprogramming code below, but failed
25+
can_solve_unc(::Type{S}) where S <: AbstractSolver = can_solve_type(S, :unc)
26+
can_solve_bnd(::Type{S}) where S <: AbstractSolver = can_solve_type(S, :bnd)
27+
can_solve_equ(::Type{S}) where S <: AbstractSolver = can_solve_type(S, :equ)
28+
can_solve_bndequ(::Type{S}) where S <: AbstractSolver = can_solve_type(S, :bndequ)
29+
can_solve_ineq(::Type{S}) where S <: AbstractSolver = can_solve_type(S, :ineq)
30+
can_solve_optgen(::Type{S}) where S <: AbstractSolver = can_solve_type(S, :optgen)
31+
32+
for ptype in opt_problem_type
33+
fname = Symbol("can_solve_$ptype")
34+
help = """
35+
$fname(solver)
36+
37+
Check if the `solve` can solve optimization problems of type `$ptype`.
38+
Call `problem_types_handled` for a list of problem types that the `solver` can solve.
39+
"""
40+
@eval begin
41+
@doc $help $fname
42+
export $fname
43+
end
44+
end
45+
46+
# Linear System
47+
const linear_problem_type = [:sym, :sqd, :gen, :lst_sqr, :lst_norm]
48+
49+
# Same...

test/dummy_solver.jl

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,20 @@ mutable struct DummySolver{T} <: AbstractOptSolver{T}
44
workspace
55
end
66

7+
SolverCore.problem_types_handled(::Type{DummySolver}) = [:unc, :bnd, :equ, :bndequ, :ineq, :genopt]
8+
79
function SolverCore.parameters(::Type{DummySolver{T}}) where T
810
(
911
α = (default=T(1e-2), type=:log, min=√√eps(T), max=one(T) / 2),
12+
β = (default=T(1e-2), type=:log, min=√√eps(T), max=one(T) / 2),
1013
δ = (default=eps(T), type=:log, min=eps(T), max=√√√eps(T)),
1114
reboot_y = (default=false, type=:bool),
1215
)
1316
end
1417

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

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

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

0 commit comments

Comments
 (0)