diff --git a/src/Bridges/Constraint/bridges/QuadtoSOCBridge.jl b/src/Bridges/Constraint/bridges/QuadtoSOCBridge.jl index 23431d0645..437547c006 100644 --- a/src/Bridges/Constraint/bridges/QuadtoSOCBridge.jl +++ b/src/Bridges/Constraint/bridges/QuadtoSOCBridge.jl @@ -80,22 +80,32 @@ function compute_sparse_sqrt_fallback(Q, ::F, ::S) where {F,S} end function compute_sparse_sqrt(Q, func, set) - factor = try - LinearAlgebra.cholesky(Q; check = false) - catch - msg = "There was an error computing a Cholesky decomposition" + # There's a big try-catch here because Cholesky can fail even if + # `check = false`. As one example, it currently (v1.12) fails with + # `BigFloat`. Similarly, we want to guard against errors in + # `compute_sparse_sqrt_fallback`. + # + # The try-catch isn't a performance concern because the alternative is not + # being able to reformulate the problem. + try + factor = LinearAlgebra.cholesky(Q; check = false) + if !LinearAlgebra.issuccess(factor) + return compute_sparse_sqrt_fallback(Q, func, set) + end + L, p = SparseArrays.sparse(factor.L), factor.p + # We have Q = P' * L * L' * P. We want to find Q = U' * U, so U = L' * P + # First, compute L'. Note I and J are reversed + J, I, V = SparseArrays.findnz(L) + # Then, we want to permute the columns of L'. The rows stay in the same + # order. + return I, p[J], V + catch err + if err isa MOI.AddConstraintNotAllowed + rethrow(err) + end + msg = "There was an error computing a matrix square root" throw(MOI.UnsupportedConstraint{typeof(func),typeof(set)}(msg)) end - if !LinearAlgebra.issuccess(factor) - return compute_sparse_sqrt_fallback(Q, func, set) - end - L, p = SparseArrays.sparse(factor.L), factor.p - # We have Q = P' * L * L' * P. We want to find Q = U' * U, so U = L' * P - # First, compute L'. Note I and J are reversed - J, I, V = SparseArrays.findnz(L) - # Then, we want to permute the columns of L'. The rows stay in the same - # order. - return I, p[J], V end function bridge_constraint(