From 66e718b7dcef4c5771ac91e1909e16111c28f414 Mon Sep 17 00:00:00 2001 From: Hendrik Ranocha Date: Fri, 4 Oct 2019 09:40:23 +0300 Subject: [PATCH 1/3] add more tests, in particular for dual variables, cf. #290 --- test/test_lp.jl | 22 +++++++++++++++++++ test/test_socp.jl | 55 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 75 insertions(+), 2 deletions(-) diff --git a/test/test_lp.jl b/test/test_lp.jl index f4699c694..5564e337e 100644 --- a/test/test_lp.jl +++ b/test/test_lp.jl @@ -6,6 +6,10 @@ solve!(p, solver) @test p.optval ≈ 1 atol=TOL @test evaluate(abs(x)) ≈ 1 atol=TOL + if p.solution.has_dual + println("Solution object has dual value, checking for dual correctness.") + @test p.constraints[1].dual ≈ 1 atol=TOL + end x = Variable(2,2) p = minimize(sum(abs(x)), x[2,2]>=1, x[1,1]>=1, x>=0) @@ -13,6 +17,14 @@ solve!(p, solver) @test p.optval ≈ 2 atol=TOL @test evaluate(sum(abs(x))) ≈ 2 atol=TOL + if p.solution.has_dual + println("Solution object has dual value, checking for dual correctness.") + @test p.constraints[1].dual ≈ 1 atol=TOL + @test p.constraints[2].dual ≈ 1 atol=TOL + @test p.constraints[3].dual[1,1] ≈ 0 atol=TOL + @test p.constraints[3].dual[2,2] ≈ 0 atol=TOL + @test p.constraints[3].dual[1,2] ≈ p.constraints[3].dual[1,2] atol=TOL + end end @testset "maximum atom" begin @@ -155,6 +167,11 @@ solve!(p, solver) @test p.optval ≈ 0 atol=TOL @test evaluate(norm_inf(x)) ≈ 0 atol=TOL + if p.solution.has_dual + println("Solution object has dual value, checking for dual correctness.") + @test norm(p.constraints[1].dual) ≈ 0 atol=TOL + @test norm(p.constraints[2].dual) ≈ 0 atol=TOL + end end @testset "norm 1 atom" begin @@ -164,5 +181,10 @@ solve!(p, solver) @test p.optval ≈ 0 atol=TOL @test evaluate(norm_1(x)) ≈ 0 atol=TOL + if p.solution.has_dual + println("Solution object has dual value, checking for dual correctness.") + @test norm(p.constraints[1].dual) ≈ 0 atol=TOL + @test norm(p.constraints[2].dual) ≈ 0 atol=TOL + end end end diff --git a/test/test_socp.jl b/test/test_socp.jl index 36e43a6ba..a32c2c34c 100644 --- a/test/test_socp.jl +++ b/test/test_socp.jl @@ -19,15 +19,23 @@ solve!(p, solver) @test p.optval ≈ 14.9049 atol=TOL @test evaluate(norm2(A * x + b) + lambda * norm2(x)) ≈ 14.9049 atol=TOL + if p.solution.has_dual + println("Solution object has dual value, checking for dual correctness.") + dual = [4.4134, 5.1546] + @test p.constraints[1].dual ≈ dual atol=TOL + end x = Variable(2) - p = minimize(norm2([x[1] + 2x[2] + 2; 2x[1] + x[2] + 3; 3x[1]+4x[2] + 4]) + lambda * norm2(x), x >= 1) @test vexity(p) == ConvexVexity() - solve!(p, solver) @test p.optval ≈ 14.9049 atol=TOL @test evaluate(norm2(A * x + b) + lambda * norm2(x)) ≈ 14.9049 atol=TOL + if p.solution.has_dual + println("Solution object has dual value, checking for dual correctness.") + dual = [4.4134, 5.1546] + @test p.constraints[1].dual ≈ dual atol=TOL + end x = Variable(2, 1) A = [1 2; 2 1; 3 4] @@ -38,6 +46,11 @@ solve!(p, solver) @test p.optval ≈ 15.4907 atol=TOL @test evaluate(norm2(A * x + b) + lambda * norm_1(x)) ≈ 15.4907 atol=TOL + if p.solution.has_dual + println("Solution object has dual value, checking for dual correctness.") + dual = [4.7062, 5.4475] + @test p.constraints[1].dual ≈ dual atol=TOL + end end @testset "frobenius norm atom" begin @@ -48,6 +61,12 @@ solve!(p, solver) @test p.optval ≈ sqrt(35) atol=TOL @test evaluate(norm(vec(m), 2)) ≈ sqrt(35) atol=TOL + if p.solution.has_dual + println("Solution object has dual value, checking for dual correctness.") + @test p.constraints[1].dual ≈ 0.6761 atol=TOL + dual = 0.1690 .* ones(4, 5); dual[3, 3] = 0 + @test p.constraints[2].dual ≈ dual atol=TOL + end end @testset "quad over lin atom" begin @@ -277,5 +296,37 @@ @test o1 <= o2 end end + + @testset "minimal norm solutions" begin + x = Variable(2) + A = [1 2; 2 4]; + b = [3, 6]; + p = minimize(norm(x, 1), A*x==b) + @test vexity(p) == ConvexVexity() + solve!(p, solver) + @test p.optval ≈ 1.5 atol=TOL + @test evaluate(x) ≈ [0, 1.5] atol=TOL + @test evaluate(norm(x, 1)) ≈ 1.5 atol=TOL + + x = Variable(2) + A = [1 2; 2 4]; + b = [3, 6]; + p = minimize(norm(x, 2), A*x==b) + @test vexity(p) == ConvexVexity() + solve!(p, solver) + @test p.optval ≈ 3/sqrt(5) atol=TOL + @test evaluate(x) ≈ [3/5, 6/5] atol=TOL + @test evaluate(norm(x, 2)) ≈ 3/sqrt(5) atol=TOL + + x = Variable(2) + A = [1 2; 2 4]; + b = [3, 6]; + p = minimize(norm(x, Inf), A*x==b) + @test vexity(p) == ConvexVexity() + solve!(p, solver) + @test p.optval ≈ 1.0 atol=TOL + @test evaluate(x) ≈ [1, 1] atol=TOL + @test evaluate(norm(x, Inf)) ≈ 1.0 atol=TOL + end end end From d6fa59b0d7dc132090d125ccb0bb9dc35b61634b Mon Sep 17 00:00:00 2001 From: Hendrik Ranocha Date: Wed, 9 Oct 2019 06:19:13 +0300 Subject: [PATCH 2/3] add tests of dual problem value for minimum norm problems --- test/test_socp.jl | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/test/test_socp.jl b/test/test_socp.jl index a32c2c34c..3ce701441 100644 --- a/test/test_socp.jl +++ b/test/test_socp.jl @@ -306,7 +306,11 @@ solve!(p, solver) @test p.optval ≈ 1.5 atol=TOL @test evaluate(x) ≈ [0, 1.5] atol=TOL - @test evaluate(norm(x, 1)) ≈ 1.5 atol=TOL + @test evaluate(norm(x, 1)) ≈ p.optval atol=TOL + if p.solution.has_dual + println("Solution object has dual value, checking for dual problem correctness.") + @test dot(b, p.constraints[1].dual) ≈ p.optval atol=TOL + end x = Variable(2) A = [1 2; 2 4]; @@ -316,7 +320,11 @@ solve!(p, solver) @test p.optval ≈ 3/sqrt(5) atol=TOL @test evaluate(x) ≈ [3/5, 6/5] atol=TOL - @test evaluate(norm(x, 2)) ≈ 3/sqrt(5) atol=TOL + @test evaluate(norm(x, 2)) ≈ p.optval atol=TOL + if p.solution.has_dual + println("Solution object has dual value, checking for dual problem correctness.") + @test dot(b, p.constraints[1].dual) ≈ p.optval atol=TOL + end x = Variable(2) A = [1 2; 2 4]; @@ -326,7 +334,11 @@ solve!(p, solver) @test p.optval ≈ 1.0 atol=TOL @test evaluate(x) ≈ [1, 1] atol=TOL - @test evaluate(norm(x, Inf)) ≈ 1.0 atol=TOL + @test evaluate(norm(x, Inf)) ≈ p.optval atol=TOL + if p.solution.has_dual + println("Solution object has dual value, checking for dual problem correctness.") + @test dot(b, p.constraints[1].dual) ≈ p.optval atol=TOL + end end end end From 4d95aa7bcf6749b23606fd187bec74e8f878b74f Mon Sep 17 00:00:00 2001 From: Hendrik Ranocha Date: Sun, 13 Oct 2019 18:41:37 +0300 Subject: [PATCH 3/3] fix typo in dual test --- test/test_lp.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_lp.jl b/test/test_lp.jl index 5564e337e..c2a511fca 100644 --- a/test/test_lp.jl +++ b/test/test_lp.jl @@ -23,7 +23,7 @@ @test p.constraints[2].dual ≈ 1 atol=TOL @test p.constraints[3].dual[1,1] ≈ 0 atol=TOL @test p.constraints[3].dual[2,2] ≈ 0 atol=TOL - @test p.constraints[3].dual[1,2] ≈ p.constraints[3].dual[1,2] atol=TOL + @test p.constraints[3].dual[1,2] ≈ p.constraints[3].dual[2,1] atol=TOL end end