@@ -489,3 +489,39 @@ function distance_to_set(
489489 elements = [x[i] for i in eachindex (x) if ! (i in pairs[k])]
490490 return LinearAlgebra. norm (elements, 2 )
491491end
492+
493+ function _reshape (x:: AbstractVector , set:: MOI.PositiveSemidefiniteConeSquare )
494+ n = MOI. side_dimension (set)
495+ return reshape (x, (n, n))
496+ end
497+
498+ function _reshape (x:: AbstractVector , set:: MOI.PositiveSemidefiniteConeTriangle )
499+ n = MOI. side_dimension (set)
500+ X = zeros (eltype (x), n, n)
501+ k = 1
502+ for i in 1 : n
503+ for j in 1 : i
504+ X[j,i] = X[i,j] = x[k]
505+ k += 1
506+ end
507+ end
508+ return LinearAlgebra. Symmetric (X)
509+ end
510+
511+ function distance_to_set (
512+ :: ProjectionUpperBoundDistance ,
513+ x:: AbstractVector{T} ,
514+ set:: Union {
515+ MOI. PositiveSemidefiniteConeSquare,
516+ MOI. PositiveSemidefiniteConeTriangle,
517+ },
518+ ) where {T<: Real }
519+ _check_dimension (x, set)
520+ λ, U = LinearAlgebra. eigen (_reshape (x, set))
521+ if minimum (λ) >= 0
522+ return 0.0
523+ end
524+ λ_negative = LinearAlgebra. Diagonal (min .(zero (T), λ))
525+ A = LinearAlgebra. Symmetric (U * λ_negative * U' )
526+ return LinearAlgebra. norm (A, 2 )
527+ end
0 commit comments