对 Python 中导数有约束的多项式的最小二乘近似
Least square approximation of a polynomial with a constraint on the derivative in Python
我正在尝试通过多个点来拟合三次多项式。当不约束导数时,这可能是一个非常简单的问题。我找到了一些 promising solutions using CVXPY to combine least squares with constraints but so far I'm not even able to solve the least-squares problem with CVXPY. I also posted this first on Computational Science 但考虑到更多关于代码 Stack Overflow 的事实可能更合适。代码如下。
import cvxpy as cp
import numpy as np
# Problem data
x = np.array([100, 200, 300, 400, 500])
y = 2160 - 1.678571429 * x + 0.006785714 * x * x + 5.52692E-20 * x * x * x
print(x)
print(y)
# Constructing the problem
a = cp.Variable(1)
b = cp.Variable(1)
c = cp.Variable(1)
d = cp.Variable(1)
objective = cp.Minimize(cp.sum_squares(a + b * x + c * x * x + d * x * x * x - y))
prob = cp.Problem(objective)
# The optimal objective value is returned by `prob.solve()`.
result = prob.solve(solver=cp.SCS, eps=1e-5)
# The optimal value for x is stored in `x.value`.
print("a: ", a.value)
print("b: ", b.value)
print("c: ", c.value)
print("d: ", d.value)
print(a.value + b.value * x + c.value * x * x + d.value * x * x * x)
这一切的结果是a = 831.67009518; b = 1.17905623; c = 0.00155167 和 d = 2.2071452e-06。这给出了 y_est = [967.29960654 1147.20547453 1384.63057033 1692.81776513 2085.00993011] 的平庸结果。鉴于应该可以得到完美的解决方案,提供的解决方案并不是很令我满意。
一旦成功,我应该能够按如下方式添加约束。
# add constraint for derivative = 0 in x = 500
constraints = [b + 2 * c * 500 + 3 * d * 500 * 500 == 0]
prob = cp.Problem(objective, constraints)
我不受 CVXPY 的约束,因此也欢迎使用其他解决方案。
您似乎只是对关联有疑问,以及 numpy 和 cvxpy 在 *
的含义上有何不同。例如,c * x * x
与 x * x * c
不同。前者当然是 (c * x) * x
,第二个 *
是点积,因此表达式是标量。后者 (x * x) * c
是您想要的,因为它首先进行逐元素乘法。这样做之后你会得到一个更明智的解决方案:)
a: [2159.91670117]
b: [-1.67850696]
c: [0.00678545]
d: [-1.13389519e-12]
[2059.92053699 2095.63343178 2267.05537873 2574.18637106 3017.02640194]
我正在尝试通过多个点来拟合三次多项式。当不约束导数时,这可能是一个非常简单的问题。我找到了一些 promising solutions using CVXPY to combine least squares with constraints but so far I'm not even able to solve the least-squares problem with CVXPY. I also posted this first on Computational Science 但考虑到更多关于代码 Stack Overflow 的事实可能更合适。代码如下。
import cvxpy as cp
import numpy as np
# Problem data
x = np.array([100, 200, 300, 400, 500])
y = 2160 - 1.678571429 * x + 0.006785714 * x * x + 5.52692E-20 * x * x * x
print(x)
print(y)
# Constructing the problem
a = cp.Variable(1)
b = cp.Variable(1)
c = cp.Variable(1)
d = cp.Variable(1)
objective = cp.Minimize(cp.sum_squares(a + b * x + c * x * x + d * x * x * x - y))
prob = cp.Problem(objective)
# The optimal objective value is returned by `prob.solve()`.
result = prob.solve(solver=cp.SCS, eps=1e-5)
# The optimal value for x is stored in `x.value`.
print("a: ", a.value)
print("b: ", b.value)
print("c: ", c.value)
print("d: ", d.value)
print(a.value + b.value * x + c.value * x * x + d.value * x * x * x)
这一切的结果是a = 831.67009518; b = 1.17905623; c = 0.00155167 和 d = 2.2071452e-06。这给出了 y_est = [967.29960654 1147.20547453 1384.63057033 1692.81776513 2085.00993011] 的平庸结果。鉴于应该可以得到完美的解决方案,提供的解决方案并不是很令我满意。
一旦成功,我应该能够按如下方式添加约束。
# add constraint for derivative = 0 in x = 500
constraints = [b + 2 * c * 500 + 3 * d * 500 * 500 == 0]
prob = cp.Problem(objective, constraints)
我不受 CVXPY 的约束,因此也欢迎使用其他解决方案。
您似乎只是对关联有疑问,以及 numpy 和 cvxpy 在 *
的含义上有何不同。例如,c * x * x
与 x * x * c
不同。前者当然是 (c * x) * x
,第二个 *
是点积,因此表达式是标量。后者 (x * x) * c
是您想要的,因为它首先进行逐元素乘法。这样做之后你会得到一个更明智的解决方案:)
a: [2159.91670117]
b: [-1.67850696]
c: [0.00678545]
d: [-1.13389519e-12]
[2059.92053699 2095.63343178 2267.05537873 2574.18637106 3017.02640194]