Skip to content

Commit

Permalink
Fix jump-dev#964 (printing) (jump-dev#974)
Browse files Browse the repository at this point in the history
  • Loading branch information
blegat authored and joehuchette committed Feb 22, 2017
1 parent f8835cc commit 0df80f8
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 40 deletions.
4 changes: 2 additions & 2 deletions src/JuMPContainer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ end

pushmeta!(x::JuMPContainer, sym::Symbol, val) = (x.meta[sym] = val)
getmeta(x::JuMPContainer, sym::Symbol) = x.meta[sym]
hasmeta(x::JuMPContainer, sym::Symbol) = haskey(x.meta, sym)

# duck typing approach -- if eltype(innerArray) doesn't support accessor, will fail
for accessor in (:getdual, :getlowerbound, :getupperbound, :getvalue)
Expand Down Expand Up @@ -129,12 +130,11 @@ end
function _mapInner{T}(f, x::JuMPContainer{T})
vars = _innercontainer(x)
vals = _similar(vars)
name = T == Variable ? printdata(x).name : "__anon__"
warnedyet = false
for I in eachindex(vars)
tmp = f(vars[I])
if isnan(tmp) && !warnedyet
_warnnan(f, name)
_warnnan(f, getname(x))
warnedyet = true
end
vals[I] = tmp
Expand Down
19 changes: 8 additions & 11 deletions src/print.jl
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ math(s,mathmode) = mathmode ? s : "\$\$ $s \$\$"

# helper to look up corresponding JuMPContainerData
printdata(v::JuMPContainer) = getmeta(v, :model).varData[v]
getname(x::JuMPContainer) = hasmeta(x, :model) ? printdata(x).name : "__anon__"
function printdata(v::Array{Variable})
if isempty(v)
error("Cannot locate printing data for an empty array")
Expand Down Expand Up @@ -552,16 +553,14 @@ cont_str(::Type{IJuliaMode}, j; mathmode=true) =
#------------------------------------------------------------------------
Base.show(io::IO, j::JuMPContainer{Float64}) = print(io, val_str(REPLMode,j))
function val_str{N}(mode, j::JuMPArray{Float64,N})
m = _getmodel(j)
data = printdata(j)
out_str = "$(data.name): $N dimensions:\n"
out_str = "$(getname(j)): $N dimensions:"
if isempty(j)
return out_str * " (no entries)"
return out_str * "\n (no entries)"
end

function val_str_rec(depth, parent_index::Vector{Any}, parent_str::AbstractString)
# Turn index set into strings
indexset = data.indexsets[depth]
indexset = j.indexsets[depth]
index_strs = map(string, indexset)

# Determine longest index so we can align columns
Expand All @@ -586,14 +585,14 @@ function val_str{N}(mode, j::JuMPArray{Float64,N})
value = length(parent_index) == 0 ?
j[indexset[i]] :
j[parent_index...,indexset[i]]
out_str *= indent * "[" * index_strs[i] * "] = $value\n"
out_str *= "\n" * indent * "[" * index_strs[i] * "] = $value"
end
else
# At least one more layer to go
for i = 1:length(indexset)
index = indexset[i]
# Print the ":" version of indices we will recurse over
out_str *= indent * "[" * index_strs[i] * ",:"^(N-depth) * "]\n"
out_str *= "\n" * indent * "[" * index_strs[i] * ",:"^(N-depth) * "]"
val_str_rec(depth+1,
length(parent_index) == 0 ? Any[index] : Any[parent_index...,index],
index_strs[i] * ",")
Expand All @@ -614,12 +613,10 @@ function _isless(t1::Tuple, t2::Tuple)
end
return n1 < n2
end
function val_str(mode, dict::JuMPDict{Float64})
function val_str{N}(mode, dict::JuMPDict{Float64,N})
nelem = length(dict.tupledict)
isempty(dict) && return ""
m = _getmodel(dict)
data = printdata(dict)
out_str = "$(data.name): $(length(data.indexsets)) dimensions, $nelem "
out_str = "$(getname(dict)): $N dimensions, $nelem "
out_str *= nelem == 1 ? "entry" : "entries"
out_str *= ":"

Expand Down
19 changes: 0 additions & 19 deletions test/expr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -82,23 +82,4 @@ using Base.Test
end
@test k == 0
end

@testset "no method matching mapcontainer_warn(::JuMP.#_getValue, ::JuMP.JuMPArray{JuMP.NonlinearExpression,1,Tuple{UnitRange{Int64}}}) #964" begin
M = [0 0 -1 -1 ;
0 0 1 -2 ;
1 -1 2 -2 ;
1 2 -2 4 ]

q = [2; 2; -2; -6]

lb = zeros(4)
ub = Inf*ones(4)

items = 1:4
m = Model()
@variable(m, lb[i] <= x[i in items] <= ub[i])
@NLexpression(m, F[i in items], sum(M[i,j]*x[j] for j in items) + q[i])

@test typeof(getvalue(F)) == JuMP.JuMPArray{Float64,1,Tuple{UnitRange{Int}}}
end
end
47 changes: 39 additions & 8 deletions test/print.jl
Original file line number Diff line number Diff line change
Expand Up @@ -184,12 +184,16 @@ end
@testset "JuMPContainer{Number}" begin
# The same output for REPL and IJulia, so only testing one
mod = Model()
@variable(mod, u[2:1])
@variable(mod, w[i=9:10, [:Apple,5,:Banana], j=-1:+1] == i*j)
@variable(mod, x[i=9:11,j=99:101,k=3:4] == i*j*k)
@variable(mod, y[i=9:11,j=i:11] == i*j)
@variable(mod, z[i=[:a,'b'],j=1:3] == j)

# Deal with hashing variations
io_test(REPLMode, getvalue(u), """
u: 1 dimensions:
(no entries)""")
if hash(5) < hash(:Apple)
io_test(REPLMode, getvalue(w), """
w: 3 dimensions:
Expand Down Expand Up @@ -218,8 +222,7 @@ end
[10,Banana,:]
[10,Banana,-1] = -10.0
[10,Banana, 0] = 0.0
[10,Banana, 1] = 10.0
""", repl=:print)
[10,Banana, 1] = 10.0""", repl=:print)
else
io_test(REPLMode, getvalue(w), """
w: 3 dimensions:
Expand Down Expand Up @@ -248,8 +251,7 @@ end
[10,Banana,:]
[10,Banana,-1] = -10.0
[10,Banana, 0] = 0.0
[10,Banana, 1] = 10.0
""", repl=:print)
[10,Banana, 1] = 10.0""", repl=:print)
end

io_test(REPLMode, getvalue(x), """
Expand Down Expand Up @@ -283,8 +285,7 @@ end
[11,100,4] = 4400.0
[11,101,:]
[11,101,3] = 3333.0
[11,101,4] = 4444.0
""", repl=:print)
[11,101,4] = 4444.0""", repl=:print)

io_test(REPLMode, getvalue(y), """
y: 2 dimensions, 6 entries:
Expand All @@ -304,8 +305,7 @@ end
[b,:]
[b,1] = 1.0
[b,2] = 2.0
[b,3] = 3.0
""")
[b,3] = 3.0""")

end

Expand Down Expand Up @@ -634,4 +634,35 @@ end
s = @SDconstraint(m, X >= A)
io_test(REPLMode, s, " X[1,1] - 2 X[1,2] is semidefinite\n X[1,2] X[2,2] - 1")
end

@testset "no method matching mapcontainer_warn(::JuMP.#_getValue, ::JuMP.JuMPArray{JuMP.NonlinearExpression,1,Tuple{UnitRange{Int64}}}) #964" begin
items = 1:4
m = Model()
@variable(m, x[i in items])
@NLexpression(m, A[i in items], x[i])
@NLexpression(m, B[i in items, j in 1:i], j * x[i])

a = getvalue(A)
@test typeof(a) == JuMP.JuMPArray{Float64,1,Tuple{UnitRange{Int}}}
io_test(REPLMode, a, """
__anon__: 1 dimensions:
[1] = NaN
[2] = NaN
[3] = NaN
[4] = NaN""")
b = getvalue(B)
@show typeof(b)
io_test(REPLMode, b, """
__anon__: 2 dimensions, 10 entries:
[1,1] = NaN
[2,1] = NaN
[2,2] = NaN
[3,1] = NaN
[3,2] = NaN
[3,3] = NaN
[4,1] = NaN
[4,2] = NaN
[4,3] = NaN
[4,4] = NaN""")
end
end

0 comments on commit 0df80f8

Please sign in to comment.