# Get the constraints matrix from a SDP relaxation

**URL:** https://discourse.julialang.org/t/get-the-constraints-matrix-from-a-sdp-relaxation/127222
**Category:** Optimization (Mathematical)
**Created:** [March 21, 2025, 1:03pm UTC](https://discourse.julialang.org/t/get-the-constraints-matrix-from-a-sdp-relaxation/127222 "2025-03-21T13:03:38Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![gustave\_Robichon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustave_robichon/32/207522_2.png) [@gustave\_Robichon](https://discourse.julialang.org/u/gustave_Robichon)
#### Post date: [March 21, 2025, 1:03pm UTC](https://discourse.julialang.org/t/get-the-constraints-matrix-from-a-sdp-relaxation/127222/1 "2025-03-21T13:03:38Z")

</div>

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:

```julia
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

---

<div class="post-metadata">

### Author: ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)
#### Post date: [March 21, 2025, 8:42pm UTC](https://discourse.julialang.org/t/get-the-constraints-matrix-from-a-sdp-relaxation/127222/2 "2025-03-21T20:42:23Z")

</div>

I’m not sure if there is an easy way to get this from Hypatia.

You can get the `Hypatia.Optimizer` object with `unsafe_backend(model)`. It has the `.solver` field.

Perhaps take a look at the fields of `unsafe_backend(model).solver.model`. But I don’t think there’s an easy way to convert this back to JuMP.

---

<div class="post-metadata">

### Author: ![gustave\_Robichon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustave_robichon/32/207522_2.png) [@gustave\_Robichon](https://discourse.julialang.org/u/gustave_Robichon)
#### Post date: [March 25, 2025, 2:48pm UTC](https://discourse.julialang.org/t/get-the-constraints-matrix-from-a-sdp-relaxation/127222/3 "2025-03-25T14:48:47Z")

</div>

Finally I get the raw constraints, then I process them by myself. Are you interessed in the code ? ChatGPT helped me a bit 🙂  
Thanks for your answer 🙂

---

<div class="post-metadata">

### Author: ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)
#### Post date: [March 25, 2025, 6:41pm UTC](https://discourse.julialang.org/t/get-the-constraints-matrix-from-a-sdp-relaxation/127222/4 "2025-03-25T18:41:30Z")

</div>

Only if the code is simple. It might be useful to someone else in the future 😄

---

<div class="post-metadata">

### Author: ![gustave\_Robichon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustave_robichon/32/207522_2.png) [@gustave\_Robichon](https://discourse.julialang.org/u/gustave_Robichon)
#### Post date: [April 7, 2025, 8:21am UTC](https://discourse.julialang.org/t/get-the-constraints-matrix-from-a-sdp-relaxation/127222/5 "2025-04-07T08:21:19Z")

</div>

OK ! here is the code. Sorry for having made you wait ! 🙂

```julia
# 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

```

---

<div class="post-metadata">

### Author: ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)
#### Post date: [April 8, 2025, 1:21am UTC](https://discourse.julialang.org/t/get-the-constraints-matrix-from-a-sdp-relaxation/127222/6 "2025-04-08T01:21:44Z")

</div>

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:

```julia
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

```

---

<div class="post-metadata">

### Author: ![gustave\_Robichon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustave_robichon/32/207522_2.png) [@gustave\_Robichon](https://discourse.julialang.org/u/gustave_Robichon)
#### Post date: [April 8, 2025, 9:40am UTC](https://discourse.julialang.org/t/get-the-constraints-matrix-from-a-sdp-relaxation/127222/7 "2025-04-08T09:40:51Z")

</div>

I have tested your code, but I found a bug … here is the patch :

```julia
x_to_col = Dict(xi => i for (i, xi) in enumerate(all_variables(model)))

```

I think it works now 🙂 Thanks for the help !
