在 pyomo 如何从 objective 函数中提取二阶导数
In pyomo how can one extract the second derivative from the objective function
我正在使用 pyomo,并且已经定义了一个模型,并带有一个 objective 函数。模型求解后,objective 函数附加了某些参数。因此,如果我有一个多索引变量 [x1, x2, x3]
,我的二次 objective 函数将看起来像这样:(x1^2 + 13*x2^2 + 10*x3^2) + (2*x1 +......)
。
我的问题是:鉴于我实际上可以从 objective 访问字符串格式的表达式,是否有任何方法可以获取此函数关于所有变量的二阶导数?
Pyomo中有两种获取衍生信息的方式
如果您需要在单个点上进行数值导数,您可以使用像 "gjh_asl_json" 工具 (https://github.com/ghackebeil/gjh_asl_json) 这样的工具,该工具可以获取 Pyomo 生成的 NL 文件并生成 JSON 包含 Jacobian 和 Hessian 信息的文件。
如果您需要符号导数,Pyomo 可以直接提供这些,前提是您还安装了 sympy
:
from pyomo.core.base.symbolic import differentiate
from pyomo.core.base.expr import identify_variables
# assuming model.objective is your Objective component
varList = list( identify_variables(model.objective.expr) )
firstDerivs = differentiate(model.objective.expr, wrt_list=varList)
# Note this calculates d^2/dx_i^2; if you want the full Hessian matrix
# ( \delta^2/{\delta x_i \delta x_j} ) replace "wrt=v" with "wrt_list=varList"
secondDerivs = [ differentiate(firstDerivs[i], wrt=v) for i,v in enumerate(varList) ]
当然,假设你的表达式是二次的,符号微分和数值微分都会给你相同的答案。
我正在使用 pyomo,并且已经定义了一个模型,并带有一个 objective 函数。模型求解后,objective 函数附加了某些参数。因此,如果我有一个多索引变量 [x1, x2, x3]
,我的二次 objective 函数将看起来像这样:(x1^2 + 13*x2^2 + 10*x3^2) + (2*x1 +......)
。
我的问题是:鉴于我实际上可以从 objective 访问字符串格式的表达式,是否有任何方法可以获取此函数关于所有变量的二阶导数?
Pyomo中有两种获取衍生信息的方式
如果您需要在单个点上进行数值导数,您可以使用像 "gjh_asl_json" 工具 (https://github.com/ghackebeil/gjh_asl_json) 这样的工具,该工具可以获取 Pyomo 生成的 NL 文件并生成 JSON 包含 Jacobian 和 Hessian 信息的文件。
如果您需要符号导数,Pyomo 可以直接提供这些,前提是您还安装了 sympy
:
from pyomo.core.base.symbolic import differentiate
from pyomo.core.base.expr import identify_variables
# assuming model.objective is your Objective component
varList = list( identify_variables(model.objective.expr) )
firstDerivs = differentiate(model.objective.expr, wrt_list=varList)
# Note this calculates d^2/dx_i^2; if you want the full Hessian matrix
# ( \delta^2/{\delta x_i \delta x_j} ) replace "wrt=v" with "wrt_list=varList"
secondDerivs = [ differentiate(firstDerivs[i], wrt=v) for i,v in enumerate(varList) ]
当然,假设你的表达式是二次的,符号微分和数值微分都会给你相同的答案。