Skip to content

Commit

Permalink
test quadratic MPS writer, fixes #227
Browse files Browse the repository at this point in the history
  • Loading branch information
mlubin committed Jul 29, 2015
1 parent 79302a2 commit 4848950
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 49 deletions.
58 changes: 14 additions & 44 deletions src/writers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ function writeMPS(m::Model, fname::String)
# Objective and constraint names
gc_enable(false)
write(f,"ROWS\n")
write(f," N CON$(numRows+1)\n")
write(f," N OBJ\n")
hasrange = false
for c in 1:numRows
rowsense = sense(m.linconstr[c])
Expand All @@ -31,49 +31,16 @@ function writeMPS(m::Model, fname::String)
end
gc_enable(true)

# Load rows into SparseMatrixCSC
gc_enable(false)
nnz = 0
for c in 1:numRows
nnz += length(m.linconstr[c].terms.coeffs)
end
objaff::AffExpr = m.obj.aff
objlincoef = objaff.coeffs
objlincoef, rowlb, rowub = prepProblemBounds(m)
if m.objSense == :Max
println("Warning, MPS does not support maximization sense. Flipping objective coefficients.")
objlincoef = -objaff.coeffs
end


nnz += length(objaff.coeffs)
I = Array(Int,nnz)
J = Array(Int,nnz)
V = Array(Float64,nnz)
nnz = 0
for c in 1:numRows
# TODO: type assertion shouldn't be necessary
constr::LinearConstraint = m.linconstr[c]
coeffs = constr.terms.coeffs
vars = constr.terms.vars
for ind in 1:length(coeffs)
nnz += 1
I[nnz] = c
J[nnz] = vars[ind].col
V[nnz] = coeffs[ind]
end
end
for ind in 1:length(objaff.coeffs)
nnz += 1
I[nnz] = numRows+1
J[nnz] = objaff.vars[ind].col
V[nnz] = objlincoef[ind]
objlincoef = -objlincoef
end

colmat = sparse(I,J,V,numRows+1,m.numCols)
colptr = colmat.colptr
rowval = colmat.rowval
nzval = colmat.nzval
gc_enable(true)
A = prepConstrMatrix(m)
colptr = A.colptr
rowval = A.rowval
nzval = A.nzval

# Output each column
gc_enable(false)
Expand All @@ -89,11 +56,14 @@ function writeMPS(m::Model, fname::String)
@printf(f," MARKER 'MARKER' 'INTEND'\n")
inintegergroup = false
end
for ind in colmat.colptr[col]:(colmat.colptr[col+1]-1)
for ind in colptr[col]:(colptr[col+1]-1)
@printf(f," VAR%d CON%d ",col,rowval[ind])
print_shortest(f,nzval[ind])
println(f)
end
@printf(f," VAR%d OBJ ",col)
print_shortest(f,objlincoef[col])
println(f)
end
if inintegergroup
@printf(f," MARKER 'MARKER' 'INTEND'\n")
Expand Down Expand Up @@ -185,9 +155,9 @@ function writeMPS(m::Model, fname::String)
@printf(f, " VAR%d VAR%d ", qv1[ind].col,qv2[ind].col)
print_shortest(f, qc[ind])
println(f)
@printf(f, " VAR%d VAR%d ", qv2[ind].col,qv1[ind].col)
print_shortest(f, qc[ind])
println(f)
#@printf(f, " VAR%d VAR%d ", qv2[ind].col,qv1[ind].col)
#print_shortest(f, qc[ind])
#println(f)
end
end
end
Expand Down
54 changes: 49 additions & 5 deletions test/model.jl
Original file line number Diff line number Diff line change
Expand Up @@ -103,26 +103,29 @@ facts("[model] Test printing a model") do
modAMPS = ASCIIString[
"NAME JuMPModel",
"ROWS",
" N CON4",
" N OBJ",
" E CON1",
" L CON2",
" L CON3",
"COLUMNS",
" VAR1 CON1 1",
" VAR1 CON2 .5",
" VAR1 CON4 -.16666666666666666",
" VAR1 OBJ -.16666666666666666",
" MARKER 'MARKER' 'INTORG'",
" VAR2 CON1 1",
" VAR2 CON3 7",
" VAR2 CON4 -.16666666666666666",
" VAR2 OBJ -.16666666666666666",
" MARKER 'MARKER' 'INTEND'",
" VAR3 CON3 -1",
" VAR3 CON4 -1",
" VAR3 OBJ -1",
" VAR4 CON2 1",
" VAR4 CON4 -1",
" VAR4 OBJ -1",
" VAR5 CON2 1",
" VAR5 OBJ 0",
" VAR6 CON2 1",
" VAR6 OBJ 0",
" VAR7 CON3 -.5263157894736842",
" VAR7 OBJ 0",
"RHS",
" rhs CON1 2",
" rhs CON2 1",
Expand Down Expand Up @@ -158,6 +161,47 @@ facts("[model] Test printing a model") do
@fact getObjectiveSense(modA) => :Min
end

facts("[model] Quadratic MPS writer") do
modQ = Model()
@defVar(modQ, x == 1)
@defVar(modQ, y 0)
@setObjective(modQ, Min, x^2 - 2*x*y + y^2 + x)

#####################################################################
# Test MPS writer
writeMPS(modQ, modPath * "Q.mps")
modQMPS = ASCIIString[
"NAME JuMPModel",
"ROWS",
" N OBJ",
"COLUMNS",
" VAR1 OBJ 1",
" VAR2 OBJ 0",
"RHS",
"BOUNDS",
" LO BOUND VAR1 1",
" UP BOUND VAR1 1",
"QMATRIX",
" VAR1 VAR1 2",
" VAR1 VAR2 -2",
" VAR2 VAR2 2",
"ENDATA"]
modQfp = open(modPath * "Q.mps")
lineInd = 1
while !eof(modQfp)
line = readline(modQfp)
@fact chomp(line) => modQMPS[lineInd]
lineInd += 1
end
close(modQfp)

# Getter/setters
@fact MathProgBase.numvar(modQ) => 2
@fact MathProgBase.numlinconstr(modQ) => 0
@fact MathProgBase.numquadconstr(modQ) => 0
@fact MathProgBase.numconstr(modQ) => 0
@fact getObjectiveSense(modQ) => :Min
end


facts("[model] Test solving a MILP") do
Expand Down

0 comments on commit 4848950

Please sign in to comment.