@@ -23,17 +23,115 @@ include("debug.jl")
23
23
"""
24
24
full_bridge_optimizer(model::MOI.ModelLike, ::Type{T}) where {T}
25
25
26
- Returns a `LazyBridgeOptimizer` bridging `model` for every bridge defined in
27
- this package and for the coefficient type `T`.
26
+ Returns a [`LazyBridgeOptimizer`](@ref) bridging `model` for every bridge
27
+ defined in this package (see below for the few exceptions) and for the
28
+ coefficient type `T` in addition to the bridges in the list returned by
29
+ `MOI.get(model, MOI.Bridges.ListOfNonstandardBridges{T}())`.
30
+
31
+ See also [`ListOfNonstandardBridges`](@ref).
32
+
33
+ !!! note
34
+ The following bridges are not added by `full_bridge_optimizer` except if
35
+ they are in the list returned by `MOI.get(model, MOI.Bridges.ListOfNonstandardBridges{T}())`
36
+ (see the docstrings of the corresponding bridge for the reason they are not
37
+ added):
38
+ * [`Constraint.SOCtoNonConvexQuadBridge`](@ref),
39
+ [`Constraint.RSOCtoNonConvexQuadBridge`](@ref) and
40
+ [`Constraint.SOCtoPSDBridge`](@ref).
41
+ * The subtypes of [`Constraint.AbstractToIntervalBridge`](@ref) (i.e.
42
+ [`Constraint.GreaterToIntervalBridge`](@ref) and
43
+ [`Constraint.LessToIntervalBridge`](@ref)) if `T` is not a subtype of
44
+ `AbstractFloat`.
28
45
"""
29
46
function full_bridge_optimizer (model:: MOI.ModelLike , :: Type{T} ) where {T}
30
47
bridged_model = LazyBridgeOptimizer (model)
48
+ for BT in MOI. get (model, ListOfNonstandardBridges {T} ())
49
+ add_bridge (bridged_model, BT)
50
+ end
31
51
Variable. add_all_bridges (bridged_model, T)
32
52
Constraint. add_all_bridges (bridged_model, T)
33
53
Objective. add_all_bridges (bridged_model, T)
34
54
return bridged_model
35
55
end
36
56
57
+ """
58
+ ListOfNonstandardBridges{T}() <: MOI.AbstractOptimizerAttribute
59
+
60
+ Any optimizer can be wrapped in a [`LazyBridgeOptimizer`](@ref) using
61
+ [`full_bridge_optimizer`](@ref). However, by default [`LazyBridgeOptimizer`](@ref)
62
+ uses a limited set of bridges that are:
63
+
64
+ 1. implemented in `MOI.Bridges`
65
+ 2. generally applicable for all optimizers.
66
+
67
+ For some optimizers however, it is useful to add additional bridges, such as
68
+ those that are implemented in external packages (e.g., within the solver package
69
+ itself) or only apply in certain circumstances (e.g.,
70
+ [`Constraint.SOCtoNonConvexQuadBridge`](@ref)).
71
+
72
+ Such optimizers should implement the `ListOfNonstandardBridges` attribute to
73
+ return a vector of bridge types that are added by [`full_bridge_optimizer`](@ref)
74
+ in addition to the list of default bridges.
75
+
76
+ Note that optimizers implementing `ListOfNonstandardBridges` may require
77
+ package-specific functions or sets to be used if the non-standard bridges
78
+ are not added. Therefore, you are recommended to use
79
+ `model = MOI.instantiate(Package.Optimizer; with_bridge_type = T)` instead of
80
+ `model = MOI.instantiate(Package.Optimizer)`. See
81
+ [`MathOptInterface.instantiate`](@ref).
82
+
83
+ ## Examples
84
+
85
+ ### An optimizer using a non-default bridge in `MOI.Bridges`
86
+
87
+ Solvers supporting [`MOI.ScalarQuadraticFunction`](@ref) can support
88
+ [`MOI.SecondOrderCone`](@ref) and [`MOI.RotatedSecondOrderCone`](@ref) by
89
+ defining:
90
+ ```julia
91
+ function MOI.get(::MyQuadraticOptimizer, ::ListOfNonstandardBridges{Float64})
92
+ return Type[
93
+ MOI.Bridges.Constraint.SOCtoNonConvexQuadBridge{Float64},
94
+ MOI.Bridges.Constraint.RSOCtoNonConvexQuadBridge{Float64},
95
+ ]
96
+ end
97
+ ```
98
+
99
+ ### An optimizer defining an internal bridge
100
+
101
+ Suppose an optimizer can exploit specific structure of a constraint, e.g., it
102
+ can exploit the structure of the matrix `A` in the linear system of equations
103
+ `A * x = b`.
104
+
105
+ The optimizer can define the function:
106
+ ```julia
107
+ struct MatrixAffineFunction{T} <: MOI.AbstractVectorFunction
108
+ A::SomeStructuredMatrixType{T}
109
+ b::Vector{T}
110
+ end
111
+ ```
112
+ and then a bridge
113
+ ```julia
114
+ struct MatrixAffineFunctionBridge{T} <: MOI.Constraint.AbstractBridge
115
+ # ...
116
+ end
117
+ # ...
118
+ ```
119
+ from `VectorAffineFunction{T}` to the `MatrixAffineFunction`. Finally, it
120
+ defines:
121
+ ```julia
122
+ function MOI.get(::Optimizer{T}, ::ListOfNonstandardBridges{T}) where {T}
123
+ return Type[MatrixAffineFunctionBridge{T}]
124
+ end
125
+ ```
126
+ """
127
+ struct ListOfNonstandardBridges{T} <: MOI.AbstractOptimizerAttribute end
128
+
129
+ attribute_value_type (:: ListOfNonstandardBridges ) = Vector{Type}
130
+
131
+ MOI. is_copyable (:: ListOfNonstandardBridges ) = false
132
+
133
+ MOI. get_fallback (model:: MOI.ModelLike , :: ListOfNonstandardBridges ) = Type[]
134
+
37
135
print_num_bridges (io:: IO , :: Variable.EmptyMap ) = nothing
38
136
39
137
print_num_bridges (io:: IO , :: Constraint.EmptyMap ) = nothing
0 commit comments