Skip to content

Commit 801a492

Browse files
authored
[Bridges] improvements to Variable bridge docstrings (#1864)
1 parent 94eb4e6 commit 801a492

File tree

7 files changed

+252
-146
lines changed

7 files changed

+252
-146
lines changed

docs/src/submodules/Bridges/reference.md

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -31,23 +31,11 @@ Bridges.debug_supports
3131
Bridges.bridged_variable_function
3232
Bridges.unbridged_variable_function
3333
Bridges.bridged_function
34-
Bridges.Variable.unbridged_map
35-
```
36-
37-
## Constraint bridges
38-
39-
```@docs
40-
Bridges.Constraint.AbstractBridge
41-
Bridges.Constraint.AbstractFunctionConversionBridge
42-
Bridges.Constraint.SingleBridgeOptimizer
43-
Bridges.Constraint.add_all_bridges
4434
```
4535

46-
### [SetMap bridges](@id constraint_set_map)
36+
### [SetMap API](@id constraint_set_map)
4737

4838
```@docs
49-
Bridges.Variable.SetMapBridge
50-
Bridges.Constraint.SetMapBridge
5139
Bridges.map_set
5240
Bridges.inverse_map_set
5341
Bridges.map_function
@@ -56,11 +44,21 @@ Bridges.adjoint_map_function
5644
Bridges.inverse_adjoint_map_function
5745
```
5846

59-
### [Bridges implemented](@id constraint_bridges_ref)
47+
## Constraint bridge API
6048

6149
```@docs
50+
Bridges.Constraint.AbstractBridge
51+
Bridges.Constraint.AbstractFunctionConversionBridge
52+
Bridges.Constraint.SingleBridgeOptimizer
53+
Bridges.Constraint.add_all_bridges
6254
Bridges.Constraint.FlipSignBridge
6355
Bridges.Constraint.AbstractToIntervalBridge
56+
Bridges.Constraint.SetMapBridge
57+
```
58+
59+
## [Constraint bridges implemented](@id constraint_bridges_ref)
60+
61+
```@docs
6462
Bridges.Constraint.GreaterToIntervalBridge
6563
Bridges.Constraint.LessToIntervalBridge
6664
Bridges.Constraint.GreaterToLessBridge
@@ -97,18 +95,20 @@ Bridges.Constraint.SemiToBinaryBridge
9795
Bridges.Constraint.ZeroOneBridge
9896
```
9997

100-
## [Variable bridges](@id ref_variable_bridges)
98+
## [Variable bridge API](@id ref_variable_bridges)
10199

102100
```@docs
103101
Bridges.Variable.AbstractBridge
104102
Bridges.Variable.SingleBridgeOptimizer
105103
Bridges.Variable.add_all_bridges
104+
Bridges.Variable.FlipSignBridge
105+
Bridges.Variable.SetMapBridge
106+
Bridges.Variable.unbridged_map
106107
```
107108

108-
### [Bridges implemented](@id variable_bridges_ref)
109+
## [Variable bridges implemented](@id variable_bridges_ref)
109110

110111
```@docs
111-
Bridges.Variable.FlipSignBridge
112112
Bridges.Variable.ZerosBridge
113113
Bridges.Variable.FreeBridge
114114
Bridges.Variable.NonposToNonnegBridge
@@ -118,15 +118,15 @@ Bridges.Variable.RSOCtoSOCBridge
118118
Bridges.Variable.RSOCtoPSDBridge
119119
```
120120

121-
## Objective bridges
121+
## Objective bridge API
122122

123123
```@docs
124124
Bridges.Objective.AbstractBridge
125125
Bridges.Objective.SingleBridgeOptimizer
126126
Bridges.Objective.add_all_bridges
127127
```
128128

129-
### [Bridges implemented](@id objective_bridges_ref)
129+
### [Objective bridges implemented](@id objective_bridges_ref)
130130

131131
```@docs
132132
Bridges.Objective.SlackBridge

src/Bridges/Variable/bridge.jl

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
Subtype of [`MathOptInterface.Bridges.AbstractBridge`](@ref) for variable
1111
bridges.
1212
"""
13-
abstract type AbstractBridge <: MOIB.AbstractBridge end
13+
abstract type AbstractBridge <: MOI.Bridges.AbstractBridge end
1414

1515
"""
1616
supports_constrained_variable(
@@ -81,10 +81,10 @@ MathOptInterface.Bridges.Variable.VectorizeBridge{Float64, MathOptInterface.Nonn
8181
concrete_bridge_type(::Type{BT}, ::Type{<:MOI.AbstractSet}) where {BT} = BT
8282

8383
function concrete_bridge_type(
84-
b::MOIB.AbstractBridgeOptimizer,
84+
b::MOI.Bridges.AbstractBridgeOptimizer,
8585
S::Type{<:MOI.AbstractSet},
8686
)
87-
return concrete_bridge_type(MOIB.bridge_type(b, S), S)
87+
return concrete_bridge_type(MOI.Bridges.bridge_type(b, S), S)
8888
end
8989

9090
"""
@@ -121,7 +121,7 @@ function MOI.get(
121121
::MOI.ModelLike,
122122
attr::MOI.AbstractVariableAttribute,
123123
bridge::AbstractBridge,
124-
::MOIB.IndexInVector,
124+
::MOI.Bridges.IndexInVector,
125125
)
126126
return throw(
127127
ArgumentError(
@@ -144,7 +144,7 @@ function MOI.set(
144144
attr::MOI.AbstractVariableAttribute,
145145
bridge::AbstractBridge,
146146
value,
147-
::MOIB.IndexInVector...,
147+
::MOI.Bridges.IndexInVector...,
148148
)
149149
if MOI.is_copyable(attr) && !MOI.supports(model, attr, typeof(bridge))
150150
throw(MOI.UnsupportedAttribute(attr))
@@ -154,7 +154,7 @@ function MOI.set(
154154
end
155155

156156
"""
157-
unbridged_map(
157+
unbridged_map(
158158
bridge::MOI.Bridges.Variable.AbstractBridge,
159159
vi::MOI.VariableIndex,
160160
)
@@ -163,21 +163,25 @@ For a bridged variable in a scalar set, return a tuple of pairs mapping the
163163
variables created by the bridge to an affine expression in terms of the
164164
bridged variable `vi`.
165165
166-
unbridged_map(
167-
bridge::MOI.Bridges.Variable.AbstractBridge,
168-
vis::Vector{MOI.VariableIndex},
169-
)
166+
```julia
167+
unbridged_map(
168+
bridge::MOI.Bridges.Variable.AbstractBridge,
169+
vis::Vector{MOI.VariableIndex},
170+
)
171+
```
170172
171173
For a bridged variable in a vector set, return a tuple of pairs mapping the
172174
variables created by the bridge to an affine expression in terms of the bridged
173175
variable `vis`. If this method is not implemented, it falls back to calling
174176
the following method for every variable of `vis`.
175177
176-
unbridged_map(
177-
bridge::MOI.Bridges.Variable.AbstractBridge,
178-
vi::MOI.VariableIndex,
179-
i::MOIB.IndexInVector,
180-
)
178+
```julia
179+
unbridged_map(
180+
bridge::MOI.Bridges.Variable.AbstractBridge,
181+
vi::MOI.VariableIndex,
182+
i::MOI.Bridges.IndexInVector,
183+
)
184+
```
181185
182186
For a bridged variable in a vector set, return a tuple of pairs mapping the
183187
variables created by the bridge to an affine expression in terms of the bridged
@@ -192,7 +196,7 @@ function unbridged_map end
192196
function unbridged_map(bridge::AbstractBridge, vis::Vector{MOI.VariableIndex})
193197
mappings = Pair{MOI.VariableIndex,MOI.AbstractScalarFunction}[]
194198
for (i, vi) in enumerate(vis)
195-
vi_mappings = unbridged_map(bridge, vi, MOIB.IndexInVector(i))
199+
vi_mappings = unbridged_map(bridge, vi, MOI.Bridges.IndexInVector(i))
196200
if vi_mappings === nothing
197201
return
198202
end

src/Bridges/Variable/bridges/flip_sign.jl

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,9 @@
55
# in the LICENSE.md file or at https://opensource.org/licenses/MIT.
66

77
"""
8-
FlipSignBridge{T,S1,S2} <: SetMapBridge{T,S2,S1}
8+
abstract type FlipSignBridge{T,S1,S2} <: SetMapBridge{T,S2,S1} end
99
10-
Bridge constrained variables in `S1` into constrained variables in `S2` by
11-
multiplying the variables by `-1` and taking the point reflection of the set
12-
across the origin.
10+
An abstract type that simplifies the creation of other bridges.
1311
"""
1412
abstract type FlipSignBridge{T,S1<:MOI.AbstractSet,S2<:MOI.AbstractSet} <:
1513
SetMapBridge{T,S2,S1} end
@@ -47,11 +45,26 @@ function MOI.delete(
4745
end
4846

4947
"""
50-
NonposToNonnegBridge{T} <:
51-
FlipSignBridge{T,MOI.Nonpositives,MOI.Nonnegatives}
48+
NonposToNonnegBridge{T} <: Bridges.Variable.AbstractBridge
5249
53-
Transforms constrained variables in [`MOI.Nonpositives`](@ref) into constrained
54-
variables in [`MOI.Nonnegatives`](@ref).
50+
`NonposToNonnegBridge` implements the following reformulation:
51+
52+
* ``x \\in \\mathbb{R}_-`` into ``y \\in \\mathbb{R}_+`` with the substitution
53+
rule ``x = -y``,
54+
55+
where `T` is the coefficient type of `-y`.
56+
57+
## Source node
58+
59+
`NonposToNonnegBridge` supports:
60+
61+
* [`MOI.VectorOfVariables`](@ref) in [`MOI.Nonpositives`](@ref)
62+
63+
## Target nodes
64+
65+
`NonposToNonnegBridge` creates:
66+
67+
* One variable node: [`MOI.VectorOfVariables`](@ref) in [`MOI.Nonnegatives`](@ref),
5568
"""
5669
struct NonposToNonnegBridge{T} <:
5770
FlipSignBridge{T,MOI.Nonpositives,MOI.Nonnegatives}

src/Bridges/Variable/bridges/free.jl

Lines changed: 36 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,24 @@
77
"""
88
FreeBridge{T} <: Bridges.Variable.AbstractBridge
99
10-
Transforms constrained variables in [`MOI.Reals`](@ref) to the difference of
11-
constrained variables in [`MOI.Nonnegatives`](@ref).
10+
`FreeBridge` implements the following reformulation:
11+
12+
* ``x \\in \\mathbb{R}`` into ``y, z \\ge 0`` with the substitution
13+
rule ``x = y - z``,
14+
15+
where `T` is the coefficient type of `y - z`.
16+
17+
## Source node
18+
19+
`FreeBridge` supports:
20+
21+
* [`MOI.VectorOfVariables`](@ref) in [`MOI.Reals`](@ref)
22+
23+
## Target nodes
24+
25+
`FreeBridge` creates:
26+
27+
* One variable node: [`MOI.VectorOfVariables`](@ref) in [`MOI.Nonnegatives`](@ref)
1228
"""
1329
struct FreeBridge{T} <: AbstractBridge
1430
variables::Vector{MOI.VariableIndex}
@@ -24,20 +40,18 @@ function bridge_constrained_variable(
2440
) where {T}
2541
variables, constraint = MOI.add_constrained_variables(
2642
model,
27-
MOI.Nonnegatives(2MOI.dimension(set)),
43+
MOI.Nonnegatives(2 * MOI.dimension(set)),
2844
)
2945
return FreeBridge{T}(variables, constraint)
3046
end
3147

32-
function supports_constrained_variable(::Type{<:FreeBridge}, ::Type{MOI.Reals})
33-
return true
34-
end
48+
supports_constrained_variable(::Type{<:FreeBridge}, ::Type{MOI.Reals}) = true
3549

36-
function MOIB.added_constrained_variable_types(::Type{<:FreeBridge})
50+
function MOI.Bridges.added_constrained_variable_types(::Type{<:FreeBridge})
3751
return Tuple{Type}[(MOI.Nonnegatives,)]
3852
end
3953

40-
function MOIB.added_constraint_types(::Type{FreeBridge{T}}) where {T}
54+
function MOI.Bridges.added_constraint_types(::Type{FreeBridge{T}}) where {T}
4155
return Tuple{Type,Type}[]
4256
end
4357

@@ -73,7 +87,7 @@ end
7387
function MOI.delete(
7488
model::MOI.ModelLike,
7589
bridge::FreeBridge,
76-
i::MOIB.IndexInVector,
90+
i::MOI.Bridges.IndexInVector,
7791
)
7892
n = div(length(bridge.variables), 2)
7993
MOI.delete(model, bridge.variables[i.value])
@@ -113,38 +127,34 @@ function MOI.get(
113127
model::MOI.ModelLike,
114128
attr::Union{MOI.VariablePrimal,MOI.VariablePrimalStart},
115129
bridge::FreeBridge{T},
116-
i::MOIB.IndexInVector,
130+
i::MOI.Bridges.IndexInVector,
117131
) where {T}
118132
n = div(length(bridge.variables), 2)
119133
return MOI.get(model, attr, bridge.variables[i.value]) -
120134
MOI.get(model, attr, bridge.variables[n+i.value])
121135
end
122136

123-
function MOIB.bridged_function(
137+
function MOI.Bridges.bridged_function(
124138
bridge::FreeBridge{T},
125-
i::MOIB.IndexInVector,
139+
i::MOI.Bridges.IndexInVector,
126140
) where {T}
127141
n = div(length(bridge.variables), 2)
128-
return MOIU.operate(
129-
-,
130-
T,
131-
bridge.variables[i.value],
132-
bridge.variables[n+i.value],
133-
)
142+
y = bridge.variables[i.value]
143+
z = bridge.variables[n+i.value]
144+
return MOI.Utilities.operate(-, T, y, z)
134145
end
135146

136147
# x_free has been replaced by x[i] - x[n + i].
137148
# To undo it we replace x[i] by x_free and x[n + i] by 0.
138149
function unbridged_map(
139150
bridge::FreeBridge{T},
140151
vi::MOI.VariableIndex,
141-
i::MOIB.IndexInVector,
152+
i::MOI.Bridges.IndexInVector,
142153
) where {T}
143-
# `unbridged_map` is required to return a `MOI.ScalarAffineFunction`.
144-
func = convert(MOI.ScalarAffineFunction{T}, vi)
145154
n = div(length(bridge.variables), 2)
146-
return bridge.variables[i.value] =>
147-
func, bridge.variables[n+i.value] => zero(MOI.ScalarAffineFunction{T})
155+
y = bridge.variables[i.value] => convert(MOI.ScalarAffineFunction{T}, vi)
156+
z = bridge.variables[n+i.value] => zero(MOI.ScalarAffineFunction{T})
157+
return y, z
148158
end
149159

150160
function MOI.supports(
@@ -160,17 +170,10 @@ function MOI.set(
160170
attr::MOI.VariablePrimalStart,
161171
bridge::FreeBridge,
162172
value,
163-
i::MOIB.IndexInVector,
173+
i::MOI.Bridges.IndexInVector,
164174
)
165-
if value < 0
166-
nonneg = zero(value)
167-
nonpos = -value
168-
else
169-
nonneg = value
170-
nonpos = zero(value)
171-
end
172175
n = div(length(bridge.variables), 2)
173-
MOI.set(model, attr, bridge.variables[i.value], nonneg)
174-
MOI.set(model, attr, bridge.variables[n+i.value], nonpos)
176+
MOI.set(model, attr, bridge.variables[i.value], max(zero(value), value))
177+
MOI.set(model, attr, bridge.variables[n+i.value], -min(zero(value), value))
175178
return
176179
end

0 commit comments

Comments
 (0)