@@ -15,10 +15,7 @@ const SVF = MOI.SingleVariable
1515const VVF = MOI. VectorOfVariables
1616const VF = Union{SVF, VVF}
1717const SAF{T} = MOI. ScalarAffineFunction{T}
18- const VAF{T} = MOI. VectorAffineFunction{T}
19- const AF{T} = Union{SAF{T}, VAF{T}}
2018const ASF{T} = Union{SVF, SAF{T}}
21- const AVF{T} = Union{VVF, VAF{T}}
2219
2320const ZS = Union{MOI. EqualTo, MOI. Zeros}
2421const NS = Union{MOI. GreaterThan, MOI. Nonnegatives}
@@ -43,7 +40,6 @@ mutable struct SOItoMOIBridge{T, SIT <: AbstractSDOptimizer} <: MOI.AbstractOpti
4340 varmap:: Vector{Vector{Tuple{Int, Int, Int, T, T}}} # Variable Index vi -> blk, i, j, coef, shift # x = sum coef * block(X, blk)[i, j] + shift
4441 zeroblock:: Dict{CI, Int}
4542 constrmap:: Dict{CI, UnitRange{Int}} # Constraint Index ci -> cs
46- slackmap:: Vector{Tuple{Int, Int, Int, T}} # c -> blk, i, j, coef
4743 double:: Vector{CI} # created when there are two cones for same variable
4844 function SOItoMOIBridge {T} (sdoptimizer:: SIT ) where {T, SIT}
4945 new {T, SIT} (sdoptimizer, Dict {Int64, T} (), Dict {Int, T} (),
@@ -53,7 +49,6 @@ mutable struct SOItoMOIBridge{T, SIT <: AbstractSDOptimizer} <: MOI.AbstractOpti
5349 Vector{Tuple{Int, Int, Int, T}}[],
5450 Dict {CI, Int} (),
5551 Dict {CI, UnitRange{Int}} (),
56- Tuple{Int, Int, Int, T}[],
5752 CI[])
5853 end
5954end
@@ -86,8 +81,7 @@ function MOI.is_empty(optimizer::SOItoMOIBridge)
8681 isempty (optimizer. free) &&
8782 isempty (optimizer. varmap) &&
8883 isempty (optimizer. zeroblock) &&
89- isempty (optimizer. constrmap) &&
90- isempty (optimizer. slackmap)
84+ isempty (optimizer. constrmap)
9185end
9286function MOI. empty! (optimizer:: SOItoMOIBridge{T} ) where T
9387 for s in optimizer. double
@@ -107,37 +101,57 @@ function MOI.empty!(optimizer::SOItoMOIBridge{T}) where T
107101 optimizer. varmap = Vector{Tuple{Int, Int, Int, T}}[]
108102 optimizer. zeroblock = Dict {CI, Int} ()
109103 optimizer. constrmap = Dict {CI, UnitRange{Int}} ()
110- optimizer. slackmap = Tuple{Int, Int, Int, T}[]
111104end
112105
113106function setconstant! (optimizer:: SOItoMOIBridge , ci:: CI , s) end
114107function setconstant! (optimizer:: SOItoMOIBridge , ci:: CI , s:: MOI.AbstractScalarSet )
115108 optimizer. setconstant[ci. value] = MOIU. getconstant (s)
116109end
117- function addsetconstant (optimizer:: SOItoMOIBridge , ci:: CI{<:Any, <:MOI.AbstractScalarSet} , x)
118- x + optimizer. setconstant[ci. value]
110+ function set_constant (optimizer:: SOItoMOIBridge ,
111+ ci:: CI {<: MOI.AbstractScalarFunction ,
112+ <: MOI.AbstractScalarSet })
113+ return optimizer. setconstant[ci. value]
119114end
120- function addsetconstant (optimizer:: SOItoMOIBridge , ci:: CI , x)
121- x
115+ function set_constant (optimizer:: SOItoMOIBridge{T} , ci:: CI ) where T
116+ return zeros (T, length (optimizer . constrmap[ci]))
122117end
123118function addblkconstant (optimizer:: SOItoMOIBridge , ci:: CI{<:Any, <:Union{NS, PS}} , x)
124119 blk = - ci. value
125- x .+ optimizer. blkconstant[blk]
126- end
127- function addblkconstant (optimizer:: SOItoMOIBridge , ci:: CI , x)
128- x
120+ return x .+ optimizer. blkconstant[blk]
129121end
122+ addblkconstant (optimizer:: SOItoMOIBridge , ci:: CI , x) = x
130123
131- function MOI. supports (optimizer:: SOItoMOIBridge{T} ,
132- :: Union {MOI. ObjectiveSense,
133- MOI. ObjectiveFunction{<: Union {MOI. SingleVariable,
134- MOI. ScalarAffineFunction{T}}}}) where T
124+ function MOI. supports (
125+ optimizer:: SOItoMOIBridge{T} ,
126+ :: Union {MOI. ObjectiveSense,
127+ MOI. ObjectiveFunction{<: Union {MOI. SingleVariable,
128+ MOI. ScalarAffineFunction{T}}}}) where T
135129 return true
136130end
137131
138- function MOI. supports_constraint (:: SOItoMOIBridge{T} ,
139- :: Type{<:Union{VF, AF{T}}} ,
140- :: Type{<:SupportedSets} ) where T
132+ # Zeros and Nonpositives supports could be removed thanks to variable bridges
133+ # * `VectorOfVariables`-in-`Zeros` would return a `VectorAffineFunction` with
134+ # zero constant and no variable created.
135+ # * `VectorOfVariables`-in-`Nonpositives` would create variables in
136+ # `Nonnegatives` and return a `VectorAffineFunction` containing `-` the
137+ # variables.
138+ function MOI. supports_constraint (
139+ :: SOItoMOIBridge , :: Type{MOI.VectorOfVariables} ,
140+ :: Type {<: Union {MOI. Zeros, MOI. Nonnegatives, MOI. Nonpositives,
141+ MOI. PositiveSemidefiniteConeTriangle}})
142+ return true
143+ end
144+ # This support could be remove thanks to variable bridges.
145+ # The VectorizeVariableBridge would redirect to the above case and then the
146+ # resulting function would be shifted by the constant.
147+ function MOI. supports_constraint (
148+ :: SOItoMOIBridge{T} , :: Type{MOI.SingleVariable} ,
149+ :: Type{<:Union{MOI.EqualTo{T}, MOI.GreaterThan{T}, MOI.LessThan{T}}} ) where T
150+ return true
151+ end
152+ function MOI. supports_constraint (
153+ :: SOItoMOIBridge{T} , :: Type{MOI.ScalarAffineFunction{T}} ,
154+ :: Type{MOI.EqualTo{T}} ) where T
141155 return true
142156end
143157
@@ -163,10 +177,10 @@ MOI.get(m::SOItoMOIBridge, s::SolverStatus) = MOI.get(m.sdoptimizer, s)
163177MOI. get (m:: SOItoMOIBridge , :: MOI.ResultCount ) = 1
164178
165179function _getblock (M, blk:: Integer , s:: Type{<:Union{NS, ZS}} )
166- diag (block (M, blk))
180+ return diag (block (M, blk))
167181end
168182function _getblock (M, blk:: Integer , s:: Type{<:PS} )
169- - diag (block (M, blk))
183+ return - diag (block (M, blk))
170184end
171185# Vectorized length for matrix dimension d
172186sympackedlen (d:: Integer ) = (d* (d+ 1 )) >> 1
@@ -183,20 +197,22 @@ function _getblock(M::AbstractMatrix{T}, blk::Integer, s::Type{<:DS}) where T
183197 end
184198 end
185199 @assert k == n
186- v
200+ return v
187201end
188202function getblock (M, blk:: Integer , s:: Type{<:MOI.AbstractScalarSet} )
189203 vd = _getblock (M, blk, s)
190204 @assert length (vd) == 1
191- vd[1 ]
205+ return vd[1 ]
192206end
193207function getblock (M, blk:: Integer , s:: Type{<:MOI.AbstractVectorSet} )
194- _getblock (M, blk, s)
208+ return _getblock (M, blk, s)
195209end
196210
197211getvarprimal (m:: SOItoMOIBridge , blk:: Integer , S) = getblock (getX (m. sdoptimizer), blk, S)
198212function getvardual (m:: SOItoMOIBridge , blk:: Integer , S)
199- getblock (getZ (m. sdoptimizer), blk, S)
213+ z = getZ (m. sdoptimizer)
214+ b = getblock (z, blk, S)
215+ return getblock (getZ (m. sdoptimizer), blk, S)
200216end
201217
202218function MOI. get (m:: SOItoMOIBridge{T} , :: MOI.VariablePrimal , vi:: VI ) where T
@@ -208,97 +224,54 @@ function MOI.get(m::SOItoMOIBridge{T}, ::MOI.VariablePrimal, vi::VI) where T
208224 x += block (X, blk)[i, j] * sign (coef)
209225 end
210226 end
211- x
227+ return x
212228end
213229function MOI. get (m:: SOItoMOIBridge , vp:: MOI.VariablePrimal , vi:: Vector{VI} )
214- MOI. get .(m, vp, vi)
230+ return MOI. get .(m, vp, vi)
215231end
216232
217233function _getattribute (m:: SOItoMOIBridge , ci:: CI{<:ASF} , f)
218234 cs = m. constrmap[ci]
219235 @assert length (cs) == 1
220- f (m, first (cs))
236+ return f (m, first (cs))
221237end
222- function _getattribute (m:: SOItoMOIBridge , ci:: CI{<:AVF} , f)
223- f .(m, m. constrmap[ci])
224- end
225-
226- function getslack (m:: SOItoMOIBridge{T} , c:: Integer ) where T
227- X = getX (m. sdoptimizer)
228- blk, i, j, coef = m. slackmap[c]
229- if iszero (blk)
230- zero (T)
231- else
232- if i != j
233- coef *= 2 # We should take block(X, blk)[i, j] + block(X, blk)[j, i] but they are equal
234- end
235- coef * block (X, blk)[i, j]
236- end
238+ function _getattribute (m:: SOItoMOIBridge , ci:: CI{<:VVF} , f)
239+ return f .(m, m. constrmap[ci])
237240end
238241
239- function MOI. get (m:: SOItoMOIBridge , a:: MOI.ConstraintPrimal , ci:: CI{F, S} ) where {F, S}
242+ function MOI. get (m:: SOItoMOIBridge , a:: MOI.ConstraintPrimal ,
243+ ci:: CI{F, S} ) where {F, S}
240244 if ci. value >= 0
241- addsetconstant (m, ci, _getattribute (m, ci, getslack) )
245+ return set_constant (m, ci)
242246 else
243247 # Variable Function-in-S with S different from Zeros and EqualTo and not a double variable constraint
244248 blk = - ci. value
245- addblkconstant (m, ci, getvarprimal (m, blk, S))
249+ return addblkconstant (m, ci, getvarprimal (m, blk, S))
246250 end
247251end
248252
249- function getvardual (m:: SOItoMOIBridge{T} , vi:: VI ) where T
250- Z = getZ (m. sdoptimizer)
251- z = zero (T)
252- for (blk, i, j, coef) in varmap (m, vi)
253- if blk != 0
254- z += block (Z, blk)[i, j] * sign (coef)
255- end
256- end
257- z
258- end
259- getvardual (m:: SOItoMOIBridge , f:: SVF ) = getvardual (m, f. variable)
260- getvardual (m:: SOItoMOIBridge , f:: VVF ) = map (vi -> getvardual (m, vi), f. variables)
261- # function MOI.get(m::SOItoMOIBridge, ::MOI.ConstraintDual, ci::CI{<:VF, S})
262- # _getattribute(m, ci, getdual) + getvardual(m, MOI.get(m, MOI.ConstraintFunction(), ci))
263- # end
264253function MOI. get (m:: SOItoMOIBridge , :: MOI.ConstraintDual , ci:: CI{<:VF, S} ) where S<: SupportedSets
265254 if ci. value < 0
266- getvardual (m, - ci. value, S)
255+ return getvardual (m, - ci. value, S)
267256 else
268257 dual = _getattribute (m, ci, getdual)
269258 if haskey (m. zeroblock, ci) # ZS
270- dual + getvardual (m, m. zeroblock[ci], S)
259+ return dual + getvardual (m, m. zeroblock[ci], S)
271260 else # var constraint on unfree constraint
272- dual
261+ return dual
273262 end
274263 end
275264end
276265
277266function getdual (m:: SOItoMOIBridge{T} , c:: Integer ) where T
278267 if c == 0
279- zero (T)
268+ return zero (T)
280269 else
281- - gety (m. sdoptimizer)[c]
270+ return - gety (m. sdoptimizer)[c]
282271 end
283272end
284273function MOI. get (m:: SOItoMOIBridge , :: MOI.ConstraintDual , ci:: CI )
285- _getattribute (m, ci, getdual)
286- end
287- function scalevec! (v, c)
288- d = div (isqrt (1 + 8 length (v))- 1 , 2 )
289- @assert div (d* (d+ 1 ), 2 ) == length (v)
290- i = 1
291- for j in 1 : d
292- for k in i: (i+ j- 2 )
293- v[k] *= c
294- end
295- i += j
296- end
297- v
298- end
299- function MOI. get (m:: SOItoMOIBridge{T} , :: MOI.ConstraintDual ,
300- ci:: CI{<:AF{T}, DS} ) where T
301- scalevec! (_getattribute (m, ci, getdual), one (T)/ 2 )
274+ return _getattribute (m, ci, getdual)
302275end
303276
304277include (" sdpa.jl" )
0 commit comments