-
-
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
Simplify NonlinearExpr with + or * and 1 or 0 #3502
Conversation
Codecov ReportPatch coverage:
Additional details and impacted files@@ Coverage Diff @@
## master #3502 +/- ##
==========================================
- Coverage 98.13% 98.12% -0.02%
==========================================
Files 37 37
Lines 5536 5555 +19
==========================================
+ Hits 5433 5451 +18
- Misses 103 104 +1
☔ View full report in Codecov by Sentry. |
I'm still testing this, but have observed the following:
The simplification only takes hold inside an I'm going to test this more tomorrow morning. |
Correct |
I don't really know how I feel about this. Is there any evidence that keeping the The overhead of walking every expression just to see if there is a |
I'm tending towards agreeing that it's mainly aesthetic and probably adds
unnecessary overhead to model creation.
I'm fine if this gets shelved. I may build a more specific solution for my
use case.
…On Mon, Sep 11, 2023, 8:56 PM Oscar Dowson ***@***.***> wrote:
I don't really know how I feel about this. Is there any evidence that
keeping the +0 and *0 is a problem? Do we just want to remove them
because it looks nice?
The overhead of walking every expression just to see if there is a +0
might be larger than continuing with one. One problem here is that it makes
* unstable, because it might return 0.0 or it might return a nonlinear
expression.
—
Reply to this email directly, view it on GitHub
<#3502 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AEVAPXKDDMCG7RCHTTOJCN3XZ66NZANCNFSM6AAAAAA4UBXKQU>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
I do think this is a nice to have, and I can see people requesting it in future. Maybe I should try what you suggested, and add |
Having an optional function would be nice. 90% of the time that operation
isn't necessary, but it's nice to have for that 10%.
The type instability is intriguing to me. I'm guessing this comes from
something like $0*x^5+x^2$ becoming quadratic after `drop_zeros!` is
applied. Is there an issue forcing it to remain nonlinear?
…On Mon, Sep 11, 2023, 9:23 PM Oscar Dowson ***@***.***> wrote:
I do think this is a nice to have, and I can see people requesting it in
future.
Maybe I should try what you suggested, and add drop_zeros!, which
wouldn't be type stable and would be opt-in by users.
—
Reply to this email directly, view it on GitHub
<#3502 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AEVAPXPZYMNY2DZ6QIU5LKTXZ7BQZANCNFSM6AAAAAA4UBXKQU>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
It would come from a definition like this: Base.:*(x::Real, y::NonlinearExpr) = iszero(x) ? x : NonlinearExpr(:*, Any[x, y]) Now in |
So one option would be: _is_zero(x::Real) = iszero(x)
_is_zero(::Any) = false
_is_one(x::Real) = isone(x)
_is_one(::Any) = false
simplify(x) = x
simplify(x::Union{GenericAffExpr,GenericQuadExpr}) = drop_zeros!(x)
function simplify(x::GenericNonlinearExpr{V}) where {V}
if x.head == :* && any(_is_zero, x.args)
return zero(value_type(V))
end
for i in 1:length(x.args)
x.args[i] = simplify(x.args[i])
end
if x.head == :*
filter!(!_is_one, x.args)
elseif x.head == :+
filter!(!_is_zero, x.args)
end
if x.head == :+ || x.head == :* && length(x.args) == 1
return x.args[1]
end
return x
end So it's a fairly simple feature addition. But I think it could wait for a bit more usage. It feels like we might want a much more robust expression rewriting system that deals with more than just |
The Symbolics.jl (or SymbolicUtils.jl) package has code that does this, simplify.jl. But then they have a helper, simplify_rules.jl, that has a long list of identities and special algebra rules. This is a lot to add right now, especially for cosmetics. |
Yeah the expectations that I think we can wait for the current stuff to be out in the world for a while before we decide to add anything. |
I'm going to close this PR for now, but I'll leave the issue open. |
One possible fix for #3498
@mitchphillipson could you try out this branch? (
] add JuMP#od/nlp-simplify
).It'd be useful if you had the test cases using sparse matrices.