Skip to content

Commit

Permalink
store raw expression inputs for JuMPContainers (and get rid of defCon…
Browse files Browse the repository at this point in the history
…strRef...)
  • Loading branch information
joehuchette committed Nov 26, 2014
1 parent b70503c commit 1ef7595
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 46 deletions.
8 changes: 5 additions & 3 deletions src/JuMPDict.jl
Expand Up @@ -8,6 +8,7 @@ type IndexPair
idxvar
idxset
end

#= Generated on the fly
type JuMPArray{T}
innerArray::Array{T,N}
Expand All @@ -21,6 +22,7 @@ type JuMPDict{T,N} <: JuMPContainer{T,N}
indexsets
indexexprs::Vector{IndexPair}
condition
innerexpr::Expr
end


Expand All @@ -33,7 +35,7 @@ Base.setindex!(d::JuMPDict, value, t...) = (d.tupledict[t] = value)
function Base.map{T,N}(f::Function, d::JuMPDict{T,N})
ret = Base.return_types(f, (T,))
R = (length(ret) == 1 ? ret[1] : Any)
x = JuMPDict(Dict{NTuple{N},R}(), d.name, copy(d.indexsets), copy(d.indexexprs), copy(d.condition))
x = JuMPDict(Dict{NTuple{N},R}(), d.name, copy(d.indexsets), copy(d.indexexprs), copy(d.condition), copy(d.innerexpr))
for (k,v) in d.tupledict
x.tupledict[k] = f(v)
end
Expand All @@ -47,7 +49,7 @@ Base.isempty(d::JuMPDict) = (isempty(d.tupledict))
# the following types of index sets are allowed:
# 0:K -- range with compile-time starting index
# S -- general iterable set
macro gendict(instancename,T,idxpairs,idxsets...)
macro gendict(instancename,T,exprcode,idxpairs,idxsets...)
N = length(idxsets)
allranges = all(s -> (isexpr(s,:(:)) && length(s.args) == 2), idxsets)
if allranges
Expand Down Expand Up @@ -115,7 +117,7 @@ macro gendict(instancename,T,idxpairs,idxsets...)
else
# JuMPDict
return :(
$(esc(instancename)) = JuMPDict{$T,$N}(Dict{NTuple{$N},$T}(),$(quot(instancename)), $(esc(Expr(:tuple,idxsets...))), $idxpairs, :())
$(esc(instancename)) = JuMPDict{$T,$N}(Dict{NTuple{$N},$T}(),$(quot(instancename)), $(esc(Expr(:tuple,idxsets...))), $idxpairs, :(), :())
)
end
end
Expand Down
39 changes: 9 additions & 30 deletions src/macros.jl
Expand Up @@ -59,7 +59,7 @@ buildrefsets(c::Nothing) = (gensym(), Any[], Any[], IndexPair[])
# idxpairs: As defined for buildrefsets
# sym: A symbol or expression containing the element type of the
# resulting container, e.g. :AffExpr or :Variable
function getloopedcode(c::Expr, code, condition, idxvars, idxsets, idxpairs, sym)
function getloopedcode(c::Expr, code, rawexpr, condition, idxvars, idxsets, idxpairs, sym)
varname = getname(c)
hascond = (condition != :())

Expand All @@ -85,9 +85,10 @@ function getloopedcode(c::Expr, code, condition, idxvars, idxsets, idxpairs, sym
$(quot(varname)),
$(Expr(:tuple,map(clear_dependencies,1:N)...)),
$idxpairs,
:()))
:(),
$(quot(rawexpr))))
else
mac = Expr(:macrocall,symbol("@gendict"),esc(varname),sym,idxpairs,idxsets...)
mac = Expr(:macrocall,symbol("@gendict"),esc(varname),sym,rawexpr,idxpairs,idxsets...)
end
return quote
$mac
Expand All @@ -96,7 +97,7 @@ function getloopedcode(c::Expr, code, condition, idxvars, idxsets, idxpairs, sym
end
end

getloopedcode(c, code, condition, idxvars, idxsets, idxpairs, sym) = code
getloopedcode(c, code, rawexpr, condition, idxvars, idxsets, idxpairs, sym) = code

getname(c::Symbol) = c
getname(c::Nothing) = ()
Expand Down Expand Up @@ -167,7 +168,7 @@ macro addConstraint(m, x, extra...)
" expr1 == expr2\n" * " lb <= expr <= ub")
end

looped = getloopedcode(c, code, :(), idxvars, idxsets, idxpairs, :ConstraintRef)
looped = getloopedcode(c, code, x, :(), idxvars, idxsets, idxpairs, :ConstraintRef)
conname = esc(getname(c))
if length(idxvars) == 0 # we will not return a JuMPContainer of ConstraintRef
return assert_validmodel(m, looped)
Expand Down Expand Up @@ -247,7 +248,7 @@ macro defExpr(args...)
$(refcall) = $newaff
end

return getloopedcode(c, code, :(), idxvars, idxsets, idxpairs, :AffExpr)
return getloopedcode(c, code, x, :(), idxvars, idxsets, idxpairs, :AffExpr)
end

function hasdependentsets(idxvars, idxsets)
Expand Down Expand Up @@ -404,7 +405,7 @@ macro defVar(args...)
# to contain them)
refcall, idxvars, idxsets, idxpairs = buildrefsets(var)
code = :( $(refcall) = Variable($m, $lb, $ub, $(quot(t))) )
looped = getloopedcode(var, code, condition, idxvars, idxsets, idxpairs, :Variable)
looped = getloopedcode(var, code, x, condition, idxvars, idxsets, idxpairs, :Variable)
varname = esc(getname(var))
return assert_validmodel(m, quote
$looped
Expand All @@ -413,28 +414,6 @@ macro defVar(args...)
end)
end

macro defConstrRef(var)
if isa(var,Symbol)
# easy case
return esc(:(local $var))
else
if !isexpr(var,:ref)
error("Syntax error: Expected $var to be of form var[...]")
end

varname = var.args[1]
idxsets = var.args[2:end]
idxpairs = IndexPair[]

mac = Expr(:macrocall,symbol("@gendict"),varname,:ConstraintRef,idxpairs, idxsets...)
code = quote
$(esc(mac))
nothing
end
return code
end
end

macro setNLObjective(m, sense, x)
m = esc(m)
if sense == :Min || sense == :Max
Expand Down Expand Up @@ -500,7 +479,7 @@ macro addNLConstraint(m, x, extra...)
" expr1 <= expr2\n" * " expr1 >= expr2\n" *
" expr1 == expr2\n")
end
looped = getloopedcode(c, code, :(), idxvars, idxsets, idxpairs, :(ConstraintRef{NonlinearConstraint}))
looped = getloopedcode(c, code, x, :(), idxvars, idxsets, idxpairs, :(ConstraintRef{NonlinearConstraint}))
code = quote
initNLP($m)
$looped
Expand Down
20 changes: 9 additions & 11 deletions test/model.jl
Expand Up @@ -47,10 +47,9 @@ facts("[model] Test printing a model") do
@defVar(modA, 2 <= z <= 4)
@defVar(modA, 0 <= r[i=3:6] <= i)
@setObjective(modA, Max, ((x + y)/2.0 + 3.0)/3.0 + z + r[3])
@defConstrRef constraints[1:3]
constraints[1] = @addConstraint(modA, 2 <= x+y <= 4)
constraints[2] = @addConstraint(modA, sum{r[i],i=3:5} <= (2 - x)/2.0)
constraints[3] = @addConstraint(modA, 7.0*y <= z + r[6]/1.9)
@addConstraint(modA, 2 <= x+y <= 4)
@addConstraint(modA, sum{r[i],i=3:5} <= (2 - x)/2.0)
@addConstraint(modA, 7.0*y <= z + r[6]/1.9)
#####################################################################
# Test LP writer
writeLP(modA, modPath * "A.lp")
Expand Down Expand Up @@ -179,10 +178,9 @@ context("With solver $(typeof(solver))") do
@defVar(modA, 2 <= z <= 4)
@defVar(modA, 0 <= r[i=3:6] <= i)
@setObjective(modA, Max, ((x + y)/2.0 + 3.0)/3.0 + z + r[3])
@defConstrRef cons[1:3]
cons[1] = @addConstraint(modA, x+y >= 2)
cons[2] = @addConstraint(modA, sum{r[i],i=3:5} <= (2 - x)/2.0)
cons[3] = @addConstraint(modA, 7.0*y <= z + r[6]/1.9)
cons1 = @addConstraint(modA, x+y >= 2)
cons2 = @addConstraint(modA, sum{r[i],i=3:5} <= (2 - x)/2.0)
cons3 = @addConstraint(modA, 7.0*y <= z + r[6]/1.9)

# Solution
@fact solve(modA) => :Optimal
Expand All @@ -205,9 +203,9 @@ context("With solver $(typeof(solver))") do
@fact getDual(r)[6] => roughly( 0.03759398, 1e-6)

# Row duals
@fact getDual(cons)[1] => roughly(-0.333333, 1e-6)
@fact getDual(cons)[2] => roughly( 1.0, 1e-6)
@fact getDual(cons)[3] => roughly( 0.0714286, 1e-6)
@fact getDual(cons1) => roughly(-0.333333, 1e-6)
@fact getDual(cons2) => roughly( 1.0, 1e-6)
@fact getDual(cons3) => roughly( 0.0714286, 1e-6)
end # solver context
end # loop over solvers
end # facts block
Expand Down
2 changes: 0 additions & 2 deletions test/print.jl
Expand Up @@ -164,8 +164,6 @@ facts("[print] JuMPContainer{Variable}") do
end
end



facts("[print] JuMPContainer{Number}") do
# The same output for REPL and IJulia, so only testing one
mod = Model()
Expand Down

0 comments on commit 1ef7595

Please sign in to comment.