Skip to content
This repository was archived by the owner on Feb 9, 2020. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions src/MathOptInterfaceMosek.jl
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ struct ConstraintMap
xs_reals :: Dict{Int64,Int} # (VectorOfVariables,Reals) -> constraint number
xs_qcone :: Dict{Int64,Int} # (VectorOfVariables,SecondOrderCone) -> constraint number
xs_rqcone :: Dict{Int64,Int} # (VectorOfVariables,RotatedSecondOrderCone) -> constraint number
xs_econe :: Dict{Int64,Int} # (VectorOfVariables,ExponentialCone) -> constraint number
xs_psdconetriangle :: Dict{Int64,Int} # (VectorOfVariables,PositiveSemidefiniteConeTriangle) -> constraint number

axb_lessthan :: Dict{Int64,Int} # (ScalarAffineFunction,LessThan) -> constraint number
Expand All @@ -71,10 +72,11 @@ struct ConstraintMap
axbs_reals :: Dict{Int64,Int} # (VectorAffineFunction,Reals) -> constraint number
axbs_qcone :: Dict{Int64,Int} # (VectorAffineFunction,SecondOrderCone) -> constraint number
axbs_rqcone :: Dict{Int64,Int} # (VectorAffineFunction,RotatedSecondOrderCone) -> constraint number
axbs_econe :: Dict{Int64,Int} # (VectorAffineFunction,ExponentialCone) -> constraint number
axbs_psdconetriangle :: Dict{Int64,Int} # (VectorAffineFunction,PositiveSemidefiniteConeTriangle) -> constraint number
end

ConstraintMap() = ConstraintMap([Dict{Int64,Int}() for i in 1:30]...)
ConstraintMap() = ConstraintMap([Dict{Int64,Int}() for i in 1:32]...)
select(cm::ConstraintMap,::Type{MOI.SingleVariable}, ::Type{MOI.LessThan{Float64}}) = cm.x_lessthan
select(cm::ConstraintMap,::Type{MOI.SingleVariable}, ::Type{MOI.GreaterThan{Float64}}) = cm.x_greaterthan
select(cm::ConstraintMap,::Type{MOI.SingleVariable}, ::Type{MOI.EqualTo{Float64}}) = cm.x_equalto
Expand All @@ -89,6 +91,7 @@ select(cm::ConstraintMap,::Type{MOI.VectorOfVariables}, ::Type{MOI.Ze
select(cm::ConstraintMap,::Type{MOI.VectorOfVariables}, ::Type{MOI.Reals}) = cm.xs_reals
select(cm::ConstraintMap,::Type{MOI.VectorOfVariables}, ::Type{MOI.SecondOrderCone}) = cm.xs_qcone
select(cm::ConstraintMap,::Type{MOI.VectorOfVariables}, ::Type{MOI.RotatedSecondOrderCone}) = cm.xs_rqcone
select(cm::ConstraintMap,::Type{MOI.VectorOfVariables}, ::Type{MOI.ExponentialCone}) = cm.xs_econe
select(cm::ConstraintMap,::Type{MOI.VectorOfVariables}, ::Type{MOI.PositiveSemidefiniteConeTriangle}) = cm.xs_psdconetriangle
select(cm::ConstraintMap,::Type{MOI.ScalarAffineFunction{Float64}},::Type{MOI.LessThan{Float64}}) = cm.axb_lessthan
select(cm::ConstraintMap,::Type{MOI.ScalarAffineFunction{Float64}},::Type{MOI.GreaterThan{Float64}}) = cm.axb_greaterthan
Expand All @@ -104,6 +107,7 @@ select(cm::ConstraintMap,::Type{MOI.VectorAffineFunction{Float64}},::Type{MOI.Ze
select(cm::ConstraintMap,::Type{MOI.VectorAffineFunction{Float64}},::Type{MOI.Reals}) = cm.axbs_reals
select(cm::ConstraintMap,::Type{MOI.VectorAffineFunction{Float64}},::Type{MOI.SecondOrderCone}) = cm.axbs_qcone
select(cm::ConstraintMap,::Type{MOI.VectorAffineFunction{Float64}},::Type{MOI.RotatedSecondOrderCone}) = cm.axbs_rqcone
select(cm::ConstraintMap,::Type{MOI.VectorAffineFunction{Float64}},::Type{MOI.ExponentialCone}) = cm.axbs_econe
select(cm::ConstraintMap,::Type{MOI.VectorAffineFunction{Float64}},::Type{MOI.PositiveSemidefiniteConeTriangle}) = cm.axbs_psdconetriangle

Base.getindex{F,D}(cm::ConstraintMap,r :: MOI.ConstraintIndex{F,D}) = select(cm,F,D)[r.value]
Expand Down Expand Up @@ -231,6 +235,7 @@ using MathOptInterfaceUtilities
const MOIU = MathOptInterfaceUtilities
@bridge GeoMean MOIU.GeoMeanBridge () () (GeometricMeanCone,) () () () (VectorOfVariables,) (VectorAffineFunction,)
@bridge RootDet MOIU.RootDetBridge () () (RootDetConeTriangle,) () () () (VectorOfVariables,) (VectorAffineFunction,)
@bridge LogDet MOIU.LogDetBridge () () (LogDetConeTriangle,) () () () (VectorOfVariables,) (VectorAffineFunction,)

function MosekInstance(; kws...)
t = maketask()
Expand Down Expand Up @@ -262,7 +267,7 @@ function MosekInstance(; kws...)
if ! be_quiet
Mosek.putstreamfunc(t,Mosek.MSK_STREAM_LOG,m -> print(m))
end
RootDet{Float64}(GeoMean{Float64}(
LogDet{Float64}(RootDet{Float64}(GeoMean{Float64}(
MosekModel(t,# task
0, # public numvar
ConstraintMap(), # public constraints
Expand All @@ -280,7 +285,7 @@ function MosekInstance(; kws...)
0, # cone counter
Mosek.MSK_RES_OK,
MosekSolution[]) # trm
))
)))
catch
Mosek.deletetask(t)
rethrow()
Expand Down
36 changes: 17 additions & 19 deletions src/attributes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ function MOI.get!(

# It is in fact a real constraint and cid is the id of an ordinary constraint
barvaridx = - m.c_block_slack[-cid]
output[1:length(output)] = sympackedLtoU(getbarxj(m.task,whichsol,barvaridx))
output[1:length(output)] = reorderval(getbarxj(m.task,whichsol,barvaridx), MOI.PositiveSemidefiniteConeTriangle)
end

# Any other domain for variable vector
Expand All @@ -259,7 +259,7 @@ function MOI.get!{D}(
idxs = getindexes(m.xc_block,xcid)
subj = m.xc_idxs[idxs]

output[1:length(output)] = m.solutions[attr.N].xx[subj]
output[1:length(output)] = reorderval(m.solutions[attr.N].xx[subj], D)
end

function MOI.get{D}(m ::MosekModel,
Expand All @@ -270,8 +270,6 @@ function MOI.get{D}(m ::MosekModel,
m.solutions[attr.N].xc[subi]
end



function MOI.get!{D}(
output::Vector{Float64},
m ::MosekModel,
Expand All @@ -286,10 +284,10 @@ function MOI.get!{D}(
elseif m.c_block_slack[cid] > 0 # qcone slack
xid = m.c_block_slack[cid]
xsubj = getindexes(m.x_block, xid)
output[1:length(output)] = m.solutions[attr.N].xx[xsubj]
output[1:length(output)] = reorderval(m.solutions[attr.N].xx[xsubj], getconeset(m, cid))
else # psd slack
xid = - m.c_block_slack[cid]
output[1:length(output)] = sympackedLtoU(getbarxj(m.task,m.solutions[attr.N].whichsol,Int32(xid)))
output[1:length(output)] = reorderval(getbarxj(m.task,m.solutions[attr.N].whichsol,Int32(xid)), MOI.PositiveSemidefiniteConeTriangle)
end
end

Expand Down Expand Up @@ -366,7 +364,7 @@ function MOI.get!(

# It is in fact a real constraint and cid is the id of an ordinary constraint
barvaridx = - m.c_block_slack[-cid]
dual = sympackedLtoU(getbarsj(m.task,whichsol,barvaridx))
dual = reorderval(getbarsj(m.task,whichsol,barvaridx), MOI.PositiveSemidefiniteConeTriangle)
if (getobjsense(m.task) == MSK_OBJECTIVE_SENSE_MINIMIZE)
output[1:length(output)] = dual
else
Expand All @@ -390,25 +388,25 @@ function MOI.get!{D}(

if (getobjsense(m.task) == MSK_OBJECTIVE_SENSE_MINIMIZE)
if mask & boundflag_lower != 0 && mask & boundflag_upper != 0
output[1:length(output)] = m.solutions[attr.N].slx[subj] - m.solutions[attr.N].sux[subj]
output[1:length(output)] = reorderval(m.solutions[attr.N].slx[subj] - m.solutions[attr.N].sux[subj], D)
elseif (mask & boundflag_lower) != 0
output[1:length(output)] = m.solutions[attr.N].slx[subj]
output[1:length(output)] = reorderval(m.solutions[attr.N].slx[subj], D)
elseif (mask & boundflag_upper) != 0
output[1:length(output)] = - m.solutions[attr.N].sux[subj]
output[1:length(output)] = reorderval(- m.solutions[attr.N].sux[subj], D)
elseif (mask & boundflag_cone) != 0
output[1:length(output)] = m.solutions[attr.N].snx[subj]
output[1:length(output)] = reorderval(m.solutions[attr.N].snx[subj], D)
else
error("Dual value available for this constraint")
end
else
if mask & boundflag_lower != 0 && mask & boundflag_upper != 0
output[1:length(output)] = m.solutions[attr.N].sux[subj] - m.solutions[attr.N].slx[subj]
output[1:length(output)] = reorderval(m.solutions[attr.N].sux[subj] - m.solutions[attr.N].slx[subj], D)
elseif (mask & boundflag_lower) != 0
output[1:length(output)] = - m.solutions[attr.N].slx[subj]
output[1:length(output)] = reorderval(- m.solutions[attr.N].slx[subj], D)
elseif (mask & boundflag_upper) != 0
output[1:length(output)] = m.solutions[attr.N].sux[subj]
output[1:length(output)] = reorderval(m.solutions[attr.N].sux[subj], D)
elseif (mask & boundflag_cone) != 0
output[1:length(output)] = - m.solutions[attr.N].snx[subj]
output[1:length(output)] = reorderval(- m.solutions[attr.N].snx[subj], D)
else
error("Dual value available for this constraint")
end
Expand Down Expand Up @@ -444,23 +442,23 @@ function MOI.get!(
elseif m.c_block_slack[cid] > 0 # qcone slack
xid = m.c_block_slack[cid]
xsubj = getindexes(m.x_block, xid)
output[1:length(output)] = m.solutions[attr.N].snx[xsubj]
output[1:length(output)] = reorderval(m.solutions[attr.N].snx[xsubj], getconeset(m, cid))
else # psd slack
whichsol = getsolcode(m,attr.N)
xid = - m.c_block_slack[cid]
output[1:length(output)] = sympackedLtoU(getbarsj(m.task,whichsol,Int32(xid)))
output[1:length(output)] = reorderval(getbarsj(m.task,whichsol,Int32(xid)), MOI.PositiveSemidefiniteConeTriangle)
end
else
if m.c_block_slack[cid] == 0 # no slack
output[1:length(output)] = - m.solutions[attr.N].y[subi]
elseif m.c_block_slack[cid] > 0 # qcone slack
xid = m.c_block_slack[cid]
subj = getindexes(m.x_block, xid)
output[1:length(output)] = - m.solutions[attr.N].snx[subj]
output[1:length(output)] = reorderval(- m.solutions[attr.N].snx[subj], getconeset(m, cid))
else # psd slack
whichsol = getsolcode(m,attr.N)
xid = - m.c_block_slack[cid]
output[1:length(output)] = sympackedLtoU(- getbarsj(m.task,whichsol,Int32(xid)))
output[1:length(output)] = reorderval(- getbarsj(m.task,whichsol,Int32(xid)), MOI.PositiveSemidefiniteConeTriangle)
end
end
end
Expand Down
36 changes: 32 additions & 4 deletions src/constraint.jl
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,16 @@ function MOI.addconstraint!(
conid = allocateconstraints(m,N)
addlhsblock!(m,
conid,
axb.outputindex,
orderidx(axb.outputindex, dom),
axb.variables,
axb.coefficients)
conidxs = getindexes(m.c_block,conid)
m.c_constant[conidxs] = axb.constant
constant = orderval(axb.constant, dom)
m.c_constant[conidxs] = constant

m.c_block_slack[conid]

addbound!(m,conid,conidxs,axb.constant,dom)
addbound!(m,conid,conidxs,constant,dom)
conref = MOI.ConstraintIndex{MOI.VectorAffineFunction{Float64},D}(UInt64(conid) << 1)
select(m.constrmap,MOI.VectorAffineFunction{Float64},D)[conref.value] = conid

Expand Down Expand Up @@ -179,6 +180,20 @@ is_positivesemidefinite_set(dom) = false
is_conic_set(dom :: VectorCone) = true
is_conic_set(dom) = false

orderidx(idx, s) = idx
expmap(i) = 4 - i
function orderidx(idx, s::MOI.ExponentialCone)
expmap.(idx)
end

orderval(val, s) = val
orderval(val, s::MOI.ExponentialCone) = val[3:-1:1]
orderval(val, s::MOI.PositiveSemidefiniteConeTriangle) = sympackedUtoL(val, s.dimension)

reorderval(val, s) = val
reorderval(val, s::Type{MOI.ExponentialCone}) = val[3:-1:1]
reorderval(val, s::Type{MOI.PositiveSemidefiniteConeTriangle}) = sympackedLtoU(val)

addvarconstr(m :: MosekModel, subj :: Vector{Int}, dom :: MOI.Reals) = nothing
function addvarconstr(m :: MosekModel, subj :: Vector{Int}, dom :: MOI.Zeros)
bnd = zeros(Float64,length(subj))
Expand Down Expand Up @@ -231,6 +246,18 @@ end

abstractset2ct(dom::MOI.SecondOrderCone) = MSK_CT_QUAD
abstractset2ct(dom::MOI.RotatedSecondOrderCone) = MSK_CT_RQUAD
abstractset2ct(dom::MOI.ExponentialCone) = MSK_CT_PEXP
function ct2abstractset(ct::Mosek.Conetype)
if ct == MSK_CT_QUAD
MOI.SecondOrderCone
elseif ct == MSK_CT_RQUAD
MOI.RotatedSecondOrderCone
else
@assert ct == MSK_CT_PEXP
MOI.ExponentialCone
end
end
getconeset(m::MosekModel, cid) = ct2abstractset(getconeinfo(m.task, m.c_coneid[cid])[1])
function MOI.addconstraint!(
m :: MosekModel,
xs :: MOI.SingleVariable,
Expand Down Expand Up @@ -264,7 +291,7 @@ function MOI.addconstraint!(m :: MosekModel,
xs :: MOI.VectorOfVariables,
dom :: D) where { D <: PositiveSemidefiniteCone }
N = dom.dimension
vars = sympackedUtoL(xs.variables, N)
vars = orderval(xs.variables, dom)
subj = Vector{Int}(length(vars))
for i in 1:length(subj)
getindexes(m.x_block, ref2id(vars[i]),subj,i)
Expand Down Expand Up @@ -342,6 +369,7 @@ function MOI.addconstraint!{D <: MOI.AbstractSet}(m :: MosekModel, xs :: MOI.Vec
for i in 1:length(subj)
getindexes(m.x_block, ref2id(xs.variables[i]),subj,i)
end
subj = orderval(subj, dom)

mask = domain_type_mask(dom)
if any(mask .& m.x_boundflags[subj[1]] .> 0)
Expand Down
9 changes: 5 additions & 4 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const MOIT = MathOptInterfaceTests

const solver = () -> MosekInstance(QUIET = true)
const config = MOIT.TestConfig(1e-7, 1e-7, true, false, true, true)
const configgeomean = MOIT.TestConfig(1e-4, 1e-4, true, false, true, true)
const configlowtol = MOIT.TestConfig(1e-4, 1e-4, true, false, true, true)

@testset "Continuous linear problems" begin
# linear11 is failing because the following are not implemented:
Expand All @@ -24,12 +24,13 @@ end
@testset "Continuous conic problems" begin
# lin1 and soc1 are failing because ListOfConstraints is not implemented
# sdp2 is failing because MOI.get(instance, MOI.ConstraintPrimal(), c1) returns -10 instead of 0
MOIT.contconictest(solver, config, ["lin1v", "lin1f", "soc1", "geomean", "exp", "sdp2", "logdet"])
MOIT.geomeantest(solver, configgeomean)
MOIT.contconictest(solver, config, ["lin1v", "lin1f", "soc1", "geomean", "exp", "sdp2"])
MOIT.exptest(solver, configlowtol)
MOIT.geomeantest(solver, configlowtol)
end

@testset "Mixed-integer linear problems" begin
MOIT.intlineartest(solver, config, ["int2"])
end

include("test_jump.jl")
#include("test_jump.jl")