[英]Automatically reduce piecewise function components - Pyomo
In pyomo, I have a piece-wise linear constraint defined through pyomo.environ.Piecewise
. 在pyomo中,我有一个通过
pyomo.environ.Piecewise
定义的分段线性约束。 I keep getting a warning along the lines of 我不断收到以下警告
Piecewise component '<component name>' has detected slopes of consecutive piecewise segments to be within <tolerance> of one another. Refer to the Piecewise help documentation for information on how to disable this warning.
I know I could increase the tolerance and get rid of the warning, but I'm wondering if there is a general approach (through Pyomo or numpy) to reduce the number of "segments" if two consecutive slopes are below a given tolerance. 我知道我可以增加公差并摆脱警告,但是我想知道是否存在一种通用方法(通过Pyomo或numpy)来减少“分段”的数量(如果两个连续的斜率都低于给定的公差)。
I could obviously implement this myself, but I'd like to avoid reinventing the wheel. 我显然可以自己实现,但是我想避免重新发明轮子。
Ok, this is what I came up with. 好的,这就是我的想法。 Definitely not optimized for performance, but my case depends on few points.
绝对没有针对性能进行优化,但是我的情况取决于几点。 It also lacks more validations on the inputs (eg
x
being sorted and unique). 它还缺乏对输入的更多验证(例如,
x
被排序并且是唯一的)。
def reduce_piecewise(x, y, abs_tol):
"""
Remove unnecessary points from piece-wise curve.
Points are remove if the slopes of consecutive segments
differ by less than `abs_tol`.
x points must be sorted and unique.
Consecutive y points can be the same though!
Parameters
----------
x : List[float]
Points along x-axis.
y : List[float]
abs_tol : float
Tolerance between consecutive segments.
Returns
-------
(np.array, np.array)
x and y points - reduced.
"""
if not len(x) == len(y):
raise ValueError("x and y must have same shape")
x_reduced = [x[0]]
y_reduced = [y[0]]
for i in range(1, len(x) - 1):
left_slope = (y[i] - y_reduced[-1])/(x[i] - x_reduced[-1])
right_slope = (y[i+1] - y[i])/(x[i+1] - x[i])
if abs(right_slope - left_slope) > abs_tol:
x_reduced.append(x[i])
y_reduced.append(y[i])
x_reduced.append(x[-1])
y_reduced.append(y[-1])
return np.array(x_reduced), np.array(y_reduced)
And here are some examples: 以下是一些示例:
>>> x = np.array([0, 1, 2, 3])
>>> y = np.array([0, 1, 2, 3])
>>> reduce_piecewise(x, y, 0.01)
(array([0, 3]), array([0, 3]))
>>> x = np.array([0, 1, 2, 3, 4, 5])
>>> y = np.array([0, 2, -1, 3, 4.001, 5]) # 4.001 should be removed
>>> reduce_piecewise(x, y, 0.01)
(array([0, 1, 2, 3, 5]), array([ 0., 2., -1., 3., 5.]))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.