@@ -2592,7 +2592,7 @@ function _det1test(model::MOI.ModelLike, config::TestConfig, vecofvars::Bool, de
25922592 atol = config. atol
25932593 rtol = config. rtol
25942594 square = detcone == MOI. LogDetConeSquare || detcone == MOI. RootDetConeSquare
2595- logdet = detcone == MOI. LogDetConeTriangle || detcone == MOI. LogDetConeSquare
2595+ use_logdet = detcone == MOI. LogDetConeTriangle || detcone == MOI. LogDetConeSquare
25962596 # We look for an ellipsoid x^T P x ≤ 1 contained in the square.
25972597 # Let Q = inv(P) (x^T Q x ≤ 1 is its polar ellipsoid), we have
25982598 # max t
@@ -2609,7 +2609,7 @@ function _det1test(model::MOI.ModelLike, config::TestConfig, vecofvars::Bool, de
26092609 @test MOIU. supports_default_copy_to (model, #= copy_names=# false )
26102610 @test MOI. supports (model, MOI. ObjectiveFunction {MOI.ScalarAffineFunction{Float64}} ())
26112611 @test MOI. supports (model, MOI. ObjectiveSense ())
2612- if logdet
2612+ if use_logdet
26132613 @test MOI. supports_constraint (model, MOI. SingleVariable, MOI. EqualTo{Float64})
26142614 end
26152615 if vecofvars
@@ -2627,7 +2627,7 @@ function _det1test(model::MOI.ModelLike, config::TestConfig, vecofvars::Bool, de
26272627 Q = MOI. add_variables (model, square ? 4 : 3 )
26282628 @test MOI. get (model, MOI. NumberOfVariables ()) == (square ? 5 : 4 )
26292629
2630- if logdet
2630+ if use_logdet
26312631 u = MOI. add_variable (model)
26322632 vc = MOI. add_constraint (model, MOI. SingleVariable (u), MOI. EqualTo (1.0 ))
26332633 @test vc. value == u. value
@@ -2657,12 +2657,12 @@ function _det1test(model::MOI.ModelLike, config::TestConfig, vecofvars::Bool, de
26572657
26582658 @test MOI. get (model, MOI. PrimalStatus ()) == MOI. FEASIBLE_POINT
26592659
2660- expectedobjval = logdet ? 0. : 1.
2660+ expectedobjval = use_logdet ? 0. : 1.
26612661 @test MOI. get (model, MOI. ObjectiveValue ()) ≈ expectedobjval atol= atol rtol= rtol
26622662
26632663 @test MOI. get (model, MOI. VariablePrimal (), t) ≈ expectedobjval atol= atol rtol= rtol
26642664
2665- if logdet
2665+ if use_logdet
26662666 @test MOI. get (model, MOI. VariablePrimal (), u) ≈ 1.0 atol= atol rtol= rtol
26672667 end
26682668
@@ -2676,12 +2676,24 @@ function _det1test(model::MOI.ModelLike, config::TestConfig, vecofvars::Bool, de
26762676
26772677 tQv = MOI. get (model, MOI. ConstraintPrimal (), cX)
26782678 @test tQv[1 ] ≈ expectedobjval atol= atol rtol= rtol
2679- @test tQv[(logdet ? 3 : 2 ): end ] ≈ Qv atol= atol rtol= rtol
2679+ @test tQv[(use_logdet ? 3 : 2 ): end ] ≈ Qv atol= atol rtol= rtol
26802680
26812681 @test MOI. get (model, MOI. ConstraintPrimal (), c) ≈ [0. , 0. ] atol= atol rtol= rtol
2682- if logdet
2682+ if use_logdet
26832683 @test MOI. get (model, MOI. ConstraintPrimal (), vc) ≈ 1.0 atol= atol rtol= rtol
26842684 end
2685+
2686+ if config. duals
2687+ if use_logdet
2688+ @test MOI. get (model, MOI. ConstraintDual (), c) ≈ [1 , 1 ] atol= atol rtol= rtol
2689+ @test MOI. get (model, MOI. ConstraintDual (), vc) ≈ 2 atol= atol rtol= rtol
2690+ dual = square ? [- 1 , - 2 , 1 , 0 , 0 , 1 ] : [- 1 , - 2 , 1 , 0 , 1 ]
2691+ else
2692+ @test MOI. get (model, MOI. ConstraintDual (), c) ≈ [0.5 , 0.5 ] atol= atol rtol= rtol
2693+ dual = square ? [- 1.0 , 0.5 , 0.0 , 0.0 , 0.5 ] : [- 1.0 , 0.5 , 0.0 , 0.5 ]
2694+ end
2695+ @test MOI. get (model, MOI. ConstraintDual (), cX) ≈ dual atol= atol rtol= rtol
2696+ end
26852697 end
26862698end
26872699
@@ -2690,13 +2702,85 @@ logdett1ftest(model::MOI.ModelLike, config::TestConfig) = _det1test(model, confi
26902702logdets1vtest (model:: MOI.ModelLike , config:: TestConfig ) = _det1test (model, config, true , MOI. LogDetConeSquare)
26912703logdets1ftest (model:: MOI.ModelLike , config:: TestConfig ) = _det1test (model, config, false , MOI. LogDetConeSquare)
26922704
2705+ function _det2test (model:: MOI.ModelLike , config:: TestConfig , detcone)
2706+ atol = config. atol
2707+ rtol = config. rtol
2708+ square = detcone == MOI. LogDetConeSquare || detcone == MOI. RootDetConeSquare
2709+ use_logdet = detcone == MOI. LogDetConeTriangle || detcone == MOI. LogDetConeSquare
2710+ # We find logdet or rootdet of a symmetric PSD matrix:
2711+ # mat = |3 2 1|
2712+ # |2 2 1|
2713+ # |1 1 3|
2714+ # det(mat) = 5, so:
2715+ # rootdet(mat) ≈ 1.709976
2716+ # logdet(mat) ≈ 1.609438
2717+
2718+ mat = Float64[3 2 1 ; 2 2 1 ; 1 1 3 ]
2719+ matL = Float64[3 , 2 , 2 , 1 , 1 , 3 ]
2720+
2721+ @test MOIU. supports_default_copy_to (model, #= copy_names=# false )
2722+ @test MOI. supports (model, MOI. ObjectiveFunction {MOI.SingleVariable} ())
2723+ @test MOI. supports (model, MOI. ObjectiveSense ())
2724+ @test MOI. supports_constraint (model, MOI. VectorAffineFunction{Float64}, detcone)
2725+
2726+ MOI. empty! (model)
2727+ @test MOI. is_empty (model)
2728+
2729+ t = MOI. add_variable (model)
2730+ @test MOI. get (model, MOI. NumberOfVariables ()) == 1
2731+
2732+ MOI. set (model, MOI. ObjectiveFunction {MOI.SingleVariable} (), MOI. SingleVariable (t))
2733+ MOI. set (model, MOI. ObjectiveSense (), MOI. MAX_SENSE)
2734+
2735+ constant_mat = square ? vec (mat) : matL
2736+ constant_vec = use_logdet ? vcat (0 , 1 , constant_mat) : vcat (0 , constant_mat)
2737+ vaf = MOI. VectorAffineFunction ([MOI. VectorAffineTerm (1 , MOI. ScalarAffineTerm (1.0 , t))], constant_vec)
2738+ det_constraint = MOI. add_constraint (model, vaf, detcone (3 ))
2739+ @test MOI. get (model, MOI. NumberOfConstraints {MOI.VectorAffineFunction{Float64}, detcone} ()) == 1
2740+
2741+ if config. solve
2742+ @test MOI. get (model, MOI. TerminationStatus ()) == MOI. OPTIMIZE_NOT_CALLED
2743+
2744+ MOI. optimize! (model)
2745+
2746+ @test MOI. get (model, MOI. TerminationStatus ()) == config. optimal_status
2747+
2748+ @test MOI. get (model, MOI. PrimalStatus ()) == MOI. FEASIBLE_POINT
2749+
2750+ expected_objval = use_logdet ? log (5 ) : (5 ^ inv (3 ))
2751+ @test MOI. get (model, MOI. ObjectiveValue ()) ≈ expected_objval atol= atol rtol= rtol
2752+ @test MOI. get (model, MOI. VariablePrimal (), t) ≈ expected_objval atol= atol rtol= rtol
2753+
2754+ det_value = MOI. get (model, MOI. ConstraintPrimal (), det_constraint)
2755+ @test det_value[1 ] ≈ expected_objval atol= atol rtol= rtol
2756+ if use_logdet
2757+ @test det_value[2 ] ≈ 1.0 atol= atol rtol= rtol
2758+ end
2759+ @test det_value[(use_logdet ? 3 : 2 ): end ] ≈ (square ? vec (mat) : matL) atol= atol rtol= rtol
2760+
2761+ if config. duals
2762+ psd_dual = square ? [1 , - 1 , 0 , - 1 , 1.6 , - 0.2 , 0 , - 0.2 , 0.4 ] : [1 , - 1 , 1.6 , 0 , - 0.2 , 0.4 ]
2763+ dual = use_logdet ? vcat (- 1 , log (5 ) - 3 , psd_dual) : vcat (- 1 , psd_dual / 3 * expected_objval)
2764+ @test MOI. get (model, MOI. ConstraintDual (), det_constraint) ≈ dual atol= atol rtol= rtol
2765+ end
2766+ end
2767+ end
2768+
2769+ logdett2test (model:: MOI.ModelLike , config:: TestConfig ) = _det2test (model, config, MOI. LogDetConeTriangle)
2770+ logdets2test (model:: MOI.ModelLike , config:: TestConfig ) = _det2test (model, config, MOI. LogDetConeSquare)
2771+
2772+
26932773const logdetttests = Dict (" logdett1v" => logdett1vtest,
2694- " logdett1f" => logdett1ftest)
2774+ " logdett1f" => logdett1ftest,
2775+ " logdett2" => logdett2test,
2776+ )
26952777
26962778@moitestset logdett
26972779
26982780const logdetstests = Dict (" logdets1v" => logdets1vtest,
2699- " logdets1f" => logdets1ftest)
2781+ " logdets1f" => logdets1ftest,
2782+ " logdets2" => logdets2test,
2783+ )
27002784
27012785@moitestset logdets
27022786
@@ -2709,14 +2793,18 @@ rootdett1vtest(model::MOI.ModelLike, config::TestConfig) = _det1test(model, conf
27092793rootdett1ftest (model:: MOI.ModelLike , config:: TestConfig ) = _det1test (model, config, false , MOI. RootDetConeTriangle)
27102794rootdets1vtest (model:: MOI.ModelLike , config:: TestConfig ) = _det1test (model, config, true , MOI. RootDetConeSquare)
27112795rootdets1ftest (model:: MOI.ModelLike , config:: TestConfig ) = _det1test (model, config, false , MOI. RootDetConeSquare)
2796+ rootdett2test (model:: MOI.ModelLike , config:: TestConfig ) = _det2test (model, config, MOI. RootDetConeTriangle)
2797+ rootdets2test (model:: MOI.ModelLike , config:: TestConfig ) = _det2test (model, config, MOI. RootDetConeSquare)
27122798
27132799const rootdetttests = Dict (" rootdett1v" => rootdett1vtest,
2714- " rootdett1f" => rootdett1ftest)
2800+ " rootdett1f" => rootdett1ftest,
2801+ " rootdett2" => rootdett2test)
27152802
27162803@moitestset rootdett
27172804
27182805const rootdetstests = Dict (" rootdets1v" => rootdets1vtest,
2719- " rootdets1f" => rootdets1ftest)
2806+ " rootdets1f" => rootdets1ftest,
2807+ " rootdets2" => rootdets2test)
27202808
27212809@moitestset rootdets
27222810
0 commit comments