# Seeking low rank solution for two PSD matrices via \`SDPLR.jl\` in \`JuMP\`

**URL:** <https://discourse.julialang.org/t/seeking-low-rank-solution-for-two-psd-matrices-via-sdplr-jl-in-jump/135823>\
**Category:** Optimization (Mathematical)\
**Tags:** jump\
**Created:** [February 25, 2026, 1:36am UTC](https://discourse.julialang.org/t/seeking-low-rank-solution-for-two-psd-matrices-via-sdplr-jl-in-jump/135823 "2026-02-25T01:36:49Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Shuvomoy\_Das\_Gupta](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shuvomoy_das_gupta/32/10069_2.png) [@Shuvomoy\_Das\_Gupta](https://discourse.julialang.org/u/Shuvomoy_Das_Gupta)\
**Post date:** [February 25, 2026, 1:36am UTC](https://discourse.julialang.org/t/seeking-low-rank-solution-for-two-psd-matrices-via-sdplr-jl-in-jump/135823/1 "2026-02-25T01:36:49Z")

</div>

I am trying the `SDPLR.jl` solver in `JuMP` for finding low-rank solutions to SDPs and it is working quite nicely when the underlying semidefinite optimization problem has only one PSD variable `X`. How do I apply `SDPLR.jl` in `JuMP` when I have two SDP matrices `X` and `Y`, where I want to seek a rank 1 solution for `X` and say rank 2 solution on `Y`. The `README.md` file for `SDPLR.jl` is not super clear in this regard of this can be done.

I will appreciate any tips/suggestions on this. If there are other SDP solvers that gives sparse/low-rank solutions to SDPs in `JuMP` ecosystem, please let me know.

---

<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:** [February 25, 2026, 2:38am UTC](https://discourse.julialang.org/t/seeking-low-rank-solution-for-two-psd-matrices-via-sdplr-jl-in-jump/135823/2 "2026-02-25T02:38:54Z")

</div>

This is a question for @blegat. He’s been working on the low-rank stuff.

---

<div class="post-metadata">

**Author:** ![technocrat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/technocrat/32/220947_2.png) [@technocrat](https://discourse.julialang.org/u/technocrat)\
**Post date:** [February 25, 2026, 3:08am UTC](https://discourse.julialang.org/t/seeking-low-rank-solution-for-two-psd-matrices-via-sdplr-jl-in-jump/135823/3 "2026-02-25T03:08:21Z")

</div>

Have you tried something along these lines?

```julia-auto
using LinearAlgebra, JuMP, SDPLR, MathOptInterface
const MOI = MathOptInterface

nx = 4 # size of X
ny = 6 # size of Y

model = Model(SDPLR.Optimizer)

@variable(model, X[1:nx, 1:nx], PSD)
@variable(model, Y[1:ny, 1:ny], PSD)

# objective and constraints ...

set_attribute(model, "maxrank", function(m, n)
    if n == nx
        return 1 # rank-1 factor for X
    elseif n == ny
        return 2 # rank-2 factor for Y
    else
        return SDPLR.default_maxrank(m, n) # fallback
    end
end)

optimize!(model)

Fx = MOI.get(model, SDPLR.Factor(), VariableInSetRef(X)) # nx×1
Fy = MOI.get(model, SDPLR.Factor(), VariableInSetRef(Y)) # ny×2 or paste code here

```

```julia-auto

            ***SDPLR 1.03-beta***

===================================================
 major minor val infeas time  
---------------------------------------------------
    1 0 0.00000000e+00 0.0e+00 0
===================================================

DIMACS error measures: 0.00e+00 0.00e+00 0.00e+00 -0.00e+00 0.00e+00 0.00e+00

julia> Fx = MOI.get(model, SDPLR.Factor(), VariableInSetRef(X)) # nx×1
4×1 Matrix{Float64}:
 -0.5556374349255623
 -0.20338580709894138
 -0.050108647317640864
 -0.25648261076643797

julia> Fy = MOI.get(model, SDPLR.Factor(), VariableInSetRef(Y)) # ny×2
6×2 Matrix{Float64}:
 -0.318264 -0.482569
 -0.413709 0.709417
  0.264882 0.686019
 -0.125805 -0.170905
  0.0918272 0.0715626
 -0.650191 -0.139925

```

---

<div class="post-metadata">

**Author:** ![Shuvomoy\_Das\_Gupta](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shuvomoy_das_gupta/32/10069_2.png) [@Shuvomoy\_Das\_Gupta](https://discourse.julialang.org/u/Shuvomoy_Das_Gupta)\
**Post date:** [February 25, 2026, 4:08am UTC](https://discourse.julialang.org/t/seeking-low-rank-solution-for-two-psd-matrices-via-sdplr-jl-in-jump/135823/4 "2026-02-25T04:08:10Z")

</div>

Thanks for your response. In my test case, the size of the matrices could be the same, i.e., `nx` can be equal to `ny`, so it would be great if there is a way to seek low rank solution to matrices of same size.

---

<div class="post-metadata">

**Author:** ![technocrat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/technocrat/32/220947_2.png) [@technocrat](https://discourse.julialang.org/u/technocrat)\
**Post date:** [February 25, 2026, 4:49am UTC](https://discourse.julialang.org/t/seeking-low-rank-solution-for-two-psd-matrices-via-sdplr-jl-in-jump/135823/5 "2026-02-25T04:49:03Z")

</div>

`ny = 4` in the example doesn’t behave as expected?

---

<div class="post-metadata">

**Author:** ![blegat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/blegat/32/217090_2.png) [@blegat](https://discourse.julialang.org/u/blegat)\
**Post date:** [February 25, 2026, 1:41pm UTC](https://discourse.julialang.org/t/seeking-low-rank-solution-for-two-psd-matrices-via-sdplr-jl-in-jump/135823/6 "2026-02-25T13:41:10Z")

</div>

Good questions. Indeed if they have the same dimension, setting a function probably doesn’t work. My plan is to define variable attributes for this in LowRankOpt.jl that would then behave uniformly across Burer-Motneiro solvers such as SDPLR and SDPLRPlus.  
At the moment, if you use SDPLRPlus using the LowRankOpt interface, you can use the `ranks` optimizer attribute:

> <https://github.com/blegat/LowRankOpt.jl/blob/3fd2cc49f326208e2fecdd855bdfa250dde1633e/test/BurerMonteiro.jl#L68>

It is not ideal since you’re giving a list of ranks that should be of length equal to the number of PSD variables which is why the goal is to have variable attributes instead.  
This will be discussed during my talk at JuMP-dev 2026 and hopefully there will be variable attributes by then 🙂

---

<div class="post-metadata">

**Author:** ![Shuvomoy\_Das\_Gupta](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shuvomoy_das_gupta/32/10069_2.png) [@Shuvomoy\_Das\_Gupta](https://discourse.julialang.org/u/Shuvomoy_Das_Gupta)\
**Post date:** [February 25, 2026, 2:02pm UTC](https://discourse.julialang.org/t/seeking-low-rank-solution-for-two-psd-matrices-via-sdplr-jl-in-jump/135823/7 "2026-02-25T14:02:49Z")

</div>

Thanks for your response. When `nx` = `ny` then the code will just impose rank 2 on both, I think.

---

<div class="post-metadata">

**Author:** ![Shuvomoy\_Das\_Gupta](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shuvomoy_das_gupta/32/10069_2.png) [@Shuvomoy\_Das\_Gupta](https://discourse.julialang.org/u/Shuvomoy_Das_Gupta)\
**Post date:** [February 25, 2026, 2:06pm UTC](https://discourse.julialang.org/t/seeking-low-rank-solution-for-two-psd-matrices-via-sdplr-jl-in-jump/135823/8 "2026-02-25T14:06:22Z")

</div>

Thanks @blegat , for now I will try the `LowRankOpt.jl` approach that you suggested. Looking forward to your talk at JuMP-dev!

---

<div class="post-metadata">

**Author:** ![blegat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/blegat/32/217090_2.png) [@blegat](https://discourse.julialang.org/u/blegat)\
**Post date:** [February 26, 2026, 8:12am UTC](https://discourse.julialang.org/t/seeking-low-rank-solution-for-two-psd-matrices-via-sdplr-jl-in-jump/135823/9 "2026-02-26T08:12:55Z")

</div>

Thanks, also looking forward to your talk on PEPit.jl, are your trying to find low-rank solutions for PEPit ?

---

<div class="post-metadata">

**Author:** ![Shuvomoy\_Das\_Gupta](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shuvomoy_das_gupta/32/10069_2.png) [@Shuvomoy\_Das\_Gupta](https://discourse.julialang.org/u/Shuvomoy_Das_Gupta)\
**Post date:** [February 26, 2026, 2:24pm UTC](https://discourse.julialang.org/t/seeking-low-rank-solution-for-two-psd-matrices-via-sdplr-jl-in-jump/135823/10 "2026-02-26T14:24:46Z")

</div>

Thank you @blegat !`PEPit.jl` mostly involves single PSD matrix and for that `SDPLR.jl` works well already, `logdet` type heuristics also work well. Actually I am actually trying to apply `SDPLR.jl` to Problem (63) of [https://arxiv.org/pdf/2510.03855](https://arxiv.org/pdf/2510.03855) , which has 4 interconnected PSD matrices. I have found [GitHub - nanleij/ClusteredLowRankSolver.jl: A semidefinite programming solver for clustered low-rank SDPs](https://github.com/nanleij/ClusteredLowRankSolver.jl) very useful in this regard so far, it does not have direct JuMP connection and the built-in interior-point solver is not robust, but the rounding procedure described at [ClusteredLowRankSolver.jl/src/rounding.jl at main · nanleij/ClusteredLowRankSolver.jl · GitHub](https://github.com/nanleij/ClusteredLowRankSolver.jl/blob/main/src/rounding.jl) was very useful for me (I had to modify it for my setup to use it). It may be useful if some variant of it can be added to `LowRankOpt.jl`.
