Description
Summary
When terms in the expression cancel, polynomial_degree
does not calculate this and reports the wrong answer.
In addition, when variables are fixed to 0 so as to make a 0 coefficient, it is possible to fool polynomial_degree
into thinking that the degree is 1 when in fact it is 0. It seems that it should be an option to calculate the degree treating fixed Vars as constants or treating them as variables.
The beginning of this conversation is in the tail of #2271.
Steps to reproduce the issue
@jsiirola mentioned this one, but these examples don't involve fixing variables at all:
m = ConcreteModel()
m.x = Var()
m.e1 = Expression(expr=m.x -m.x)
print(m.e1.polynomial_degree()) # 1
m.e2 = Expression(expr=m.x**2 - m.x**2)
print(m.e2.polynomial_degree()) # 2
But there is also an inconsistency between generate_standard_repn
and polynomial_degree
when parts of the expression are multiplied by subexpressions that are fixed to 0:
m.y = Var()
m.z = Var()
m.e4 = Expression(expr=(m.x + m.y)*m.z)
print(m.e4.polynomial_degree()) # 2
m.x.fix(0)
m.y.fix(0)
print(m.e4.polynomial_degree()) # 1 (This is objectively wrong... If not 0, then 2 makes more sense.)
m.e5 = Expression(expr=(m.x**2 + m.y)*m.z)
print(m.e5.polynomial_degree()) # 1 (Again, I think 0 and 3 are the only correct answers here.)
# You don't even have to get fancy
m.e6 = Expression(expr=m.x*m.z)
print(m.e6.polynomial_degree()) # 1
Note that generate_standard_repn
for m.e4
, m.e5
, and m.e6
is 0 for all.
Information on your system
Pyomo version: 6.2
Python version: all
Operating system: all
How Pyomo was installed (PyPI, conda, source): N/A
Solver (if applicable): N/A