77 dual_optimizer(
88 optimizer_constructor;
99 coefficient_type::Type{T} = Float64,
10+ with_cache_type::Union{Nothing,Type{T}} = coefficient_type,
11+ with_bridge_type::Union{Nothing,Type{T}} = coefficient_type,
1012 kwargs...,
1113 ) where {T<:Number}
1214
1315A user-friendly constructor for [`DualOptimizer`](@ref) that can be passed
1416directly to the JuMP `Model` constructor.
1517
18+ By default, the optimizer is wrapped in both a cache and a bridging layer. To
19+ disable the bridge, to `with_bridge_type = nothing`.
20+
1621## Example
1722
1823```julia
1924julia> using Dualization, JuMP, HiGHS
2025
21- julia> model = Model(dual_optimizer(HiGHS.Optimizer))
26+ julia> model = Model(dual_optimizer(HiGHS.Optimizer; with_bridge_type = false ))
2227A JuMP Model
2328Feasibility problem with:
2429Variables: 0
@@ -28,46 +33,45 @@ Solver name: Dual model with HiGHS attached
2833```
2934"""
3035function dual_optimizer (
31- optimizer_constructor ;
36+ optimizer_fn ;
3237 coefficient_type:: Type{T} = Float64,
38+ with_cache_type:: Union{Nothing,Type{T}} = coefficient_type,
39+ with_bridge_type:: Union{Nothing,Type{T}} = coefficient_type,
3340 kwargs... ,
3441) where {T<: Number }
35- return () ->
36- DualOptimizer {T} (MOI. instantiate (optimizer_constructor); kwargs... )
37- end
38-
39- struct DualOptimizer{T,OT<: MOI.ModelLike } <: MOI.AbstractOptimizer
40- dual_problem:: DualProblem{T,OT}
41- assume_min_if_feasibility:: Bool
42-
43- function DualOptimizer {T,OT} (
44- dual_problem:: DualProblem{T,OT} ;
45- assume_min_if_feasibility:: Bool = false ,
46- ) where {T,OT<: MOI.ModelLike }
47- return new {T,OT} (dual_problem, assume_min_if_feasibility)
42+ return () -> begin
43+ inner = MOI. instantiate (optimizer_fn; with_cache_type, with_bridge_type)
44+ return DualOptimizer {T} (inner; kwargs... )
4845 end
4946end
5047
5148"""
52- DualOptimizer(dual_optimizer::OT ) where {OT <: MOI.ModelLike }
49+ DualOptimizer{T} (dual_optimizer::MOI.ModelLike; kwargs... ) where {T }
5350
54- The DualOptimizer finds the solution for a problem by solving its dual
55- representation. It builds the dual model internally and solve it using the
56- `dual_optimizer` as the solver.
51+ Construct a new `DualOptimizer <: MOI.AbstractOptimizer` that finds the solution
52+ for a problem by solving its dual representation. It builds the dual model
53+ internally and solves it using the `dual_optimizer` as the solver.
5754
5855Primal results are obtained by querying dual results of the internal problem
5956solved by `dual_optimizer`. Analogously, dual results are obtained by querying
6057primal results of the internal problem.
6158
62- The user can define the model providing the `DualOptimizer` and the solver of
63- its choice.
59+ ## Keyword arguments
60+
61+ * `assume_min_if_feasibility::Bool = false`: if `true`, treat
62+ `MOI.FEASIBILITY_SENSE` as `MOI.MIN_SENSE` with a zero objective function.
6463
6564## Example
6665
6766```julia
6867julia> using Dualization, JuMP, HiGHS
6968
70- julia> model = Model(dual_optimizer(HiGHS.Optimizer))
69+ julia> model = JuMP.Model() do
70+ return Dualization.DualOptimizer(
71+ HiGHS.Optimizer();
72+ assume_min_if_feasibility = true,
73+ )
74+ end
7175A JuMP Model
7276Feasibility problem with:
7377Variables: 0
@@ -76,27 +80,24 @@ CachingOptimizer state: EMPTY_OPTIMIZER
7680Solver name: Dual model with HiGHS attached
7781```
7882"""
79- function DualOptimizer (dual_optimizer:: OT ; kwargs... ) where {OT<: MOI.ModelLike }
80- return DualOptimizer {Float64} (dual_optimizer; kwargs... )
83+ struct DualOptimizer{T,OT<: MOI.ModelLike } <: MOI.AbstractOptimizer
84+ dual_problem:: DualProblem{T,OT}
85+ assume_min_if_feasibility:: Bool
86+
87+ function DualOptimizer {T,OT} (
88+ dual_problem:: DualProblem{T,OT} ;
89+ assume_min_if_feasibility:: Bool = false ,
90+ ) where {T,OT<: MOI.ModelLike }
91+ return new {T,OT} (dual_problem, assume_min_if_feasibility)
92+ end
8193end
8294
83- function DualOptimizer {T} (
84- dual_optimizer:: OT ;
85- kwargs... ,
86- ) where {T,OT<: MOI.ModelLike }
87- dual_problem = DualProblem {T} (
88- MOI. Bridges. full_bridge_optimizer (
89- MOI. Utilities. CachingOptimizer (
90- MOI. Utilities. UniversalFallback (MOI. Utilities. Model {T} ()),
91- dual_optimizer,
92- ),
93- T,
94- ),
95- )
96- # discover the type of
97- # MOI.Utilities.CachingOptimizer(MOI.Utilities.Model{T}(), dual_optimizer)
98- OptimizerType = typeof (dual_problem. dual_model)
99- return DualOptimizer {T,OptimizerType} (dual_problem; kwargs... )
95+ function DualOptimizer {T} (optimizer:: OT ; kwargs... ) where {T,OT<: MOI.ModelLike }
96+ return DualOptimizer {T,OT} (DualProblem {T} (optimizer); kwargs... )
97+ end
98+
99+ function DualOptimizer (optimizer:: MOI.ModelLike ; kwargs... )
100+ return DualOptimizer {Float64} (optimizer; kwargs... )
100101end
101102
102103DualOptimizer () = error (" DualOptimizer must have a solver attached" )
0 commit comments