Search code examples
pyomononlinear-optimizationderivative

Computing the gradient of an objective function evaluated at the optimum in a dynamic optimization problem, pyomo


I am computing the solution to a dynamic non-linear optimization problem, that I set up usign the pyomo library. I use a ConcreteModel, with an objective function and several constraints, all time-indexed. My objective function takes the form of a ScalarObjective (I am solving a dynamic general equilibrium problem in which I seek to maximize total welfare). I would like to compute the gradient of the objective, evaluated at the optimum, with respect to one of the model's variables at a given period t. My problem is a discrete-time problem.

I have tried many different options, asking AI chatbots for help (both You Chat and ChatGPT), but every solution I'm given is incorrect -- on this topic the AI chatbots seem to know very little. I feel that some method in the library pyomo.dae could be of help, but I haven't found a solution yet. Could anyone help me, please?


Solution

  • You can do this using Pyomo's differentiate function. Here is a toy example:

    import pyomo.environ as pyo
    from pyomo.core.expr.calculus.derivatives import differentiate
    m = pyo.ConcreteModel()
    m.x = pyo.Var()
    m.con = pyo.Constraint(expr=m.x<=10)
    m.obj = pyo.Objective(expr=m.x**2)
    pyo.SolverFactory('ipopt').solve(m)
    print(pyo.value(m.x))
    # -1.2528349584581178e-10
    
    # Evaluate the derivative at current value of m.x
    ddx = differentiate(m.obj, wrt=m.x)  
    print(ddx)
    # -2.5056699169162357e-10
    
    # Return derivative expression
    ddx2 = differentiate(m.obj, wrt=m.x, mode='sympy')
    print(ddx2)
    # 2.0*x
    

    You can read more about this function here: https://github.com/Pyomo/pyomo/blob/main/pyomo/core/expr/calculus/derivatives.py#L31