-
-
Notifications
You must be signed in to change notification settings - Fork 398
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
Should we simplify NonLinearExpr similar to AffExpr or QuadExpr? #3498
Comments
I was hesitant to make too many changes to the expression graph. For example, which of the following is desired? julia> flatten!(sum(x^5+i for i∈1:4))
(x ^ 5) + (x ^ 5) + (x ^ 5) + (x ^ 5) + 1.0 + 2.0 + 3.0 + 4.0
julia> flatten!(sum(x^5+i for i∈1:4))
(x ^ 5) + (x ^ 5) + (x ^ 5) + (x ^ 5) + 10.0
julia> flatten!(sum(x^5+i for i∈1:4))
4 * (x ^ 5) + 10.0 But I think it is reasonable to drop any |
’flatten!’ does a decent job of simplifying as is. Obviously, I'd prefer the reverse order of the examples you gave, but can see how issues would arise. Dropping zeros would be sufficient, at least for the moment, and if I need more I'll write and propose a ’simplify’ function or something similar. |
We had a discussion here: #3502 One issue that came up is users might expect us to simplify more than just dropping If you are reading this issue and have an example in which simplifying would make a difference, please post it. If we get enough requests, we may revisit this problem. |
Just to weigh in on this: Currently, I have the problem that |
Yes, I think this is our conclusion too.
This happens for any quadratic terms, because they get represented as julia> model = Model();
julia> @variable(model, x)
x
julia> @expression(model, sin(x) + (x - 0.1)^2)
sin(x) + (x² - 0.2 x + 0.010000000000000002) Because of the way that JuMP parses the macros, there is no easy way to override this behavior. |
My current workaround is adding a dummy variable fixed to zero and formulate @expression(model, sin(x) + (dummy^3 + x - 0.1)^2) |
@Downsite we added julia> model = Model(); @variable(model, x);
julia> @expression(model, @force_nonlinear sin(x) + (x - 0.1)^2)
sin(x) + ((x - 0.1) ^ 2)
julia> @expression(model, sin(x) + @force_nonlinear((x - 0.1)^2))
sin(x) + ((x - 0.1) ^ 2)
julia> @force_nonlinear @expression(model, sin(x) + (x - 0.1)^2)
sin(x) + ((x - 0.1) ^ 2) For the main issue, I think our answer to this is "no". Adding simplification rules by default in JuMP just introduces the risk of problems. We want the nonlinear expressions to be passed to the solver pretty much as-is. In the future, we could consider adding a |
I'm tempted to close this. I don't know if there's anything actionable left to do here. |
Closing as won't-fix for now. We can always revisit this in the future, but I think the first step is to develop some sort of MOI nonlinear presolve layer to test ideas. This doesn't need to happen in JuMP.jl, and it doesn't need to be one of the core contributors, so if you are reading this comment and are interested, feel free to explore with some ideas in a new repository 😄 |
Explanation of Issue
I'll start this with an example of the issue
The issue is the difference between
and
Notice both
test
andtest_nl
differ only in powers, buttest
drops any term multiplied by 0 whereastest_nl
does not. This is deeper than just the@show
method, as can be seen here:The zero terms no longer exist in
test
.I typically work with large, sparse matrices meaning there are many zero terms. Dropping these zero terms reduces the model complexity and agrees with what one would expect.
This may also speed up the evaluator in the situation, as an extreme example, where you have an$n\times n$ diagonal matrix and a constraint of the form $Ax^m = b$ . If $m=1,2$ there are $n$ evaluations, otherwise there are currently $n^2$ .
Solution Suggestion
My suggestion to fix this is to implement
drop_zeros!
on NonLinearExpr. I'm guessing that is the culprit. This is more complicated on a NonLinearExpr as it requires recursing the leaves of a tree.One compounding issue
In general NonLinearExpr don't simplify
This is related to the above, but more general. This is something to keep in mind when working on the above, but implementing this may be non-trivial.
*edit:
flatten!
gets close to fixing the abovebut not quite perfect.
The text was updated successfully, but these errors were encountered: