hello everyone
I am using Julia, and I am programming some SDP. For this, I use JuMP to prepare the problem, then Hypatia to solve it. But, after the constraints are cleaned (by Hypatia), I would like to get the matrix of all constraints of the solver.
My setup looks like this:
model = Model( Hypatia.Optimizer)
@variable( model , ... )
@constraint( model , ... )
@objective( model , ... )
optimize!(model)
# 1243 of 2511 primal equality constraints are dependent
# get the matrix of the processed constraints
I found this object : backend(model).optimizer.model.optimizer.solver.
but after there are so many variables, I don’t know which variable is the one I am looking for ! I don’t know neither if it is in the list !
Is there a way to retrieve the constraint matrix that Hypatia uses internally?
Thanks a lot
Gustave
OK ! here is the code. Sorry for having made you wait !
# get the constraints in some matrix A_sparse
function get_constraints(model::Model)
rows = Int[]
cols = Int[]
A = ComplexF64[]
b = ComplexF64[]
i = 1
for ci in all_constraints(model, include_variable_in_set_constraints=true)
con = JuMP.constraint_object(ci)
if con.func isa GenericAffExpr{Complex{Float64}, VariableRef}
f = con.func
rhs = con.set.value
for (var, coeff) in f.terms
push!(rows, i)
push!(cols, var.index.value)
push!(A, coeff)
end
push!(b, rhs - f.constant)
i += 1
end
end
n_constr = length(b)
n_vars = num_variables(model)
A_sparse = sparse(rows, cols, A, n_constr, n_vars)
return Matrix(A_sparse)
end
# process to clean the constraints
function remove_dependent_constraints(A::Matrix{ComplexF64}; tol=1e-10)
Q, R, p = qr(A', Val(true)) # A' or A ? I am not sure !
diagR = abs.(diag(R))
rankA = count(x -> x > tol, diagR)
independent_rows = Vector(p)[1:rankA]
return A[independent_rows, :] # or select the columns ?
end
I assume you’re aware that there will be other constraints in your model that you’re not capturing here? You’re also making an assumption that var.index.value is the column, which may not always be true.
You might want to do something like this:
function get_constraints(model::Model)
x_to_col = Dict(i => xi for (i, xi) in enumerate(all_variables(model)))
I, J, V, b = Int[], Int[], ComplexF64[], ComplexF64[]
F, S = GenericAffExpr{ComplexF64,VariableRef}, MOI.EqualTo{ComplexF64}
for (row, ci) in enumerate(all_constraints(model, F, S))
con = JuMP.constraint_object(ci)
for (var, coeff) in con.func.terms
push!(I, row)
push!(J, x_to_col[var])
push!(V, coeff)
end
push!(b, con.set.value - con.func.constant)
end
return SparseArrays.sparse(I, J, V, length(b), length(x_to_col))
end