-
Notifications
You must be signed in to change notification settings - Fork 525
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
Identify squared linear sums as quadratic with generate_standard_repn #1493
Conversation
generate_standard_repn applied to (x+y)**2 now returns a quadratic expression.
Standard repn for this should be m.a*m.a + 2*m.a*m.b + m.b*m.b which is quadratic.
The square of a linear sum should be quadratic.
Codecov Report
@@ Coverage Diff @@
## master #1493 +/- ##
==========================================
+ Coverage 72.35% 72.38% +0.02%
==========================================
Files 608 608
Lines 85595 85642 +47
==========================================
+ Hits 61933 61991 +58
+ Misses 23662 23651 -11
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is OK to merge. The tests highlight a nondeterminism in the internal Results
data structures, but resolving that is beyond the scope of this PR and I believe should be dealt with elsewhere (see #1073 and the solver-rewrite).
pyomo/repn/standard_repn.py
Outdated
for key2, coef2 in res.linear.items(): | ||
ans.quadratic[key1,key2] = 2*multiplier*coef1*coef2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that this is inherently nondeterministic. Unfortunately, this is a flaw in the current Results data structures. It will be resolved n an upcoming rewrite of generate_standard_repn (see #1073 and the draft implementation on the solver-rewrite branch)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I stand corrected. @carldlaird pointed out to me that this can be made deterministic relatively easily. Expect a PR from him that will resolve this and then we can merge.
Fixes #1287
Summary/Motivation:
generate_standard_repn
should recognize the square of a linear sum(x_1 + x_2 + ... + x_n)**2
as a quadratic whenquadratic=True
. It currently returns a nonlinear expression if the linear sum has more than one term. This leads, e.g., to issues when trying to solve a model with a quadratic constraint of this form with Gurobi.Note that there is a test case which asks for this behavior for expression
e = (m.a + m.b)**2
:pyomo/pyomo/repn/tests/test_standard.py
Lines 3141 to 3157 in 7920516
Am I missing a reason why this behavior might be wanted?
Changes proposed in this PR:
_collect_pow
returns a quadratic expression for anyPowExpression
with linear base and exponent 2. The underlying logic is:(sum_i x_i)**2 = sum_i sum_j x_i*x_j = sum_i x_i**2 + 2*sum_i sum_{j<i} x_i*x_j
(m.a + m.b)**2
which currently expectsgenerate_standard_repn
to return a nonlinear expression.(linear sum)**2
with more than two variables.Legal Acknowledgement
By contributing to this software project, I have read the contribution guide and agree to the following terms and conditions for my contribution: