Extract Jacobian for equality constraints then embed symbolic expressions in constraints
Summary
I have a square Pyomo model with equality constraints $h(y,p) = 0$. I want to compute $\nabla_y h$ and $\nabla_p h$ for this model and then embed those expressions into Pyomo constraints. $h(.,.)$ is nonlinear, for the Jacobian will not be constant.
#3561 sparked my interest in this.
Rationale
This feature would be handy for Pyomo.DoE and uncertainty quantification (UQ) more broadly. In the current Pyomo.DoE/ParmEst abstraction, $h(.,.)$ is the experiment model. $y$ are the annotated measurements and $p$ are the annotated parameters. The model is square when the measurement decisions $x$ (not shown) and parameters $p$ are fixed.
If we can compute the Jacobians with automatic differentiation (AD), we can add the constraint:
$\nabla_p h = - \nabla_y h \nabla_p y$
Notice that $\nabla_p y$ is the sensitivity matrix $Q$ we need for Pyomo.DoE. In Pyomo.DoE, we currently use finite difference to approximate $Q$. Performing automatic differentiation on $h(.,.)$ would allow us to have a much more compact Pyomo.DoE formulation.
Description
See above.
Could you point me to examples of performing AD on Pyomo constraints and then using those symbolic AD results to construct new Pyomo constraints/expressions? I think PyNumero interfaces with the AMPL AD, but returns the derivatives evaluated at a current point. I was the symbolic derivates. (Please correct me if this understanding of PyNumero is incorrect.)
Additional information
See above.
This should all be possible. We can compute symbolic derivatives with respect to both variables and parameters:
In [1]: import pyomo.environ as pe
...: from pyomo.core.expr.calculus.diff_with_pyomo import reverse_sd
...: m = pe.ConcreteModel()
...: m.x = pe.Var()
...: m.p = pe.Param(initialize=7, mutable=True)
...: e = m.x**2 + pe.log(m.p)
In [2]: for k, v in reverse_sd(e).items():
...: print(f'derivative with respect to {str(k)} is {str(v)}')
...:
derivative with respect to x is 2*x
derivative with respect to 2 is 0
derivative with respect to x**2 is 1
derivative with respect to p is 1/p
derivative with respect to log(p) is 1
derivative with respect to x**2 + log(p) is 1
Let me know if I am missing something.
@michaelbynum Thank you. Is there an easy way to take a constraint and compute its symbolic derivative relative to a variable? I then want to add the symbolic expression as another constraint.
I am working in a notebook here: https://github.com/dowlinglab/pyomo-doe/pull/8
For the example in the linked repo, I have a model with equality constraints $h(x)=0$. As a starting point, I want to assemble the Jacobian matrix $\nabla_x h$ symbolically.
Just in case anyone else is tracking this issue, @adowling2's notebook has a nice example of this.
The example is nice thank you to @michaelbynum!
I started to implement these ideas in Pyomo.DoE! See https://github.com/adowling2/pyomo/pull/7