Skip to content

Commit

Permalink
Add set for low-rank constrained SDP
Browse files Browse the repository at this point in the history
  • Loading branch information
blegat committed Jun 8, 2023
1 parent d48ac54 commit 5defcea
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 11 deletions.
4 changes: 3 additions & 1 deletion docs/src/background/duality.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,9 @@ and similarly, the dual is:

The scalar product is different from the canonical one for the sets
[`PositiveSemidefiniteConeTriangle`](@ref), [`LogDetConeTriangle`](@ref),
[`RootDetConeTriangle`](@ref).
[`RootDetConeTriangle`](@ref),
[`FrobeniusProductPostiviveSemidefiniteConeTriangle`](@ref) and
[`LinearMatrixInequalityConeTriangle`](@ref).

If the set ``C_i`` of the section [Duality](@ref) is one of these three cones,
then the rows of the matrix ``A_i`` corresponding to off-diagonal entries are
Expand Down
3 changes: 2 additions & 1 deletion docs/src/manual/standard_form.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ The matrix-valued set types implemented in MathOptInterface.jl are:
| [`NormSpectralCone(r, c)`](@ref MathOptInterface.NormSpectralCone) | ``\{ (t, X) \in \mathbb{R}^{1 + r \times c} : t \ge \sigma_1(X), X \mbox{ is a } r\times c\mbox{ matrix} \}``
| [`NormNuclearCone(r, c)`](@ref MathOptInterface.NormNuclearCone) | ``\{ (t, X) \in \mathbb{R}^{1 + r \times c} : t \ge \sum_i \sigma_i(X), X \mbox{ is a } r\times c\mbox{ matrix} \}`` |
| [`HermitianPositiveSemidefiniteConeTriangle(d)`](@ref MathOptInterface.HermitianPositiveSemidefiniteConeTriangle) | The cone of Hermitian positive semidefinite matrices, with
`side_dimension` rows and columns. |
| [`FrobeniusProductPostiviveSemidefiniteConeTriangle(d, A)`](@ref MathOptInterface.FrobeniusProductPostiviveSemidefiniteConeTriangle) | The cone of positive semidefinite matrices, with `side_dimension` rows and columns and their Frobenius inner product with the matrices in `A`. |
| [`LinearMatrixInequalityConeTriangle(d, A)`](@ref MathOptInterface.LinearMatrixInequalityConeTriangle) | The cone of vector `y` and symmetric `C`, with `side_dimension` rows and columns such that ``\sum_i y_i A_i + C`` is positive semidefinite. |

Some of these cones can take two forms: `XXXConeTriangle` and `XXXConeSquare`.

Expand Down
2 changes: 2 additions & 0 deletions docs/src/reference/standard_form.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,4 +152,6 @@ LogDetConeTriangle
LogDetConeSquare
RootDetConeTriangle
RootDetConeSquare
FrobeniusProductPostiviveSemidefiniteConeTriangle
LinearMatrixInequalityConeTriangle
```
21 changes: 21 additions & 0 deletions src/Bridges/bridge.jl
Original file line number Diff line number Diff line change
Expand Up @@ -283,3 +283,24 @@ If you implement this method, you must also implement
[`needs_final_touch`](@ref).
"""
function final_touch end

"""
struct FirstBridge <: MOI.AbstractConstraintAttribute end
Returns the first bridge used to bridge the constraint.
!!! warning
The indices of the bridge correspond to internal indices and may not
correspond to indices of the model this attribute is got from.
"""
struct FirstBridge <: MOI.AbstractConstraintAttribute end

MOI.is_set_by_optimize(::FirstBridge) = true
MOI.get(::MOI.ModelLike, ::FirstBridge, b::MOI.Bridges.AbstractBridge) = b
function MOI.Utilities.map_indices(
::Function,
::FirstBridge,
b::MOI.Bridges.AbstractBridge,
)
return b
end
2 changes: 2 additions & 0 deletions src/Utilities/model.jl
Original file line number Diff line number Diff line change
Expand Up @@ -795,6 +795,8 @@ const LessThanIndicatorZero{T} =
MOI.ScaledPositiveSemidefiniteConeTriangle,
MOI.RootDetConeTriangle,
MOI.RootDetConeSquare,
MOI.FrobeniusProductPostiviveSemidefiniteConeTriangle,
MOI.LinearMatrixInequalityConeTriangle,
MOI.LogDetConeTriangle,
MOI.LogDetConeSquare,
MOI.AllDifferent,
Expand Down
35 changes: 28 additions & 7 deletions src/Utilities/results.jl
Original file line number Diff line number Diff line change
Expand Up @@ -500,11 +500,7 @@ end
Return the scalar product between a vector `x` of the set `set` and a vector
`y` of the dual of the set `s`.
"""
function set_dot(
x::AbstractVector,
y::AbstractVector,
set::MOI.AbstractVectorSet,
)
function set_dot(x::AbstractVector, y::AbstractVector, ::MOI.AbstractVectorSet)
return dot(x, y)
end

Expand All @@ -514,7 +510,7 @@ end
Return the scalar product between a number `x` of the set `set` and a number
`y` of the dual of the set `s`.
"""
set_dot(x, y, set::MOI.AbstractScalarSet) = dot(x, y)
set_dot(x, y, ::MOI.AbstractScalarSet) = dot(x, y)

function triangle_dot(
x::AbstractVector{S},
Expand Down Expand Up @@ -575,13 +571,26 @@ function set_dot(
return x[1] * y[1] + x[2] * y[2] + triangle_dot(x, y, set.side_dimension, 2)
end

function set_dot(
x::AbstractVector,
y::AbstractVector,
set::Union{
MOI.FrobeniusProductPostiviveSemidefiniteConeTriangle,
MOI.LinearMatrixInequalityConeTriangle,
},
)
m = length(set.matrices)
return LinearAlgebra.dot(view(x, 1:m), view(y, 1:m)) +
triangle_dot(x, y, set.side_dimension, m)
end

"""
dot_coefficients(a::AbstractVector, set::AbstractVectorSet)
Return the vector `b` such that for all vector `x` of the set `set`,
`set_dot(b, x, set)` is equal to `dot(a, x)`.
"""
function dot_coefficients(a::AbstractVector, set::MOI.AbstractVectorSet)
function dot_coefficients(a::AbstractVector, ::MOI.AbstractVectorSet)
return a
end

Expand Down Expand Up @@ -633,3 +642,15 @@ function dot_coefficients(a::AbstractVector, set::MOI.LogDetConeTriangle)
triangle_coefficients!(b, set.side_dimension, 2)
return b
end

function set_dot(
a::AbstractVector,
set::Union{
MOI.FrobeniusProductPostiviveSemidefiniteConeTriangle,
MOI.LinearMatrixInequalityConeTriangle,
},
)
b = copy(a)
triangle_coefficients!(b, set.side_dimension, length(set.matrices))
return b
end
59 changes: 57 additions & 2 deletions src/sets.jl
Original file line number Diff line number Diff line change
Expand Up @@ -880,7 +880,7 @@ MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInte
"""
struct ExponentialCone <: AbstractVectorSet end

dual_set(s::ExponentialCone) = DualExponentialCone()
dual_set(::ExponentialCone) = DualExponentialCone()
dual_set_type(::Type{ExponentialCone}) = DualExponentialCone

dimension(::ExponentialCone) = 3
Expand All @@ -906,7 +906,7 @@ MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInte
"""
struct DualExponentialCone <: AbstractVectorSet end

dual_set(s::DualExponentialCone) = ExponentialCone()
dual_set(::DualExponentialCone) = ExponentialCone()
dual_set_type(::Type{DualExponentialCone}) = ExponentialCone

dimension(::DualExponentialCone) = 3
Expand Down Expand Up @@ -1735,6 +1735,61 @@ function triangular_form(set::RootDetConeSquare)
return RootDetConeTriangle(set.side_dimension)
end

"""
FrobeniusProductPostiviveSemidefiniteConeTriangle{M}(side_dimension::Int, matrices::Vector{M})
Given `m` symmetric matrices `A_1`, ..., `A_m` given in `matrices`, the frobenius inner
product of positive semidefinite matrices is the convex cone:
``\\{ ((\\langle A_1, X \\rangle, ..., \\langle A_m, X \\rangle, X) \\in \\mathbb{R}^{m + d(d+1)/2} : X \\text{ postive semidefinite} \\}``,
where the matrix `X` is represented in the same symmetric packed format as in
the [`PositiveSemidefiniteConeTriangle`](@ref).
"""
struct FrobeniusProductPostiviveSemidefiniteConeTriangle{M} <: AbstractVectorSet
side_dimension::Int
matrices::Vector{M}
end

function dimension(s::FrobeniusProductPostiviveSemidefiniteConeTriangle)
return length(s.matrices) + s.side_dimension^2
end

function dual_set(s::FrobeniusProductPostiviveSemidefiniteConeTriangle)
return LinearMatrixInequalityConeTriangle(s.side_dimension, s.matrices)
end

function dual_set_type(
::Type{FrobeniusProductPostiviveSemidefiniteConeTriangle{M}},
) where {M}
return LinearMatrixInequalityConeTriangle
end

"""
LinearMatrixInequalityConeTriangle{M}(side_dimension::Int, matrices::Vector{M})
Given `m` symmetric matrices `A_1`, ..., `A_m` given in `matrices`, the linear
matrix inequality cone is the convex cone:
``\\{ ((y, C) \\in \\mathbb{R}^{m + d(d+1)/2} : \\sum_{i=1}^m y_i A_i + C \\text{ postive semidefinite} \\}``,
where the matrix `C` is represented in the same symmetric packed format as in
the [`PositiveSemidefiniteConeTriangle`](@ref).
"""
struct LinearMatrixInequalityConeTriangle{M} <: AbstractVectorSet
side_dimension::Int
matrices::Vector{M}
end

dimension(s::LinearMatrixInequalityConeTriangle) = length(s.matrices) + s.side_dimension^2

function dual_set(s::LinearMatrixInequalityConeTriangle)
return FrobeniusProductPostiviveSemidefiniteConeTriangle(
s.side_dimension,
s.matrices,
)
end

function dual_set_type(::Type{LinearMatrixInequalityConeTriangle{M}}) where {M}
return FrobeniusProductPostiviveSemidefiniteConeTriangle
end

"""
SOS1{T<:Real}(weights::Vector{T})
Expand Down

0 comments on commit 5defcea

Please sign in to comment.