Any way to achieve the L2 norm of a matrix xx is smaller than 1 in JuMP?

I want to achieve the constraint: norm(A) <= 1, where A is a matrix variable.

M = Model(SCS.Optimizer)
@variable(M,A[1:3,1:3])
@constraint(M, [1; A] in SecondOrderCone()) 

But it shows error:@constraint(M, [1; A] in SecondOrderCone()): Unrecognized constraint building format. Tried to invoke build_constraint(error, GenericAffExpr{Float64,VariableRef}[1 1 1; A[1,1] A[1,2] A[1,3]; A[2,1] A[2,2] A[2,3]; A[3,1] A[3,2] A[3,3]], SecondOrderCone()), but no such method exists. This is due to specifying an unrecognized function, constraint set, and/or extra positional/keyword arguments.

If you’re trying to create a JuMP extension, you need to implement build_constraint to accomodate these arguments.

How to implement build_constraint? Or is any way to achieve the L2 norm of a matrix xx is smaller than 1 in JuMP?

You’re pretty close, you just needed vec(A):

julia> using JuMP

julia> model = Model()
A JuMP Model
Feasibility problem with:
Variables: 0
Model mode: AUTOMATIC
CachingOptimizer state: NO_OPTIMIZER
Solver name: No optimizer attached.

julia> @variable(model, A[1:3, 1:3])
3×3 Matrix{VariableRef}:
 A[1,1]  A[1,2]  A[1,3]
 A[2,1]  A[2,2]  A[2,3]
 A[3,1]  A[3,2]  A[3,3]

julia> @constraint(model, [1; vec(A)] in SecondOrderCone())
[1, A[1,1], A[2,1], A[3,1], A[1,2], A[2,2], A[3,2], A[1,3], A[2,3], A[3,3]] ∈ MathOptInterface.SecondOrderCone(10)

julia> [1; A]
4×3 Matrix{AffExpr}:
 1       1       1
 A[1,1]  A[1,2]  A[1,3]
 A[2,1]  A[2,2]  A[2,3]
 A[3,1]  A[3,2]  A[3,3]

julia> [1; vec(A)]
10-element Vector{AffExpr}:
 1
 A[1,1]
 A[2,1]
 A[3,1]
 A[1,2]
 A[2,2]
 A[3,2]
 A[1,3]
 A[2,3]
 A[3,3]

Thanks! It is a surprising way.

It is a surprising way

Yes. Julia’s array construction syntax can be subtle.

Another option is

julia> @constraint(model, [1, A...] in SecondOrderCone())
[1, A[1,1], A[2,1], A[3,1], A[1,2], A[2,2], A[3,2], A[1,3], A[2,3], A[3,3]] ∈ MathOptInterface.SecondOrderCone(10)

julia> [1, A...]
10-element Vector{AffExpr}:
 1
 A[1,1]
 A[2,1]
 A[3,1]
 A[1,2]
 A[2,2]
 A[3,2]
 A[1,3]
 A[2,3]
 A[3,3]

Note that none of this is specific to JuMP.

julia> A = rand(3, 3)
3×3 Matrix{Float64}:
 0.541972  0.333154  0.674608
 0.946944  0.905994  0.741906
 0.967324  0.304619  0.0828009

julia> [1; A]
4×3 Matrix{Float64}:
 1.0       1.0       1.0
 0.541972  0.333154  0.674608
 0.946944  0.905994  0.741906
 0.967324  0.304619  0.0828009

julia> [1; vec(A)]
10-element Vector{Float64}:
 1.0
 0.5419723001710393
 0.9469443906608599
 0.9673244837937178
 0.3331539326850954
 0.9059938871589952
 0.30461886604324073
 0.6746081111474829
 0.7419057032214258
 0.08280092651279558

julia> [1, A...]
10-element Vector{Float64}:
 1.0
 0.5419723001710393
 0.9469443906608599
 0.9673244837937178
 0.3331539326850954
 0.9059938871589952
 0.30461886604324073
 0.6746081111474829
 0.7419057032214258
 0.08280092651279558
2 Likes