如何解决当导数的值受到约束时如何拟合多项式?
在多项式函数 f(x)
的导数的最大值存在约束的情况下,对于 x
的特定范围的值,是否有一种简单的方法可以得到解决方案?
对 this question 的回答是,curve_fit
中的 scipy.optimize
可以处理对各个系数的约束,如下例所示:
def func(x,a,b,c,d):
return a + b * x + c * x ** 2 + d * x ** 3
x = np.array([0.0,1.0,2.0,3.0,4.0,5.0])
y = np.array([0.0,0.8,0.9,0.1,-0.8,-1.0])
popt_cons,_ = curve_fit(func,x,y,bounds=([-np.inf,2,-np.inf,-np.inf],[np.inf,2.001,np.inf,np.inf]))
print(popt_cons)
>>> [-0.14331349 2. -0.95913556 0.10494372]
但是,如果我想要最佳拟合多项式,例如对特定范围的 x
值限制加速度(二阶导数)的最大值,该怎么办?
这意味着,通过对函数进行两次积分,2*c + 6*d*x
的值存在约束,例如,x
到 0
之间的 10
。
有没有办法做到这一点,还是我必须从头开始构建?
解决方法
curve_fit
方法不支持附加约束。但是,您可以实现非线性最小二乘问题
min ||f(x,coeffs) - y||^2
s.t. lb <= coeffs <= ub
f''(x,coeffs) <= max_val for all x_lb <= x <= x_ub
附加约束并用minimize
解决它。以下是如何通过 np.polyval
和 np.polyder
完成的示例:
import numpy as np
from scipy.optimize import minimize
x = np.array([0.0,1.0,2.0,3.0,4.0,5.0])
y = np.array([0.0,0.8,0.9,0.1,-0.8,-1.0])
def objective(coeffs):
return np.linalg.norm(np.polyval(coeffs,x) - y)
def constraint(coeffs,deriv_order,x_lb,x_ub,max_val):
deriv_coeffs = np.polyder(coeffs,deriv_order)
# Evaluate the derivative for all x_lb <= x <= x_ub
deriv_value = np.polyval(deriv_coeffs,x[(x >= x_lb) & (x <= x_ub)])
return -1.0*deriv_value + max_val
# Each inequality constraint has the form fun(x) >= 0
cons = [{'type': 'ineq','fun': lambda coeffs: constraint(coeffs,2,0.0,20)}]
bnds = [(-np.inf,np.inf),(2,5.001),(-np.inf,np.inf)]
poly_degree = 3
res = minimize(objective,x0=2.0*np.ones(poly_degree+1),bounds=bnds,constraints=cons)
请注意,每个不等式约束都具有 fun(x) >= 0
形式,即我们有 -f''(x,coeffs) + max_val >= 0
并且我们使用 x_lb = 0.0
、x_ub = 3.0
和 max_val = 20
作为二阶导数。最后,res.x
包含多项式系数。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。