-
-
Notifications
You must be signed in to change notification settings - Fork 399
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
syntax brainstorming #692
Comments
I think I like idea 2 variant 1 best. Idea 1 seems too busy, and the syntax too weird, to me. If you go with the |
Yes, a single |
I agree with David on idea 2 variant 1. I also never liked the |
I prefer idea 2 variant 2 the most of the options presented, but still find it less satisfying than the current syntax. We lose the bounds for syntax which I like very much, and although the assignment is a bit clearer with the |
Currently @defVar(m, buy[1:n] >= 0, Int)
@defVar(m, 0 <= send[i=1:n,j=1:n] <= capacity[i,j])
@defVar(m, 0 <= sold[i=1:n] <= demand[i]) Idea 1 @variables m begin
buy = (Variable[i=1:n](Int) >= 0)
send = (0 <= Variable[i=1:n,j=1:n] <= capacity[i,j]))
sold = (0 <= Variable[i=1:n] <= demand[i])
end Idea 1 Var. 1 @jump m begin
buy = Variable[i=1:n](Int, lowerbound=0)
send = Variable[i=1:n,j=1:n](lowerbound=0,upperbound=capacity[i,j])
sold = Variable[i=1:n](Int, lowerbound=0,upperbound=demand[i])
end Idea 1 Var. 2 @jump m begin
buy[i=1:n] = Variable(Int, lowerbound=0)
send[i=1:n,j=1:n] = Variable(lowerbound=0,upperbound=capacity[i,j])
sold[i=1:n] = Variable(Int, lowerbound=0,upperbound=demand[i])
end I don't really find any of them an improvement to be honest. |
acpower @defVar(mod, bus_voltage_min[bus[i].bustype] <= bus_voltage[i=1:nbus] <= bus_voltage_max[bus[i].bustype], start=1)
@defVar(mod, bus[i].b_shunt_min <= bus_b_shunt[i=1:nbus] <= bus[i].b_shunt_max, start=bus[i].b_shunt0) or @defVar(mod, bus_voltage_min[bus[i].bustype] <=
bus_voltage[i=1:nbus] <=
bus_voltage_max[bus[i].bustype], start=1) Idea 1 Var 2, formatted nicely @jump b begin
bus_voltage[i=1:nbus] = Variable(start=1,
lowerbound=bus_voltage_min[bus[i].bustype],
upperbound=bus_voltage_max[bus[i].bustype])
bus_b_shunt[i=1:nbus] = Variable(start=bus[i].b_shunt0,
lowerbound=bus[i].b_shunt_min,
upperbound=bus[i].b_shunt_max)
end |
That could be arguably better? |
Definitely a lot clearer without any context what is happening in the statement. |
Variant 2 of Idea 2 definitely will still have the "extension" problem, but Variant 1 will not I think. |
Yes, I prefer variant 1 |
Agreed that it's better in Iain's example. But again I think in that example it's the Of the variants, I might actually prefer 2 now, because I think you want to be able to see quickly both the variable name and its indexing, and they're nicely aligned on the left before |
The syntax
isn't available to us, would have to be
|
Echoing joey: I also really like the bounds syntax of at-defVar for most problems that I write. If you insist, you can align names using whitespace, e.g. @defVar(m, x[i=1:p.nlocations] >= 0, Int, start=warmstart[i])
@defVar(m, d[1:nregions] >= 0, Int)
@defVar(m, 0 <= p[1:nregions] <= ub)
@defVar(m, lowerbound <= q[1:nlocations] <= upperbound) it's also why I used to write two-sided bounds the other way round, i.e. @defVar(m, x[i=1:nlocations] >= 0, Int, start=warmstart[i])
@defVar(m, d[1:nregions] >= 0, Int)
@defVar(m, ub >= p[1:nregions] >= 0)
@defVar(m, upperbound >= q[1:nlocations] >= lowerbound) For complicated formulations, I find the proposals minor improvements over explicit constructions of JuMP Variables, and have not had as much opportunities to remember to use them. |
I like Idea 1 Var. 2
|
I'd like a common prefix for all macro like @jump (or even @jp): @jump m begin send[i=1:n,j=1:n] = Variable(something complicated, but we already now that send is an array) send[i=1:n,j=1:n] = Variable(lowerbound=0,upperbound=capacity[i,j]) ... (others variables) c_kirchoff[i=1:n] = Contraint(...) ... (other constrants_ end # later we define one more variable with a possibly newer syntaxe that @defVar: @jumpVar(m, ...) # or one more constraint @jumpCst(m, ...) @jumpSolve(...) ... -- Maurice |
There doesn't seem to be too much consensus here, so I don't see any big changes happening soon. The next step forward to proceed with this would be for someone to put together a prototype JuMP extension to test out the new syntax. |
I think it needs to be tried out for some nontrivial problems/index sets to really capture the impact. Hopefully the things I added here capture at least some use cases |
Another point here is that we're removing the semicolon from the @variable(m, x[i,j] for i in X, j in Y if i <= j) |
Does that parse reasonably? |
@joehuchette, yes, the second argument to the macro is a generator statement. |
I like it. Some comments:
|
Anything you can loop over in Julia.
I wouldn't want to keep multiple inconsistent syntaxes around. If we make a change like this we should be convinced that it's obviously better than the |
Let me enumerate the big issues with the current syntax:
If we can find a new syntax that addresses all of these issues and is visually appealing then I could be convinced to switch. |
I like the idea of lb, ub kwargs in place of I am also a fan of using the generator syntax, although it probably does not immediately resolve point 2. I like the original "idea 2" proposals for addressing this issue. When first learning JuMP it was confusing to me that the variable declaration appears to occur inside a function/macro arguments. In other solver APIs I have seen things along the lines of,
Variable constructors only support 1 variable at a time and comprehensions are used for making groups of variables. Inspired by that, here is a proposal,
By disconnecting the index set from the name of the variable, I suspect it would prevent the confusion around being able to add indexes to sets. If the variable object pointer became the unique key for all variables in a model you could even imagine a syntax along the lines of,
|
In response to the points Miles raised:
I am not in favour of removing the |
The reason we didn't do this before was lack of anonymous variables. Now that we have these, I'd be in favor of a warning in this case. I don't even see a compelling reason why we should allow people to disable the warning.
The syntax |
@ccoffrin, if the syntax is
where you don't know if you're declaring an anonymous set of variables indexed over S or a single variable named S. |
Bed time for me by the way. This is very promising and I'll pick this up tomorrow. |
|
I feel like |
I think @odow's case is a case where set intersection reasoning could pay off, something like |
I think this has a number of things going for it. It plays nicely of Julia's type system. It gets rid of the ternary Single variable type
Nesting variable types
Generators
Anonymous Variables
|
A few comments:
doesn't feel right because x is not restricted to the interval
doesn't parse with the right precedence. It should be
I like how the latter reads as PSD and Integer.
This seems confusing because |
My thoughts:
|
@joehuchette, I'd agree that |
I disagree. Someone without julia programming experience won't know what the |
The problem I have with variations on If the point of changing the syntax is to make it more intuitive, and JuMP doesn't reformulate these cases, then this goes against that. I would almost argue that we don't need intersecting types. If there is
As a side note/tangent: what are the downsides of stictly typing variables?
|
The first is valid (if we choose), while the other three are errors. If we want to support more exotic CP-style set constraints later on, the syntax is already there, and we can just remove the errors.
Why? IMO
There are some potential compiler optimizations that may be impossible (i.e. packing |
I think we should aim for a well-defined concept of the domain of a variable (or collection of variables) that can be constructed programmatically, and then find the right syntax for it. We're having trouble deciding how integer/bounds/semicontinuous/PSD restrictions interact because it's been pretty ad-hoc up to this point. Now is the right time to look forward to make the concepts and syntax general enough to allow for future extensions to JuMP that could allow unions of domains and/or CP-style domains. |
I agree, but I think the there are two somewhat orthogonal questions here. One is what types/operations to define so that |
@joehuchette, I think it also affects the question of |
That's a question of syntax, though. Let's choose what we feel is most natural, as you're not going to be programmatically generating that code. If we want to add support for something like D = Integer(0,5)
@variable(m, x in D) later, we can. |
@joehuchette, could you sketch up a proposal analogous to #692 (comment)? |
Single variable type @variables(m, begin
x
x in [l, u] # simple interval
x <= u # one sided bound
x >= l # one sided bound
x in {0,1}
x in [l, u], Integer
x >= l, Integer
x in {0} ∪ [l, u] # SemiContinuous
x in {0} ∪ [l, u], Integer # SemiInteger
x[1:N,1:N], PSD
x[1:N,1:N], Symmetric
x >= 0 # NonNegative
x <= 0 # NonPositive
end) Nesting variable types ∩ or & @variables(m, begin
x[1:N,1:N], PSD, Integer
x <= 0, Integer # NonPositive
end) Anonymous Variables x = @variable(m, lowerbound=1) # distinguished by the keyword argument
x = @variable(m, lowerbound=1) The generators don't play nicely with the variable type specification (or any keyword arguments, for that matter), so that will take some more thought. |
Well.. we could double down on the @variable(m, x[i,j]::Integer(name="x[$i,$j]") in [l[i], u[j]] for i in I, j in J if i <= j)
@variable(m, x[i,j]::Integer(name="x[$i,$j]",lowerbound=l[i],upperbound=u[i]) for i in I, j in J if i <= j) |
Declaring variables shouldn't be that hard, not sure why we would need multiple macros for it. |
I think it's quickly becoming confusing* whether the @domain(m, D[i],
variabletype = Integer,
lowerbound = l[i],
upperbound = u[i]
)
@variable(m, x[i,j] in D[i] for i in I, j in J if i <= j) where
That allows existing users of JuMP to not worry about a whole new set of rules. *case in point: |
I'm not opposed to new suggestions/syntax. But echoing #692 (comment), it feels alarming when it's supposed to "unify" everything (for existing users to stay in the loop and get their opinions heard), when preferences differ across communities. Given that it might take a while to assess the suitability of various proposals for describing different domains, providing a separate macro for it allows for existing users to not have to worry too much about keeping up with ideas for syntax innovations.
Does your preference extend to the |
My intent is to close this issue if there's no substantial progress made at the meetup next week. At this point, radical syntax changes should be first implemented and tested by multiple people in a separate package before we'd force them onto JuMP users. |
I think set inclusion syntax for variables would go a long way, and would be relatively easy to add. |
We can open a separate issue for that, because the scope of this issue is
much broader.
…On Jun 10, 2017 13:41, "Joey Huchette" ***@***.***> wrote:
I think set inclusion syntax for variables would go a long way, and would
be relatively easy to add.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#692 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ABp0M28bSDwmk_KtHC6dPrzU-88OWW8oks5sCtVKgaJpZM4HqDr7>
.
|
Addressing the issue raised in #688, the current syntax of
@defVar
, despite the name, doesn't make it clear that all we're doing is defining a julia variable. Maybe it's time to brainstorm a new approach:Both examples below are valid julia syntax:
Idea 1:
The trouble here is that it looks like you're assigning x to refer to the constraints enforcing the bounds instead of the variables.
Idea 2:
We lose some of the magic of using comparison operators, but maybe this is much clearer. You can always use explicit constraints instead if you prefer the mathy syntax. Of the two variants I prefer the first because it's more clear that we're just assigning a collection of variables to
x
whereas the second variant might lead you to think that you can append indices tox
later on.CC @StefanKarpinski @carnaval @yeesian @JackDunnNZ @davidanthoff @juan-pablo-vielma @chriscoey
The text was updated successfully, but these errors were encountered: