使用Julia Convex包时diagind函数报错的正定矩阵优化问题问询
diagind Error in Convex.jl for Your Optimization Problem Let's break down why you're hitting that diagind error and fix your code step by step.
The Root Cause
Convex.jl's variables (like Semidefinite) aren't regular Julia arrays—they're symbolic representations that track constraints and expressions under the hood. Directly modifying them with diagind and .= doesn't work because Convex can't track these in-place, low-level changes to its variable structures.
Corrected Code
Here's the fixed version of your code, with explanations for each key change:
using Convex using SCS # Required: Convex needs a numerical solver; SCS works well for semidefinite problems m = 5; Σ = randn(m, m); # Renamed to match your problem's known matrix Σ # Define the symmetric positive definite variable (Semidefinite enforces symmetry + positive semidefiniteness) x = Semidefinite(m) # Construct XX: X with diagonal elements set to 0 (using Convex-compatible operations) xx = x - Diagonal(x) # Define the objective function as per your problem statement obj = 0.5 * norm(Σ - x, :fro) + 0.01 * sum(abs(xx)) # Set up the minimization problem pro = minimize(obj) # Add the diagonal constraint: all diagonal elements of x must equal 1 pro.constraints += [diag(x) == ones(m)] # Solve the problem with the SCS solver solve!(pro, SCS.Optimizer) # Inspect results println("Optimal objective value: ", pro.optval) println("Optimal X matrix:\n", evaluate(x))
Key Fixes Explained
- Building
xxcorrectly: Instead of trying to zero out diagonal elements withdiagind, we usex - Diagonal(x)—this creates a valid Convex expression that representsxwith its diagonal removed, which the library can properly track and use in the objective. - Enforcing diagonal elements = 1: Instead of
x[diagind(x)].=1, we add an equality constraintdiag(x) == ones(m). This is the correct way to tell Convex to enforce that all diagonal entries ofxequal 1, as it fits into the library's constraint-tracking system. - Adding a solver: Convex.jl doesn't include a solver by default—we added SCS, a popular open-source solver for semidefinite and convex optimization problems, and specified it in the
solve!call. - Clarifying the objective: We used
norm(Σ - x, :fro)for explicit Frobenius norm notation (it's equivalent to your originalvecnormcall) and aligned variable names with your problem statement for readability.
Why This Works
All operations now use Convex.jl's symbolic expression framework, so the library can correctly model your optimization problem, track all constraints, and pass a valid problem formulation to the solver without errors.
内容的提问来源于stack exchange,提问作者Xia.Song

