Skip to content

Commit

Permalink
Merge pull request #4 from JuliaOpt/bl/j7
Browse files Browse the repository at this point in the history
Fixes for Julia v0.7
  • Loading branch information
blegat authored Aug 11, 2018
2 parents 2dcb7bb + ea013a4 commit b10df53
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 54 deletions.
4 changes: 2 additions & 2 deletions src/SD.jl
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Methods for the Semidefinite interface

@compat abstract type AbstractSDModel <: AbstractMathProgModel end
@compat abstract type AbstractSDModel <: MPB.AbstractMathProgModel end
export AbstractSDModel

MathProgBase.SolverInterface.@define_interface begin
MPB.@define_interface begin
SDModel
setconstrB!
setconstrentry!
Expand Down
6 changes: 4 additions & 2 deletions src/SemidefiniteModels.jl
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
module SemidefiniteModels

using Compat
using Compat.LinearAlgebra
using Compat.SparseArrays

using MathProgBase
importall MathProgBase.SolverInterface
import MathProgBase
const MPB = MathProgBase.SolverInterface

include("SD.jl")

Expand Down
9 changes: 4 additions & 5 deletions src/conic_sdpa.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,16 @@
# http://www.opt.tu-darmstadt.de/scipsdp/downloads/data_format.txt

using GZip
import MathProgBase.SolverInterface.loadproblem!

function loadproblem!(m::AbstractConicModel, filename::AbstractString; all_bin=false)
function MPB.loadproblem!(m::MPB.AbstractConicModel, filename::AbstractString; all_bin=false)
if endswith(filename,".dat-s") || endswith(filename,".dat-s.gz")
loadsdpa!(m, filename)
else
error("unrecognized input format extension in $filename")
end
end

function loadsdpa!(m::AbstractConicModel, filename::String; all_bin=false)
function loadsdpa!(m::MPB.AbstractConicModel, filename::String; all_bin=false)
if endswith(filename, ".gz")
fd = gzopen(filename, "r")
else
Expand Down Expand Up @@ -55,9 +54,9 @@ function sdpatoconicdata(io::IO, all_bin::Bool)
end
end

LPblocks = find(size -> (sign(size) == -1), sizeblocks)
LPblocks = findall(size -> (sign(size) == -1), sizeblocks)
LPblock = isempty(LPblocks) ? 0 : first(LPblocks)
PSDblocks = find(size -> (sign(size) == 1), sizeblocks)
PSDblocks = findall(size -> (sign(size) == 1), sizeblocks)

if LPblock != 0
sizeblocks[LPblock] *= -1
Expand Down
67 changes: 33 additions & 34 deletions src/sd_to_conic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# To enable Conic support from an SD solver, define, e.g.,
# ConicModel(s::CSDPSolver) = SDtoConicBridge(SDModel(s))

type SDtoConicBridge <: AbstractConicModel
mutable struct SDtoConicBridge <: MPB.AbstractConicModel
sdmodel::AbstractSDModel
varmap
varnewconstrmap
Expand All @@ -22,8 +22,8 @@ SDtoConicBridge(m::AbstractSDModel) = SDtoConicBridge(m, nothing, nothing, nothi

export SDtoConicBridge

numvar(m::SDtoConicBridge) = size(m.A,2)
numconstr(m::SDtoConicBridge) = size(m.A,1)
MPB.numvar(m::SDtoConicBridge) = size(m.A,2)
MPB.numconstr(m::SDtoConicBridge) = size(m.A,1)

function getmatdim(k)
# n*(n+1)/2 = k
Expand All @@ -37,7 +37,7 @@ function getmatdim(k)
end

# To transform Conic problems into SD problems
function loadproblem!(model::SDtoConicBridge, c, A, b, constr_cones, var_cones)
function MPB.loadproblem!(model::SDtoConicBridge, c, A, b, constr_cones, var_cones)
m, n = size(A)
model.c = c
model.A = A
Expand All @@ -62,14 +62,14 @@ function loadproblem!(model::SDtoConicBridge, c, A, b, constr_cones, var_cones)
blk = 0
blkdims = Int[]
socblks = Int[]
socblksrotated = IntSet()
socblksrotated = BitSet()
socblksvarconemap = Int[]
# For a variable at column index `col' in the conic model,
# varmap[col] gives an array such that each coefficient A[.,col] should be replaced by the sum,
# over each element (blk, i, j, coef) of the array of
# X[blk][i,j] * (A[.,col] * coef)
# Where X[blk] is the blk'th block of X
model.varmap = varmap = Vector{Vector{Tuple{Int,Int,Int,Float64}}}(n)
model.varmap = varmap = Vector{Vector{Tuple{Int,Int,Int,Float64}}}(undef, n)
varconeidx = 0
for (cone,idxs) in var_cones
varconeidx += 1
Expand Down Expand Up @@ -102,7 +102,7 @@ function loadproblem!(model::SDtoConicBridge, c, A, b, constr_cones, var_cones)
blk += 1
push!(blkdims, length(idxs))
for i in 1:length(idxs)
varmap[idxs[i]] = [(blk,1,i,i == 1 ? 1. : .5)]
varmap[idxs[i]] = [(blk, 1, i, i == 1 ? 1.0 : 0.5)]
end
push!(socblks, blk)
push!(socblksvarconemap, varconeidx)
Expand All @@ -126,7 +126,7 @@ function loadproblem!(model::SDtoConicBridge, c, A, b, constr_cones, var_cones)
for j in i:d
k += 1
# In the MPB conic model, those are scaled by sqrt(2)
coef = i == j ? 1. : 1./sqrt(2)
coef = i == j ? 1.0 : inv(2)
varmap[idxs[k]] = [(blk,i,j,coef)]
end
end
Expand All @@ -139,11 +139,11 @@ function loadproblem!(model::SDtoConicBridge, c, A, b, constr_cones, var_cones)
# For the constraint at row index `row' in the conic model,
# constrmap[row] gives the index of the constraint in the SD model,
# a value of 0 meaning that it does not correspond to any constraint
model.constrmap = constrmap = Vector{Int}(m)
constrmapcheck = IntSet()
model.constrmap = constrmap = Vector{Int}(undef, m)
constrmapcheck = BitSet()
# slackmap[row] gives (blk,i,j,coef) indicating that a slack variable has been created at X[blk][i,j] with coefficient coef
# blk=0 corresponds to no slack
slackmap = Vector{Tuple{Int,Int,Int,Float64}}(m)
slackmap = Vector{Tuple{Int,Int,Int,Float64}}(undef, m)
model.constrscaling = constrscaling = ones(Float64, m)
for (cone,idxs) in constr_cones
if cone == :Free
Expand All @@ -159,7 +159,7 @@ function loadproblem!(model::SDtoConicBridge, c, A, b, constr_cones, var_cones)
constrmap[idx] = constr
end
if cone == :Zero
slackmap[idxs] = (0,0,0,0.)
slackmap[idxs] .= ((0,0,0,0.),)
elseif cone == :NonNeg
for idx in idxs
blk += 1
Expand Down Expand Up @@ -210,12 +210,12 @@ function loadproblem!(model::SDtoConicBridge, c, A, b, constr_cones, var_cones)
end
end
end
if constrmapcheck != IntSet(1:m)
if constrmapcheck != BitSet(1:m)
throw(ArgumentError("Some variable have no cone"))
end
@assert blk == length(blkdims)

socconstr = Vector{Int}(length(socblks))
socconstr = Vector{Int}(undef, length(socblks))
for i in 1:length(socblks)
blk = socblks[i]
d = blkdims[blk]
Expand All @@ -229,7 +229,7 @@ function loadproblem!(model::SDtoConicBridge, c, A, b, constr_cones, var_cones)

# Writing the sparse block diagonal matrices
sdmodel = model.sdmodel
loadproblem!(sdmodel, blkdims, constr)
MPB.loadproblem!(sdmodel, blkdims, constr)
for row in 1:m
if constrmap[row] != 0
setconstrB!(sdmodel, b[row] * constrscaling[row], constrmap[row])
Expand Down Expand Up @@ -308,16 +308,15 @@ function loadproblem!(model::SDtoConicBridge, c, A, b, constr_cones, var_cones)
end
end

for f in [:optimize!, :status]
@eval $f(model::SDtoConicBridge) = $f(model.sdmodel)
end
MPB.optimize!(model::SDtoConicBridge) = MPB.optimize!(model.sdmodel)
MPB.status(model::SDtoConicBridge) = MPB.status(model.sdmodel)

function getobjval(model::SDtoConicBridge)
-getobjval(model.sdmodel)
function MPB.getobjval(model::SDtoConicBridge)
-MPB.getobjval(model.sdmodel)
end

function getsolution(model::SDtoConicBridge)
X = getsolution(model.sdmodel)
function MPB.getsolution(model::SDtoConicBridge)
X = MPB.getsolution(model.sdmodel)
n = size(model.A, 2)
x = zeros(Float64, n)
for col in 1:n
Expand All @@ -331,12 +330,12 @@ function getsolution(model::SDtoConicBridge)
x
end

function getdual(model::SDtoConicBridge)
y = getdual(model.sdmodel)
function MPB.getdual(model::SDtoConicBridge)
y = MPB.getdual(model.sdmodel)
constrmap = model.constrmap
constrscaling = model.constrscaling
m = size(model.A, 1)
dual = Vector{Float64}(m)
dual = Vector{Float64}(undef, m)
for row in 1:m
if constrmap[row] != 0
dual[row] = y[constrmap[row]] * constrscaling[row]
Expand All @@ -347,9 +346,9 @@ function getdual(model::SDtoConicBridge)
dual
end

function getvardual(model::SDtoConicBridge)
y = getdual(model.sdmodel)
Z = getvardual(model.sdmodel)
function MPB.getvardual(model::SDtoConicBridge)
y = MPB.getdual(model.sdmodel)
Z = MPB.getvardual(model.sdmodel)
n = size(model.A, 2)
z = zeros(Float64, n)
for col in 1:n
Expand All @@ -366,20 +365,20 @@ function getvardual(model::SDtoConicBridge)
z
end

function getvartype(model::SDtoConicBridge, col)
function MPB.getvartype(model::SDtoConicBridge, col)
# they are all supposed to be the same so we take the first one
blk, i, j, _ = first(model.varmap[col])
getvartype(model.sdmodel, blk, i, j)
MPB.getvartype(model.sdmodel, blk, i, j)
end

function setvartype!(model::SDtoConicBridge, vtype)
function MPB.setvartype!(model::SDtoConicBridge, vtype)
for (col, vt) in enumerate(vtype)
for (blk, i, j, _) in model.varmap[col]
setvartype!(model.sdmodel, vt, blk, i, j)
MPB.setvartype!(model.sdmodel, vt, blk, i, j)
end
end
end

for f in SolverInterface.methods_by_tag[:rewrap]
@eval $f(model::SDtoConicBridge) = $f(model.sdmodel)
for f in MPB.methods_by_tag[:rewrap]
@eval MPB.$f(model::SDtoConicBridge) = MPB.$f(model.sdmodel)
end
4 changes: 3 additions & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using SemidefiniteModels
using Base.Test
using Compat
using Compat.Test
using Compat.LinearAlgebra

include("sdinterface.jl")
using CSDP
Expand Down
22 changes: 12 additions & 10 deletions test/sdinterface.jl
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
using Base.Test
using Compat
using Compat.Test
using SemidefiniteModels
using MathProgBase.SolverInterface
import MathProgBase
const MPB = MathProgBase.SolverInterface

function sdtest(solver::MathProgBase.AbstractMathProgSolver; duals=false, tol=1e-6)
@testset "Testing SDModel with $solver" begin
m = ConicModel(solver)
loadproblem!(m, "prob.dat-s")
optimize!(m)
@test status(m) == :Optimal
@test isapprox(getobjval(m), 2.75)
@test norm(getsolution(m) - [.75, 1.]) < tol
m = MPB.ConicModel(solver)
MPB.loadproblem!(m, "prob.dat-s")
MPB.optimize!(m)
@test MPB.status(m) == :Optimal
@test isapprox(MPB.getobjval(m), 2.75)
@test norm(MPB.getsolution(m) - [.75, 1.]) < tol
if duals
@test norm(getdual(m) - [0, 0, .125, .125*sqrt(2), .125, 2/3, 0, 0, 0, 0, 0]) < tol
@test norm(getvardual(m)) < tol
@test norm(MPB.getdual(m) - [0, 0, .125, .125*sqrt(2), .125, 2/3, 0, 0, 0, 0, 0]) < tol
@test norm(MPB.getvardual(m)) < tol
end
end
end

0 comments on commit b10df53

Please sign in to comment.