6060const QuadtoSOC{T,OT<: MOI.ModelLike } =
6161 SingleBridgeOptimizer{QuadtoSOCBridge{T},OT}
6262
63- function compute_sparse_sqrt_fallback (Q, :: F , :: S ) where {F,S}
64- msg = """
63+ function _error_msg ( :: MOI.Utilities.LDLFactorizationsExt )
64+ return """
6565 Unable to transform a quadratic constraint into a SecondOrderCone
6666 constraint because the quadratic constraint is not strongly convex and
6767 our Cholesky decomposition failed.
@@ -76,36 +76,41 @@ function compute_sparse_sqrt_fallback(Q, ::F, ::S) where {F,S}
7676 LDLFactorizations.jl is not included by default because it is licensed
7777 under the LGPL.
7878 """
79- return throw (MOI. AddConstraintNotAllowed {F,S} (msg))
8079end
8180
82- function compute_sparse_sqrt (Q, func, set)
83- # There's a big try-catch here because Cholesky can fail even if
84- # `check = false`. As one example, it currently (v1.12) fails with
85- # `BigFloat`. Similarly, we want to guard against errors in
86- # `compute_sparse_sqrt_fallback`.
87- #
88- # The try-catch isn't a performance concern because the alternative is not
89- # being able to reformulate the problem.
90- try
91- factor = LinearAlgebra. cholesky (Q; check = false )
92- if ! LinearAlgebra. issuccess (factor)
93- return compute_sparse_sqrt_fallback (Q, func, set)
94- end
95- L, p = SparseArrays. sparse (factor. L), factor. p
96- # We have Q = P' * L * L' * P. We want to find Q = U' * U, so U = L' * P
97- # First, compute L'. Note I and J are reversed
98- J, I, V = SparseArrays. findnz (L)
99- # Then, we want to permute the columns of L'. The rows stay in the same
100- # order.
101- return I, p[J], V
102- catch err
103- if err isa MOI. AddConstraintNotAllowed
104- rethrow (err)
105- end
106- msg = " There was an error computing a matrix square root"
107- throw (MOI. UnsupportedConstraint {typeof(func),typeof(set)} (msg))
81+ function _error_msg (:: MOI.Utilities.CliqueTreesExt )
82+ return """
83+ Unable to transform a quadratic constraint into a SecondOrderCone
84+ constraint because the quadratic constraint is not strongly convex and
85+ our Cholesky decomposition failed.
86+
87+ If the constraint is convex but not strongly convex, you can work-around
88+ this issue by manually installing and loading `CliqueTrees.jl`:
89+ ```julia
90+ import Pkg; Pkg.add("CliqueTrees")
91+ using CliqueTrees
92+ ```
93+
94+ CliqueTrees.jl is not included by default because it contains a number of
95+ heavy dependencies.
96+ """
97+ end
98+
99+ function compute_sparse_sqrt (Q, :: F , :: S ) where {F,S}
100+ if (ret = MOI. Utilities. compute_sparse_sqrt (Q)) != = nothing
101+ return ret
102+ elseif ! MOI. Utilities. is_defined (MOI. Utilities. LDLFactorizationsExt ())
103+ msg = _error_msg (MOI. Utilities. LDLFactorizationsExt ())
104+ return throw (MOI. AddConstraintNotAllowed {F,S} (msg))
105+ elseif ! MOI. Utilities. is_defined (MOI. Utilities. CliqueTreesExt ())
106+ msg = _error_msg (MOI. Utilities. CliqueTreesExt ())
107+ return throw (MOI. AddConstraintNotAllowed {F,S} (msg))
108108 end
109+ msg = """
110+ Unable to transform a quadratic constraint into a SecondOrderCone
111+ constraint because the quadratic constraint is not convex.
112+ """
113+ return throw (MOI. UnsupportedConstraint {F,S} (msg))
109114end
110115
111116function bridge_constraint (
0 commit comments