@@ -11,7 +11,7 @@ import MathOptInterface as MOI
1111struct Decomposition
1212 neqns:: Int
1313 values:: Vector{Int}
14- cliques:: Vector{Vector{ Int} }
14+ cliques:: SparseMatrixCSC{Bool, Int}
1515end
1616
1717mutable struct Optimizer{A <: EliminationAlgorithm } <: MOI.AbstractOptimizer
@@ -206,7 +206,7 @@ function MOI.add_constraint(
206206 s:: MOI.PositiveSemidefiniteConeTriangle ,
207207 ) where {T}
208208 # construct sparse matrices
209- V, A, b = decode (f, s)
209+ V, A, b = decode (f, s); n = size (b, 2 )
210210
211211 # compute aggregate sparsity pattern
212212 pattern = sum (sparsitypattern, A; init = sparsitypattern (b))
@@ -215,16 +215,22 @@ function MOI.add_constraint(
215215 label, tree = cliquetree (pattern; alg = model. alg)
216216
217217 # compute cliques
218- cliques = map (tree) do clique
219- return sort! (label[clique])
220- end
218+ cliques = spzeros (Bool, n, length (tree))
219+
220+ for (b, bag) in enumerate (tree)
221+ append! (cliques. rowval, bag)
222+ cliques. colptr[b + 1 ] = cliques. colptr[b] + length (bag)
223+ end
224+
225+ resize! (cliques. nzval, length (cliques. rowval))
226+ permute! (cliques, invperm (label), axes (cliques, 2 ))
221227
222228 # terms
223229 indices = Int[]
224230 terms = MOI. VectorAffineTerm{T}[]
225231
226- for clique in cliques
227- m = length (clique)
232+ for b in axes ( cliques, 2 )
233+ clique = view (cliques . rowval, nzrange (cliques, b)); m = length (clique)
228234 U = MOI. add_variables (model, m * (m + 1 ) ÷ 2 )
229235
230236 for j in oneto (m), i in oneto (j)
@@ -246,7 +252,6 @@ function MOI.add_constraint(
246252 end
247253
248254 # constants
249- n = size (b, 2 )
250255 constants = zeros (T, n * (n + 1 ) ÷ 2 )
251256
252257 for j in axes (b, 2 )
@@ -294,11 +299,22 @@ function MOI.get(
294299 F <: MOI.VectorAffineFunction{Float64} ,
295300 S <: MOI.PositiveSemidefiniteConeTriangle ,
296301 }
297- decomposition = model. outer_to_inner[index. value]
298- result = zeros (Float64, decomposition. neqns * (decomposition. neqns + 1 ) ÷ 2 )
299302
300- for (value, clique) in zip (decomposition. values, decomposition. cliques)
301- part = MOI. get (model. inner, attribute, MOI. ConstraintIndex {MOI.VectorOfVariables, MOI.PositiveSemidefiniteConeTriangle} (value))
303+ decomposition = model. outer_to_inner[index. value]
304+ neqns = decomposition. neqns
305+ values = decomposition. values
306+ cliques = decomposition. cliques
307+ result = zeros (Float64, neqns * (neqns + 1 ) ÷ 2 )
308+
309+ for b in axes (cliques, 2 )
310+ clique = view (cliques. rowval, nzrange (cliques, b))
311+ value = values[b]
312+
313+ part = MOI. get (
314+ model. inner,
315+ attribute,
316+ MOI. ConstraintIndex {MOI.VectorOfVariables, MOI.PositiveSemidefiniteConeTriangle} (value),
317+ )
302318
303319 for (j, w) in enumerate (clique)
304320 for (i, v) in enumerate (clique)
@@ -320,10 +336,20 @@ function MOI.get(
320336 S <: MOI.PositiveSemidefiniteConeTriangle ,
321337 }
322338 decomposition = model. outer_to_inner[index. value]
323- result = zeros (Float64, decomposition. neqns * (decomposition. neqns + 1 ) ÷ 2 )
324-
325- for (value, clique) in zip (decomposition. values, decomposition. cliques)
326- part = MOI. get (model. inner, attribute, MOI. ConstraintIndex {MOI.VectorOfVariables, MOI.PositiveSemidefiniteConeTriangle} (value))
339+ neqns = decomposition. neqns
340+ values = decomposition. values
341+ cliques = decomposition. cliques
342+ result = zeros (Float64, neqns * (neqns + 1 ) ÷ 2 )
343+
344+ for b in axes (cliques, 2 )
345+ clique = view (cliques. rowval, nzrange (cliques, b))
346+ value = values[b]
347+
348+ part = MOI. get (
349+ model. inner,
350+ attribute,
351+ MOI. ConstraintIndex {MOI.VectorOfVariables, MOI.PositiveSemidefiniteConeTriangle} (value),
352+ )
327353
328354 for (j, w) in enumerate (clique)
329355 for (i, v) in enumerate (clique)
0 commit comments