I have a rather large SDP problem which I deconstruct (block diagonalize) to smaller ones; A baby example (~5000Γ5000) in JuMP-0.18.01
took
215.068401 seconds (124.47 M allocations: 231.684 GiB, 16.09% gc time)
(there are 7229 dense constraints, at some point I spent a lot of time trying to optimize this)
Much to my surprise, upgrading to JuMP-0.18.04 caused this:
905.073732 seconds (893.81 M allocations: 1.343 TiB, 38.38% gc time)
below You can find some code but let me vaguely describe it. The problem itself is very simple:
-
P
is a vector of SD blocks (JuMP.Variables) -
M
is aVector{Array{Float64, 2}}
of the same length and same dimensions asP
- all linear constraints look like
lhs == x - Ξ»*u
, - where
-
lhs = sum(vecdot(M[Ο], P[Ο]) for Ο in 1:length(P))
(its a sum of traces of products) -
x
andu
areFloat64
s
-
I suspect that lhs
thing is not the right way, but I couldnβt find anything in the docs.
So here is the code:
Ns = size.(data.UΟs, 2) #UΟs: 5000Γn projection matrix
m = JuMP.Model();
P = Vector{Matrix{JuMP.Variable}}(length(Ns))
for (k,n) in enumerate(Ns)
P[k] = JuMP.@variable(m, [i=1:n, j=1:n]) # small semidefinite blocks
JuMP.@SDconstraint(m, P[k] >= 0.0)
end
Ξ» = JuMP.@variable(m, Ξ»)
JuMP.@objective(m, Max, Ξ»)
info("Adding $(length(data.orbits)) constraints... ")
@time addconstraints!(m,P,Ξ»,X,orderunit, data) # the timing above is from here
function addconstraints!(m::JuMP.Model,
P::Vector{Matrix{JuMP.Variable}}, Ξ»::JuMP.Variable,
X::GroupRingElem, orderunit::GroupRingElem, data::OrbitData)
orderunit_orb = orbit_spvector(orderunit.coeffs, data.orbits)
X_orb = orbit_spvector(X.coeffs, data.orbits)
UΟsT = [U' for U in data.UΟs]
cnstrs = constraints(parent(X).pm)
orb_cnstr = spzeros(Float64, size(parent(X).pm)...)
M = [Array{Float64}(n,n) for n in size.(UΟsT,1)]
for (t, orbit) in enumerate(data.orbits)
orbit_constraint!(orb_cnstr, cnstrs, orbit)
constraintLHS!(M, orb_cnstr, data.UΟs, UΟsT, data.dims)
lhs = @expression(m, sum(vecdot(M[Ο], P[Ο]) for Ο in 1:length(P))
x, u = X_orb[t], orderunit_orb[t]
JuMP.@constraint(m, lhs == x - Ξ»*u)
end
end
function constraintLHS!(M, cnstr, Us, Ust, dims)
for Ο in 1:endof(Us)
M[Ο] = dims[Ο].*Ust[Ο]*cnstr*Us[Ο]
end
end