Skip to content

Commit

Permalink
step in interior direction always when finding initial iterate: fixes…
Browse files Browse the repository at this point in the history
… failing MOI dense test; all tests passing now
  • Loading branch information
chriscoey committed Oct 8, 2018
1 parent a7bf226 commit 78b16c7
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 49 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
*.jl.mem
deps/deps.jl
scratch.jl
*/scratch.jl
54 changes: 16 additions & 38 deletions src/nativeinterface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -295,27 +295,6 @@ function load_data!(
return opt
end

# function load_data!(
# opt::Optimizer,
# c::Vector{Float64},
# A::AbstractMatrix{Float64},
# b::Vector{Float64},
# G::AbstractMatrix{Float64},
# h::Vector{Float64},
# cone::Cone;
# preprocess::Bool = true,
# lscachetype = QRSymmCache, # linear system solver cache type (see linsyssolvers folder)
# )
#
# if preprocess || lscachetype == QRSymmCache
# # must preprocess
#
# load_data!(opt, c, A, b, G, h, cone, lscachetype(c, A, b, G, h))
#
#
# return ???
# end

# solve using predictor-corrector algorithm based on homogeneous self-dual embedding
function solve!(opt::Optimizer)
starttime = time()
Expand Down Expand Up @@ -358,25 +337,24 @@ function solve!(opt::Optimizer)
@. tz = -h
solvelinsys3!(tx, ty, tz, H, opt.L)
@. ts = -tz
@. ls_ts = ts

# from ts, step along interior direction of cone until ts is inside cone
if !incone(cone)
getintdir!(tmp_ts, cone)
alpha = 1.0 # TODO starting alpha maybe should depend on ls_ts (eg norm like in Hypatia) in case 1.0 is too large/small
steps = 1
@. ls_ts += alpha*tmp_ts
while !incone(cone)
steps += 1
if steps > 25
error("cannot find initial iterate")
end
alpha *= 1.5
@. ls_ts = ts + alpha*tmp_ts

# from ts, step along interior direction of cone
getintdir!(tmp_ts, cone)
alpha = (norm(ts) + 1e-3)#/norm(tmp_ts) # TODO tune this
@. ls_ts = ts + alpha*tmp_ts

# continue stepping until ts is inside cone
steps = 1
while !incone(cone)
steps += 1
if steps > 25
error("cannot find initial iterate")
end
opt.verbose && println("$steps steps taken for initial iterate")
@. ts = ls_ts
alpha *= 1.5
@. ls_ts = ts + alpha*tmp_ts
end
opt.verbose && println("$steps steps taken for initial iterate")
@. ts = ls_ts

calcg!(tz, cone)
@. tz *= -1.0
Expand Down
14 changes: 7 additions & 7 deletions test/examples.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ function _envelope1(verbose::Bool, lscachetype)
@test r.status == :Optimal
@test r.pobj r.dobj atol=1e-4 rtol=1e-4
@test r.pobj -25.502777 atol=1e-4 rtol=1e-4
@test r.niters <= 30
@test r.niters <= 35

# sparse methods
opt = Hypatia.Optimizer(verbose=verbose)
Expand All @@ -19,7 +19,7 @@ function _envelope1(verbose::Bool, lscachetype)
@test r.status == :Optimal
@test r.pobj r.dobj atol=1e-4 rtol=1e-4
@test r.pobj -25.502777 atol=1e-4 rtol=1e-4
@test r.niters <= 30
@test r.niters <= 35
end

function _envelope2(verbose::Bool, lscachetype)
Expand All @@ -28,15 +28,15 @@ function _envelope2(verbose::Bool, lscachetype)
(c, A, b, G, h, cone) = build_envelope!(2, 4, 2, 7, dense=true)
rd = fullsolve(opt, c, A, b, G, h, cone)
@test rd.status == :Optimal
@test rd.niters <= 55
@test rd.niters <= 60
@test rd.pobj rd.dobj atol=1e-4 rtol=1e-4

# sparse methods
opt = Hypatia.Optimizer(verbose=verbose)
(c, A, b, G, h, cone) = build_envelope!(2, 4, 2, 7, dense=false)
rs = fullsolve(opt, c, A, b, G, h, cone)
@test rs.status == :Optimal
@test rs.niters <= 55
@test rs.niters <= 60
@test rs.pobj rs.dobj atol=1e-4 rtol=1e-4

@test rs.pobj rd.pobj atol=1e-4 rtol=1e-4
Expand Down Expand Up @@ -64,15 +64,15 @@ function _lp1(verbose::Bool, lscachetype)
(c, A, b, G, h, cone) = build_lp!(50, 100, dense=true, tosparse=false)
rd = fullsolve(opt, c, A, b, G, h, cone)
@test rd.status == :Optimal
@test rd.niters <= 40
@test rd.niters <= 45
@test rd.pobj rd.dobj atol=1e-4 rtol=1e-4

# sparse methods
opt = Hypatia.Optimizer(verbose=verbose)
(c, A, b, G, h, cone) = build_lp!(50, 100, dense=true, tosparse=true)
rs = fullsolve(opt, c, A, b, G, h, cone)
@test rs.status == :Optimal
@test rs.niters <= 40
@test rs.niters <= 45
@test rs.pobj rs.dobj atol=1e-4 rtol=1e-4

@test rs.pobj rd.pobj atol=1e-4 rtol=1e-4
Expand Down Expand Up @@ -164,7 +164,7 @@ function _namedpoly7(verbose::Bool, lscachetype)
(c, A, b, G, h, cone) = build_namedpoly!(:motzkin, 7)
r = fullsolve(opt, c, A, b, G, h, cone)
@test r.status == :Optimal
@test r.niters <= 35
@test r.niters <= 40
@test r.pobj r.dobj atol=1e-4 rtol=1e-4
@test r.pobj 0 atol=1e-4 rtol=1e-4
end
Expand Down
6 changes: 3 additions & 3 deletions test/native.jl
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ function _ellinf2(verbose::Bool, lscachetype)
cone = Hypatia.Cone([Hypatia.EllInfinityCone(6)], [1:6])
r = fullsolve(opt, c, A, b, G, h, cone)
@test r.status == :Optimal
@test r.niters <= 20
@test r.niters <= 25
@test r.pobj r.dobj atol=1e-4 rtol=1e-4
@test r.pobj 1 atol=1e-4 rtol=1e-4
end
Expand All @@ -160,7 +160,7 @@ function _soc1(verbose::Bool, lscachetype)
cone = Hypatia.Cone([Hypatia.SecondOrderCone(3)], [1:3])
r = fullsolve(opt, c, A, b, G, h, cone)
@test r.status == :Optimal
@test r.niters <= 15
@test r.niters <= 20
@test r.pobj r.dobj atol=1e-4 rtol=1e-4
@test r.pobj -sqrt(2) atol=1e-4 rtol=1e-4
@test r.x [1, 1/sqrt(2), 1/sqrt(2)] atol=1e-4 rtol=1e-4
Expand Down Expand Up @@ -209,7 +209,7 @@ function _psd1(verbose::Bool, lscachetype)
cone = Hypatia.Cone([Hypatia.PositiveSemidefiniteCone(3)], [1:3])
r = fullsolve(opt, c, A, b, G, h, cone)
@test r.status == :Optimal
@test r.niters <= 15
@test r.niters <= 20
@test r.pobj r.dobj atol=1e-4 rtol=1e-4
@test r.pobj -1 atol=1e-4 rtol=1e-4
@test r.x[2] 1 atol=1e-4 rtol=1e-4
Expand Down
4 changes: 3 additions & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ using SparseArrays


# TODO make it a native interface function eventually
# TODO maybe build a new high-level optimizer struct. the current optimizer struct is low-level
function fullsolve(opt::Hypatia.Optimizer, c, A, b, G, h, cone) # TODO handle lscachetype
Hypatia.check_data(c, A, b, G, h, cone)
(c1, A1, b1, G1, prkeep, dukeep, Q2, RiQ1) = Hypatia.preprocess_data(c, A, b, G, useQR=true)
Expand Down Expand Up @@ -106,9 +107,10 @@ end


# MathOptInterface tests
verbose = false # test verbosity
include(joinpath(@__DIR__, "moi.jl"))
testmoi(verbose, false)
# testmoi(verbose, true) # TODO fix failure on linear1
testmoi(verbose, true)


return nothing

0 comments on commit 78b16c7

Please sign in to comment.