Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add set for low-rank constrained SDP #2198

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
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),
[`SetWithDotProducts`](@ref) and
[`LinearCombinationInSet`](@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
2 changes: 2 additions & 0 deletions docs/src/manual/standard_form.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ The vector-valued set types implemented in MathOptInterface.jl are:
| [`RelativeEntropyCone(d)`](@ref MathOptInterface.RelativeEntropyCone) | ``\{ (u, v, w) \in \mathbb{R}^{d} : u \ge \sum_i w_i \log (\frac{w_i}{v_i}), v_i \ge 0, w_i \ge 0 \}`` |
| [`HyperRectangle(l, u)`](@ref MathOptInterface.HyperRectangle) | ``\{x \in \bar{\mathbb{R}}^d: x_i \in [l_i, u_i] \forall i=1,\ldots,d\}`` |
| [`NormCone(p, d)`](@ref MathOptInterface.NormCone) | ``\{ (t,x) \in \mathbb{R}^{d} : t \ge \left(\sum\limits_i \lvert x_i \rvert^p\right)^{\frac{1}{p}} \}`` |
| [`SetWithDotProcuts(s, v)`](@ref MathOptInterface.SetWithDotProducts) | The cone `s` with dot products with the fixed vectors `v`. |
blegat marked this conversation as resolved.
Show resolved Hide resolved
| [`LinearCombinationInSet(s, v)`](@ref MathOptInterface.LinearCombinationInSet) | The cone of vector `(y, x)` such that ``\sum_i y_i v_i + x`` belongs to `s`. |

## Matrix cones

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 @@ -153,4 +153,6 @@ LogDetConeTriangle
LogDetConeSquare
RootDetConeTriangle
RootDetConeSquare
SetWithDotProducts,
LinearCombinationInSet,
```
20 changes: 20 additions & 0 deletions src/Utilities/set_dot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,16 @@ 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.SetWithDotProducts,MOI.LinearCombinationInSet},
)
m = length(set.matrices)
return LinearAlgebra.dot(view(x, 1:m), view(y, 1:m)) +
set_dot(view(x, (m+1):length(x)), view(y, (m+1):length(y)), set.set)
end

"""
dot_coefficients(a::AbstractVector, set::AbstractVectorSet)

Expand Down Expand Up @@ -145,6 +155,16 @@ function dot_coefficients(a::AbstractVector, set::MOI.LogDetConeTriangle)
return b
end

function dot_coefficients(
a::AbstractVector,
set::Union{MOI.SetWithDotProducts,MOI.LinearCombinationInSet},
)
b = copy(a)
m = length(set.vectors)
b[(m+1):end] = dot_coefficients(b[(m+1):end], set.set)
return b
end

# For `SetDotScalingVector`, we would like to compute the dot product
# of canonical vectors in O(1) instead of O(n)
# See https://github.com/jump-dev/Dualization.jl/pull/135
Expand Down
44 changes: 44 additions & 0 deletions src/sets.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1791,6 +1791,50 @@ function Base.getproperty(
end
end

"""
SetWithDotProducts(set, vectors::Vector{V})

Given a set `set` of dimension `d` and `m` vectors `v_1`, ..., `v_m` given in `vectors`, this is the set:
``\\{ ((\\langle v_1, x \\rangle, ..., \\langle v_m, x \\rangle, x) \\in \\mathbb{R}^{m + d} : x \\in \\text{set} \\}.``
"""
struct SetWithDotProducts{S,V} <: AbstractVectorSet
set::S
vectors::Vector{V}
end

function dimension(s::SetWithDotProducts)
return length(s.vectors) + dimension(s.set)
end

function dual_set(s::SetWithDotProducts)
return LinearCombinationInSet(s.set, s.vectors)
end

function dual_set_type(::Type{SetWithDotProducts{S,V}}) where {S,V}
return LinearCombinationInSet{S,V}
end

"""
LinearCombinationInSet{S,V}(set::S, matrices::Vector{V})

Given a set `set` of dimension `d` and `m` vectors `v_1`, ..., `v_m` given in `vectors`, this is the set:
``\\{ ((y, x) \\in \\mathbb{R}^{m + d} : \\sum_{i=1}^m y_i v_i + x \\in \\text{set} \\}.``
"""
struct LinearCombinationInSet{S,V} <: AbstractVectorSet
set::S
vectors::Vector{V}
end

dimension(s::LinearCombinationInSet) = length(s.vectors) + simension(s.set)

function dual_set(s::LinearCombinationInSet)
return SetWithDotProducts(s.side_dimension, s.matrices)
end

function dual_set_type(::Type{LinearCombinationInSet{S,V}}) where {S,V}
return SetWithDotProducts{S,V}
end

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

Expand Down
Loading