Skip to content

Commit 5defcea

Browse files
committed
Add set for low-rank constrained SDP
1 parent d48ac54 commit 5defcea

File tree

7 files changed

+115
-11
lines changed

7 files changed

+115
-11
lines changed

docs/src/background/duality.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,9 @@ and similarly, the dual is:
113113

114114
The scalar product is different from the canonical one for the sets
115115
[`PositiveSemidefiniteConeTriangle`](@ref), [`LogDetConeTriangle`](@ref),
116-
[`RootDetConeTriangle`](@ref).
116+
[`RootDetConeTriangle`](@ref),
117+
[`FrobeniusProductPostiviveSemidefiniteConeTriangle`](@ref) and
118+
[`LinearMatrixInequalityConeTriangle`](@ref).
117119

118120
If the set ``C_i`` of the section [Duality](@ref) is one of these three cones,
119121
then the rows of the matrix ``A_i`` corresponding to off-diagonal entries are

docs/src/manual/standard_form.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,8 @@ The matrix-valued set types implemented in MathOptInterface.jl are:
9898
| [`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} \}``
9999
| [`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} \}`` |
100100
| [`HermitianPositiveSemidefiniteConeTriangle(d)`](@ref MathOptInterface.HermitianPositiveSemidefiniteConeTriangle) | The cone of Hermitian positive semidefinite matrices, with
101-
`side_dimension` rows and columns. |
101+
| [`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`. |
102+
| [`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. |
102103

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

docs/src/reference/standard_form.md

+2
Original file line numberDiff line numberDiff line change
@@ -152,4 +152,6 @@ LogDetConeTriangle
152152
LogDetConeSquare
153153
RootDetConeTriangle
154154
RootDetConeSquare
155+
FrobeniusProductPostiviveSemidefiniteConeTriangle
156+
LinearMatrixInequalityConeTriangle
155157
```

src/Bridges/bridge.jl

+21
Original file line numberDiff line numberDiff line change
@@ -283,3 +283,24 @@ If you implement this method, you must also implement
283283
[`needs_final_touch`](@ref).
284284
"""
285285
function final_touch end
286+
287+
"""
288+
struct FirstBridge <: MOI.AbstractConstraintAttribute end
289+
290+
Returns the first bridge used to bridge the constraint.
291+
292+
!!! warning
293+
The indices of the bridge correspond to internal indices and may not
294+
correspond to indices of the model this attribute is got from.
295+
"""
296+
struct FirstBridge <: MOI.AbstractConstraintAttribute end
297+
298+
MOI.is_set_by_optimize(::FirstBridge) = true
299+
MOI.get(::MOI.ModelLike, ::FirstBridge, b::MOI.Bridges.AbstractBridge) = b
300+
function MOI.Utilities.map_indices(
301+
::Function,
302+
::FirstBridge,
303+
b::MOI.Bridges.AbstractBridge,
304+
)
305+
return b
306+
end

src/Utilities/model.jl

+2
Original file line numberDiff line numberDiff line change
@@ -795,6 +795,8 @@ const LessThanIndicatorZero{T} =
795795
MOI.ScaledPositiveSemidefiniteConeTriangle,
796796
MOI.RootDetConeTriangle,
797797
MOI.RootDetConeSquare,
798+
MOI.FrobeniusProductPostiviveSemidefiniteConeTriangle,
799+
MOI.LinearMatrixInequalityConeTriangle,
798800
MOI.LogDetConeTriangle,
799801
MOI.LogDetConeSquare,
800802
MOI.AllDifferent,

src/Utilities/results.jl

+28-7
Original file line numberDiff line numberDiff line change
@@ -500,11 +500,7 @@ end
500500
Return the scalar product between a vector `x` of the set `set` and a vector
501501
`y` of the dual of the set `s`.
502502
"""
503-
function set_dot(
504-
x::AbstractVector,
505-
y::AbstractVector,
506-
set::MOI.AbstractVectorSet,
507-
)
503+
function set_dot(x::AbstractVector, y::AbstractVector, ::MOI.AbstractVectorSet)
508504
return dot(x, y)
509505
end
510506

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

519515
function triangle_dot(
520516
x::AbstractVector{S},
@@ -575,13 +571,26 @@ function set_dot(
575571
return x[1] * y[1] + x[2] * y[2] + triangle_dot(x, y, set.side_dimension, 2)
576572
end
577573

574+
function set_dot(
575+
x::AbstractVector,
576+
y::AbstractVector,
577+
set::Union{
578+
MOI.FrobeniusProductPostiviveSemidefiniteConeTriangle,
579+
MOI.LinearMatrixInequalityConeTriangle,
580+
},
581+
)
582+
m = length(set.matrices)
583+
return LinearAlgebra.dot(view(x, 1:m), view(y, 1:m)) +
584+
triangle_dot(x, y, set.side_dimension, m)
585+
end
586+
578587
"""
579588
dot_coefficients(a::AbstractVector, set::AbstractVectorSet)
580589
581590
Return the vector `b` such that for all vector `x` of the set `set`,
582591
`set_dot(b, x, set)` is equal to `dot(a, x)`.
583592
"""
584-
function dot_coefficients(a::AbstractVector, set::MOI.AbstractVectorSet)
593+
function dot_coefficients(a::AbstractVector, ::MOI.AbstractVectorSet)
585594
return a
586595
end
587596

@@ -633,3 +642,15 @@ function dot_coefficients(a::AbstractVector, set::MOI.LogDetConeTriangle)
633642
triangle_coefficients!(b, set.side_dimension, 2)
634643
return b
635644
end
645+
646+
function set_dot(
647+
a::AbstractVector,
648+
set::Union{
649+
MOI.FrobeniusProductPostiviveSemidefiniteConeTriangle,
650+
MOI.LinearMatrixInequalityConeTriangle,
651+
},
652+
)
653+
b = copy(a)
654+
triangle_coefficients!(b, set.side_dimension, length(set.matrices))
655+
return b
656+
end

src/sets.jl

+57-2
Original file line numberDiff line numberDiff line change
@@ -880,7 +880,7 @@ MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInte
880880
"""
881881
struct ExponentialCone <: AbstractVectorSet end
882882

883-
dual_set(s::ExponentialCone) = DualExponentialCone()
883+
dual_set(::ExponentialCone) = DualExponentialCone()
884884
dual_set_type(::Type{ExponentialCone}) = DualExponentialCone
885885

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

909-
dual_set(s::DualExponentialCone) = ExponentialCone()
909+
dual_set(::DualExponentialCone) = ExponentialCone()
910910
dual_set_type(::Type{DualExponentialCone}) = ExponentialCone
911911

912912
dimension(::DualExponentialCone) = 3
@@ -1735,6 +1735,61 @@ function triangular_form(set::RootDetConeSquare)
17351735
return RootDetConeTriangle(set.side_dimension)
17361736
end
17371737

1738+
"""
1739+
FrobeniusProductPostiviveSemidefiniteConeTriangle{M}(side_dimension::Int, matrices::Vector{M})
1740+
1741+
Given `m` symmetric matrices `A_1`, ..., `A_m` given in `matrices`, the frobenius inner
1742+
product of positive semidefinite matrices is the convex cone:
1743+
``\\{ ((\\langle A_1, X \\rangle, ..., \\langle A_m, X \\rangle, X) \\in \\mathbb{R}^{m + d(d+1)/2} : X \\text{ postive semidefinite} \\}``,
1744+
where the matrix `X` is represented in the same symmetric packed format as in
1745+
the [`PositiveSemidefiniteConeTriangle`](@ref).
1746+
"""
1747+
struct FrobeniusProductPostiviveSemidefiniteConeTriangle{M} <: AbstractVectorSet
1748+
side_dimension::Int
1749+
matrices::Vector{M}
1750+
end
1751+
1752+
function dimension(s::FrobeniusProductPostiviveSemidefiniteConeTriangle)
1753+
return length(s.matrices) + s.side_dimension^2
1754+
end
1755+
1756+
function dual_set(s::FrobeniusProductPostiviveSemidefiniteConeTriangle)
1757+
return LinearMatrixInequalityConeTriangle(s.side_dimension, s.matrices)
1758+
end
1759+
1760+
function dual_set_type(
1761+
::Type{FrobeniusProductPostiviveSemidefiniteConeTriangle{M}},
1762+
) where {M}
1763+
return LinearMatrixInequalityConeTriangle
1764+
end
1765+
1766+
"""
1767+
LinearMatrixInequalityConeTriangle{M}(side_dimension::Int, matrices::Vector{M})
1768+
1769+
Given `m` symmetric matrices `A_1`, ..., `A_m` given in `matrices`, the linear
1770+
matrix inequality cone is the convex cone:
1771+
``\\{ ((y, C) \\in \\mathbb{R}^{m + d(d+1)/2} : \\sum_{i=1}^m y_i A_i + C \\text{ postive semidefinite} \\}``,
1772+
where the matrix `C` is represented in the same symmetric packed format as in
1773+
the [`PositiveSemidefiniteConeTriangle`](@ref).
1774+
"""
1775+
struct LinearMatrixInequalityConeTriangle{M} <: AbstractVectorSet
1776+
side_dimension::Int
1777+
matrices::Vector{M}
1778+
end
1779+
1780+
dimension(s::LinearMatrixInequalityConeTriangle) = length(s.matrices) + s.side_dimension^2
1781+
1782+
function dual_set(s::LinearMatrixInequalityConeTriangle)
1783+
return FrobeniusProductPostiviveSemidefiniteConeTriangle(
1784+
s.side_dimension,
1785+
s.matrices,
1786+
)
1787+
end
1788+
1789+
function dual_set_type(::Type{LinearMatrixInequalityConeTriangle{M}}) where {M}
1790+
return FrobeniusProductPostiviveSemidefiniteConeTriangle
1791+
end
1792+
17381793
"""
17391794
SOS1{T<:Real}(weights::Vector{T})
17401795

0 commit comments

Comments
 (0)