@@ -31,13 +31,19 @@ function test_error_for_nonconvex_quadratic_constraints()
3131 model = MOI. Bridges. Constraint. QuadtoSOC {Float64} (inner)
3232 x = MOI. add_variable (model)
3333 F = MOI. ScalarQuadraticFunction{Float64}
34+ # Error is now thrown at final_touch, not add_constraint
35+ MOI. add_constraint (model, 1.0 * x * x, MOI. GreaterThan (0.0 ))
3436 @test_throws (
3537 MOI. UnsupportedConstraint{F,MOI. GreaterThan{Float64}},
36- MOI. add_constraint (model, 1.0 * x * x, MOI . GreaterThan ( 0.0 ))
38+ MOI. Bridges . final_touch (model),
3739 )
40+ MOI. empty! (model)
41+ MOI. add_variable (model)
42+ x = MOI. get (model, MOI. ListOfVariableIndices ())[1 ]
43+ MOI. add_constraint (model, - 1.0 * x * x, MOI. LessThan (0.0 ))
3844 @test_throws (
3945 MOI. UnsupportedConstraint{F,MOI. LessThan{Float64}},
40- MOI. add_constraint (model, - 1.0 * x * x, MOI . LessThan ( 0.0 ))
46+ MOI. Bridges . final_touch (model),
4147 )
4248 return
4349end
@@ -65,6 +71,7 @@ function test_quadratic_constraints_with_2_variables()
6571 ),
6672 )
6773 MOI. Test. test_constraint_qcp_duplicate_off_diagonal (bridged_mock, config)
74+ MOI. Bridges. final_touch (bridged_mock)
6875 ci = first (
6976 MOI. get (
7077 mock,
@@ -164,6 +171,7 @@ function test_fill_reducing_permutation()
164171 Q = Float64[2 1 1 ; 1 2 0 ; 1 0 2 ]
165172 f = 0.5 * x' * Q * x
166173 MOI. add_constraint (bridge, f, MOI. LessThan (2.0 ))
174+ MOI. Bridges. final_touch (bridge)
167175 indices = MOI. get (
168176 model,
169177 MOI. ListOfConstraintIndices{
@@ -331,6 +339,7 @@ function test_semidefinite_cholesky_fail()
331339 x = MOI. add_variables (model, 2 )
332340 f = 0.5 * x[1 ] * x[1 ] + 1.0 * x[1 ] * x[2 ] + 0.5 * x[2 ] * x[2 ]
333341 c = MOI. add_constraint (model, f, MOI. LessThan (1.0 ))
342+ MOI. Bridges. final_touch (model)
334343 F, S = MOI. VectorAffineFunction{Float64}, MOI. RotatedSecondOrderCone
335344 ci = only (MOI. get (inner, MOI. ListOfConstraintIndices {F,S} ()))
336345 g = MOI. get (inner, MOI. ConstraintFunction (), ci)
@@ -435,6 +444,7 @@ function test_clique_trees_semidefinite_cholesky_fail()
435444 x = MOI. add_variables (model, 2 )
436445 f = 0.5 * x[1 ] * x[1 ] + 1.0 * x[1 ] * x[2 ] + 0.5 * x[2 ] * x[2 ]
437446 c = MOI. add_constraint (model, f, MOI. LessThan (1.0 ))
447+ MOI. Bridges. final_touch (model)
438448 F, S = MOI. VectorAffineFunction{Float64}, MOI. RotatedSecondOrderCone
439449 ci = only (MOI. get (inner, MOI. ListOfConstraintIndices {F,S} ()))
440450 g = MOI. get (inner, MOI. ConstraintFunction (), ci)
@@ -454,6 +464,7 @@ function test_clique_trees_early_zero_pivot()
454464 # Q = [1 1 0; 1 1 0; 0 0 1]
455465 f = sum (0.5 * x[i] * x[i] for i in 1 : 3 ) + 1.0 * x[1 ] * x[2 ]
456466 c = MOI. add_constraint (model, f, MOI. LessThan (1.0 ))
467+ MOI. Bridges. final_touch (model)
457468 F, S = MOI. VectorAffineFunction{Float64}, MOI. RotatedSecondOrderCone
458469 ci = only (MOI. get (inner, MOI. ListOfConstraintIndices {F,S} ()))
459470 g = MOI. get (inner, MOI. ConstraintFunction (), ci)
@@ -482,6 +493,68 @@ function test_is_defined_default_fallback()
482493 return
483494end
484495
496+ function test_quad_to_soc_square_root_attribute ()
497+ inner = MOI. Utilities. Model {Float64} ()
498+ model = MOI. Bridges. Constraint. QuadtoSOC {Float64} (inner)
499+ x = MOI. add_variables (model, 2 )
500+ f = 1.0 * x[1 ] * x[1 ] + 1.0 * x[2 ] * x[2 ]
501+ c = MOI. add_constraint (model, f, MOI. LessThan (1.0 ))
502+ attr = MOI. Bridges. Constraint. QuadtoSOCSquareRoot ()
503+ F = MOI. ScalarQuadraticFunction{Float64}
504+ S = MOI. LessThan{Float64}
505+ @test MOI. supports (model, attr, MOI. ConstraintIndex{F,S})
506+ # Default is nothing
507+ @test MOI. get (model, attr, c) === nothing
508+ # Set to _LinearAlgebra
509+ la = MOI. Bridges. Constraint. _LinearAlgebra ()
510+ MOI. set (model, attr, c, la)
511+ @test MOI. get (model, attr, c) === la
512+ # final_touch uses the specified method
513+ MOI. Bridges. final_touch (model)
514+ F2, S2 = MOI. VectorAffineFunction{Float64}, MOI. RotatedSecondOrderCone
515+ ci = only (MOI. get (inner, MOI. ListOfConstraintIndices {F2,S2} ()))
516+ g = MOI. get (inner, MOI. ConstraintFunction (), ci)
517+ @test MOI. output_dimension (g) == 4 # [1, rhs, Ux...]
518+ return
519+ end
520+
521+ function test_quad_to_soc_square_root_attribute_clique_trees ()
522+ inner = MOI. Utilities. Model {Float64} ()
523+ model = MOI. Bridges. Constraint. QuadtoSOC {Float64} (inner)
524+ x = MOI. add_variables (model, 2 )
525+ f = 1.0 * x[1 ] * x[1 ] + 1.0 * x[2 ] * x[2 ]
526+ c = MOI. add_constraint (model, f, MOI. LessThan (1.0 ))
527+ attr = MOI. Bridges. Constraint. QuadtoSOCSquareRoot ()
528+ ct = MOI. Bridges. Constraint. _CliqueTrees ()
529+ MOI. set (model, attr, c, ct)
530+ @test MOI. get (model, attr, c) === ct
531+ MOI. Bridges. final_touch (model)
532+ F, S = MOI. VectorAffineFunction{Float64}, MOI. RotatedSecondOrderCone
533+ ci = only (MOI. get (inner, MOI. ListOfConstraintIndices {F,S} ()))
534+ g = MOI. get (inner, MOI. ConstraintFunction (), ci)
535+ @test MOI. output_dimension (g) == 4
536+ return
537+ end
538+
539+ function test_quad_to_soc_square_root_attribute_reset ()
540+ inner = MOI. Utilities. Model {Float64} ()
541+ model = MOI. Bridges. Constraint. QuadtoSOC {Float64} (inner)
542+ x = MOI. add_variables (model, 2 )
543+ f = 1.0 * x[1 ] * x[1 ] + 1.0 * x[2 ] * x[2 ]
544+ c = MOI. add_constraint (model, f, MOI. LessThan (1.0 ))
545+ attr = MOI. Bridges. Constraint. QuadtoSOCSquareRoot ()
546+ la = MOI. Bridges. Constraint. _LinearAlgebra ()
547+ MOI. set (model, attr, c, la)
548+ # Reset to nothing (default behavior)
549+ MOI. set (model, attr, c, nothing )
550+ @test MOI. get (model, attr, c) === nothing
551+ MOI. Bridges. final_touch (model)
552+ F, S = MOI. VectorAffineFunction{Float64}, MOI. RotatedSecondOrderCone
553+ ci = only (MOI. get (inner, MOI. ListOfConstraintIndices {F,S} ()))
554+ @test ci isa MOI. ConstraintIndex
555+ return
556+ end
557+
485558end # module
486559
487560TestConstraintQuadToSOC. runtests ()
0 commit comments