Skip to content
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

Quadratic term not identified by generate_standard_repn #1287

Closed
michaelbynum opened this issue Feb 7, 2020 · 5 comments · Fixed by #1493
Closed

Quadratic term not identified by generate_standard_repn #1287

michaelbynum opened this issue Feb 7, 2020 · 5 comments · Fixed by #1493

Comments

@michaelbynum
Copy link
Contributor

>>> import pyomo.environ as pe                                                                                                                                                                                               
>>> from pyomo.repn.standard_repn import generate_standard_repn
>>> m = pe.ConcreteModel()
>>> m.x = pe.Var()
>>> m.y = pe.Var()
>>> print(generate_standard_repn((m.x + m.y)**2, quadratic=True))

constant:       0
linear vars:    []
linear var ids: []
linear coef:    []
quadratic vars:    []
quadratic var ids: []
quadratic coef:    []
nonlinear expr:
(x + y)**2
nonlinear vars: ['x', 'y']
@carldlaird
Copy link
Member

@michaelbynum good catch. We should also consider adding an explicit QuadraticExpression object like we have for LinearExpression.

@johwiebe
Copy link
Contributor

johwiebe commented Jun 9, 2020

@michaelbynum I also just came across this issue. I noticed that there is a test which asks for this behaviour. Is this by design for some reason?

e = (m.a+m.b)**2
rep = generate_standard_repn(e, compute_values=False, quadratic=False)
#
self.assertFalse( rep.is_fixed() )
self.assertEqual( rep.polynomial_degree(), None )
self.assertFalse( rep.is_constant() )
self.assertFalse( rep.is_linear() )
self.assertFalse( rep.is_quadratic() )
self.assertTrue( rep.is_nonlinear() )
#
self.assertTrue(len(rep.linear_vars) == 0)
self.assertTrue(len(rep.linear_coefs) == 0)
self.assertTrue(len(rep.quadratic_vars) == 0)
self.assertTrue(len(rep.quadratic_coefs) == 0)
self.assertFalse(rep.nonlinear_expr is None)
self.assertTrue(len(rep.nonlinear_vars) == 2)
baseline = { }
self.assertEqual(baseline, repn_to_dict(rep))
rep = generate_standard_repn(e, compute_values=False, quadratic=True)
#
self.assertFalse( rep.is_fixed() )
self.assertEqual( rep.polynomial_degree(), None )
self.assertFalse( rep.is_constant() )
self.assertFalse( rep.is_linear() )
self.assertFalse( rep.is_quadratic() )
self.assertTrue( rep.is_nonlinear() )
#
self.assertTrue(len(rep.linear_vars) == 0)
self.assertTrue(len(rep.linear_coefs) == 0)
self.assertTrue(len(rep.quadratic_vars) == 0)
self.assertTrue(len(rep.quadratic_coefs) == 0)
self.assertFalse(rep.nonlinear_expr is None)
self.assertTrue(len(rep.nonlinear_vars) == 2)
baseline = { }
self.assertEqual(baseline, repn_to_dict(rep))

@michaelbynum
Copy link
Contributor Author

@johwiebe The test you mentioned does not actually expect this behavior. The key is the quadratic=False keyword argument to the generate_standard_repn function. When quadratic=False, quadratic terms are not identified (only linear).

@johwiebe
Copy link
Contributor

johwiebe commented Jun 9, 2020

@michaelbynum I think that's just the first part of the test. On line 3141 the same expression is tested with quadratic=True:

rep = generate_standard_repn(e, compute_values=False, quadratic=True)
#
self.assertFalse( rep.is_fixed() )
self.assertEqual( rep.polynomial_degree(), None )
self.assertFalse( rep.is_constant() )
self.assertFalse( rep.is_linear() )
self.assertFalse( rep.is_quadratic() )
self.assertTrue( rep.is_nonlinear() )
#
self.assertTrue(len(rep.linear_vars) == 0)
self.assertTrue(len(rep.linear_coefs) == 0)
self.assertTrue(len(rep.quadratic_vars) == 0)
self.assertTrue(len(rep.quadratic_coefs) == 0)
self.assertFalse(rep.nonlinear_expr is None)
self.assertTrue(len(rep.nonlinear_vars) == 2)
baseline = { }
self.assertEqual(baseline, repn_to_dict(rep))

The expected outcome with and without quadratic=False seems to be the same.

@michaelbynum
Copy link
Contributor Author

@johwiebe Oh, I apologize. I did not scroll far enough. Good catch. I don't think this behavior is by design.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants