pyomo icon indicating copy to clipboard operation
pyomo copied to clipboard

Interface to GiNaC for Simplification

Open michaelbynum opened this issue 1 year ago • 7 comments

Summary/Motivation:

This PR provides an interface to GiNaC for expression simplification (although sympy can be used as well).

In [1]: import pyomo.environ as pe

In [2]: from pyomo.core.expr import differentiate

In [3]: from pyomo.contrib.simplification import Simplifier

In [4]: from pyomo.contrib.fbbt.fbbt import compute_bounds_on_expr

In [5]: m = pe.ConcreteModel()
   ...: m.x = pe.Var(bounds=(0, None))
   ...: e = m.x * pe.log(m.x)

In [6]: der1 = differentiate(e, m.x, mode=differentiate.Modes.reverse_symbolic)
   ...: der2 = differentiate(der1, m.x, mode=differentiate.Modes.reverse_symbolic)

In [7]: simp = Simplifier()

In [8]: der2_simp = simp.simplify(der2)

In [9]: print(der2)
1/x - x/x**2 + 1/x

In [10]: print(der2_simp)
x**-1.0

In [11]: compute_bounds_on_expr(der2_simp)
Out[11]: (0.0, None)

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:

  1. I agree my contributions are submitted under the BSD license.
  2. I represent I am authorized to make the contributions and grant the license. If my employer has rights to intellectual property that includes these contributions, I represent that I have received permission to make contributions and grant the required license on behalf of that employer.

michaelbynum avatar Jan 10 '24 23:01 michaelbynum

Okay, I think tests will pass now. The GiNaC interface is only tested under "singletest" because it takes a while to install GiNaC.

michaelbynum avatar Jan 22 '24 14:01 michaelbynum

Codecov Report

Attention: 50 lines in your changes are missing coverage. Please review.

Comparison is base (85b63ab) 88.26% compared to head (125b7c7) 88.22%. Report is 87 commits behind head on main.

Files Patch % Lines
pyomo/contrib/simplification/build.py 18.33% 49 Missing :warning:
pyomo/contrib/simplification/simplify.py 97.36% 1 Missing :warning:
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3088      +/-   ##
==========================================
- Coverage   88.26%   88.22%   -0.05%     
==========================================
  Files         832      835       +3     
  Lines       92385    92484      +99     
==========================================
+ Hits        81544    81593      +49     
- Misses      10841    10891      +50     
Flag Coverage Δ
linux 85.98% <50.00%> (-0.04%) :arrow_down:
osx 75.49% <31.00%> (-0.05%) :arrow_down:
other 86.16% <50.00%> (-0.04%) :arrow_down:
win 83.37% <31.00%> (-0.06%) :arrow_down:

Flags with carried forward coverage won't be shown. Click here to find out more.

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

codecov[bot] avatar Jan 24 '24 07:01 codecov[bot]

FWIW, I got directed to this PR by John Siirola, and had an error:

Traceback (most recent call last):
  File "C:\Users\[REDACTED]\.conda\envs\idaes\lib\pdb.py", line 1723, in main
    pdb._runscript(mainpyfile)
  File "C:\Users\[REDACTED]\.conda\envs\idaes\lib\pdb.py", line 1583, in _runscript
    self.run(statement)
  File "C:\Users\[REDACTED]\.conda\envs\idaes\lib\bdb.py", line 598, in run
    exec(cmd, globals, locals)
  File "<string>", line 1, in <module>
  File "c:\users\[REDACTED]\repos\cesar_1\enrtl\enthalpy_validation_local_3.py", line 96, in <module>
    diff = simp.simplify(
  File "c:\users\[REDACTED]\repos\pyomo\pyomo\contrib\simplification\simplify.py", line 65, in simplify
    return simplify_with_sympy(expr)
  File "c:\users\[REDACTED]\repos\pyomo\pyomo\contrib\simplification\simplify.py", line 32, in simplify_with_sympy
    se = se.simplify()
AttributeError: 'int' object has no attribute 'simplify'
Uncaught exception. Entering post mortem debugging
Running 'cont' or 'step' will restart the program
> c:\users\[REDACTED]\repos\pyomo\pyomo\contrib\simplification\simplify.py(32)simplify_with_sympy()
-> se = se.simplify()
(Pdb) print(se)
0

I see now that I didn't end up installing GiNaC, so that's why it's using Sympy, but thought I should let you know about the issue in the present implementation.

Edit: Is there any tutorial about how to install GiNaC and make it available to Pyomo? I see there's parts of the PR to add GiNaC install to the CI, but I'm not sure how to translate that to my (Windows) machine.

dallan-keylogic avatar Apr 29 '24 22:04 dallan-keylogic

@dallan-keylogic - Thanks! Should be fixed now. Please let me know if my fix did not actually fix the problem.

Let me get back to you on installation.

michaelbynum avatar Apr 29 '24 23:04 michaelbynum

@dallan-keylogic, I don't have any better installation instructions than what is here: https://www.ginac.de/Download.html. Once you have GiNaC installed, you need to make sure the libraries and header files for both CLN and GiNaC are "findable". Ultimately those get used here: https://github.com/michaelbynum/pyomo/blob/1b1f944dbd00ca0e0b27d2fd2b70ee681b8e44ae/pyomo/contrib/simplification/build.py#L60.

michaelbynum avatar Apr 30 '24 11:04 michaelbynum

Unfortunately that fix didn't work:

Traceback (most recent call last):
  File "C:\Users\[REDACTED]\.conda\envs\idaes\lib\pdb.py", line 1723, in main
    pdb._runscript(mainpyfile)
  File "C:\Users\[REDACTED]\.conda\envs\idaes\lib\pdb.py", line 1583, in _runscript
    self.run(statement)
  File "C:\Users\[REDACTED]\.conda\envs\idaes\lib\bdb.py", line 598, in run
    exec(cmd, globals, locals)
  File "<string>", line 1, in <module>
  File "c:\users\[REDACTED]\repos\cesar_1\enrtl\enthalpy_validation_local_3.py", line 96, in <module>
    diff = simp.simplify(
  File "c:\users\[REDACTED]\repos\pyomo\pyomo\contrib\simplification\simplify.py", line 69, in simplify
    return simplify_with_sympy(expr)
  File "c:\users\[REDACTED]\repos\pyomo\pyomo\contrib\simplification\simplify.py", line 34, in simplify_with_sympy
    se = se.simplify()
AttributeError: 'int' object has no attribute 'simplify'
Uncaught exception. Entering post mortem debugging
Running 'cont' or 'step' will restart the program
> c:\users\[REDACTED]\repos\pyomo\pyomo\contrib\simplification\simplify.py(34)simplify_with_sympy()
-> se = se.simplify()
(Pdb) is_constant(se)
True
(Pdb) is_constant(expr_
*** SyntaxError: '(' was never closed
(Pdb) is_constant(expr)
False
(Pdb) expr
<pyomo.core.base.expression.ExpressionData object at 0x0000022960608880>
(Pdb) expr.pprint()
{Member of Liq_dalpha_dT} : Non-randomness parameters
    Size=28, Index=params.true_species_set*params.true_species_set
    Key            : Expression
    ('H2O', 'H2O') :        0.0
(Pdb) expr.is_constant()
False
(Pdb) type(expr)
<class 'pyomo.core.base.expression.ExpressionData'>

It looks like is_constant always returns false for ExpressionData.

Let me try installing GiNaC and get back to you on that.

dallan-keylogic avatar Apr 30 '24 13:04 dallan-keylogic

The link for Windows builds of GiNaC is broken, so that probably ends this experiment for me.

dallan-keylogic avatar Apr 30 '24 13:04 dallan-keylogic

@jsiirola, should sympyify_expression convert mutable parameters to sympy symbols like it does for variables? I think this is what is causing @dallan-keylogic's error (not 100% sure).

michaelbynum avatar May 07 '24 16:05 michaelbynum

Another question for @jsiirola - right now, the simplification logic using sympy will remove mutable parameters from the expression. I'm not sure how I feel about that. I don't really know what the expected behavior should be. Thoughts?

michaelbynum avatar May 07 '24 16:05 michaelbynum

Unfortunately, in my current model I have some "mutable" parameters that are equal to zero and that I never want to change, but they're forced to be mutable because they have units. I think that AD is fixed so I could just turn them into 0 multiplied by units, though.

dallan-keylogic avatar May 07 '24 16:05 dallan-keylogic

There seem to be issues with get_tar_archive on windows

michaelbynum avatar May 07 '24 17:05 michaelbynum

Thanks for all the help on this one, @jsiirola.

michaelbynum avatar May 08 '24 16:05 michaelbynum

@dallan-keylogic, I believe we did fix the mutable parameter issue as part of the PR (with the sympy interface).

michaelbynum avatar May 13 '24 14:05 michaelbynum