Skip to content

Commit

Permalink
[Utilities] add distance_to_set for SecondOrderCone (#2060)
Browse files Browse the repository at this point in the history
  • Loading branch information
odow authored Feb 4, 2023
1 parent 38fc9e4 commit 79081f0
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 0 deletions.
20 changes: 20 additions & 0 deletions src/Utilities/distance_to_set.jl
Original file line number Diff line number Diff line change
Expand Up @@ -193,3 +193,23 @@ function distance_to_set(
_check_dimension(x, set)
return zero(T)
end

function distance_to_set(
::ProjectionUpperBoundDistance,
x::AbstractVector{T},
set::MOI.SecondOrderCone,
) where {T<:Real}
_check_dimension(x, set)
# Projections come from:
# Parikh, N., & Boyd, S. (2014). Proximal algorithms. Foundations and
# trends in Optimization, page 184, section 6.3.2.
t, rhs = x[1], LinearAlgebra.norm(@views x[2:end])
if t >= rhs
return zero(T) # The point is feasible!
end
if rhs <= -t # Projection to the point (0, [0])
return LinearAlgebra.norm(x)
end
# Projection to the point (t, x) + 0.5 * (|x|_2 - t, (t/|x|_2 - 1) * x)
return sqrt(2) / 2 * abs(t - rhs)
end
16 changes: 16 additions & 0 deletions test/Utilities/distance_to_set.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module TestFeasibilityChecker

using Test

import LinearAlgebra
import MathOptInterface

const MOI = MathOptInterface
Expand Down Expand Up @@ -127,6 +128,21 @@ function test_zeros()
return
end

function test_secondordercone()
@test_throws(
DimensionMismatch,
MOI.Utilities.distance_to_set([-1.0, 1.0], MOI.SecondOrderCone(3))
)
set = MOI.SecondOrderCone(3)
@test MOI.Utilities.distance_to_set([sqrt(2), 1, 1], set) 0.0
@test MOI.Utilities.distance_to_set([-sqrt(2), 1, 1], set) 2
@test MOI.Utilities.distance_to_set([-2, 1, 1], set) sqrt(6)
# According to Boyd, (t, x) = (1, [1, 1]), projects to:
d = ((1 / 2) * (1 + 1 / 2) * [2, 1, 1]) .- [1, 1, 1]
@test MOI.Utilities.distance_to_set([1, 1, 1], set) LinearAlgebra.norm(d)
return
end

end

TestFeasibilityChecker.runtests()

0 comments on commit 79081f0

Please sign in to comment.