Pyomo 中 TransformedPiecewiseLinearFunctionND 的正确用法是什么?

What is the correct usage of TransformedPiecewiseLinearFunctionND in Pyomo?

背景

我正在尝试在 Pyomo 中使用代理模型。给定一组标记为 x、y 和 z 的数据,我想将 z 写成 x 和 y 的廉价函数。

问题

Pyomo 具有用于多元分段线性函数的工具。参见 here。我设置了一个简单的示例,我的函数正在正确评估。但是似乎没有为 Z 添加任何约束。我希望模型值等于下面的插值。我猜我在设置 TransformedPiecewiseLinearFunctionND 时做了一些错误的事情,但我在文档中找不到任何示例。任何见解将不胜感激。

代码

from pyomo.core import ConcreteModel, Var, Constraint
import pyomo.environ as pe
from pyomo.core.kernel.piecewise_library.transforms_nd import (
    PiecewiseLinearFunctionND,
    TransformedPiecewiseLinearFunctionND
)
from pyomo.core.kernel.variable import (
    variable,
    variable_list
)
import pyomo.core.kernel.piecewise_library.util as util
import numpy as np
from scipy.spatial import Delaunay

npts = 100

vlist = variable_list([variable(lb=-1, ub=1),
                       variable(lb=-1, ub=1)])

tri = util.generate_delaunay(vlist, num=npts)
x, y = tri.points.T
z = np.cos(x) * np.sin(y)

model = ConcreteModel()
model.X = Var(initialize=0)
model.Y = Var(initialize=0)
model.Z = Var(initialize=999)

f = PiecewiseLinearFunctionND(tri, z)
model.g = TransformedPiecewiseLinearFunctionND(
    f=f,
    input=(model.X, model.Y),
    output=model.Z
)

def x_rule(model):
    return model.X == 0.5

def y_rule(model):
    return model.Y == 0.5

model.x_const = Constraint(rule=x_rule)
model.y_const = Constraint(rule=y_rule)

solver = pe.SolverFactory('ipopt')
solver.solve(model)

z_exact = np.cos(0.5) * np.sin(0.5)
z_interp = f([0.5, 0.5])

x_model = pe.value(model.X)
y_model = pe.value(model.Y)
z_model = pe.value(model.Z)

print(f'Z Exact: {z_exact}')
print(f'Z Interpolated: {z_interp}')
print(f'Model values (X, Y, Z): {x_model}, {y_model}, {z_model}')

输出

Z Exact: 0.42073549240394825
Z Interpolated: 0.42067082611089646
Model values (X, Y, Z): 0.5, 0.5, 999

我也试过手动为 Z 添加约束。这会产生错误:

def z_rule(model):
    return model.Z == f([model.X, model.Y])

model.z_const = Constraint(rule=z_rule)

您正在 pyomo.kernel 和 pyomo.environ 建模层之间混合建模组件。这不受支持(this 页面有更多信息)。

多维分段功能目前只能使用 pyomo.kernel 界面。可以在此处找到如何使用它的示例:

https://github.com/Pyomo/pyomo/blob/main/examples/kernel/piecewise_nd_functions.py