简体   繁体   English

在Python中导数受约束的多项式的最小二乘逼近

[英]Least square approximation of a polynomial with a constraint on the derivative in Python

I'm trying to fit a polynomial of the third degree through a number of points. 我正在尝试通过多个点来拟合三次多项式。 This could be a very simple problem when not constraining the derivative. 当不限制导数时,这可能是一个非常简单的问题。 I found some 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. 我发现了一些有前途的解决方案,可以使用CVXPY结合约束的最小二乘法,但是到目前为止,我什至无法解决CVXPY的最小二乘问题。 I also posted this first on Computational Science but given the fact that it is more about the code Stack Overflow might be more appropriate. 我也首先在计算科学杂志上发表了这篇文章,但是考虑到它更多地与代码有关,Stack Overflow可能更合适。 The code is below. 代码如下。

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)

The result of all this is a = 831.67009518; 所有这些的结果是= 831.67009518; b = 1.17905623; b = 1.17905623; c = 0.00155167 and d = 2.2071452e-06. c = 0.00155167,d = 2.2071452e-06。 This gives the mediocre result of y_est = [967.29960654 1147.20547453 1384.63057033 1692.81776513 2085.00993011]. 这给出y_est = [967.29960654 1147.20547453 1384.63057033 1692.81776513 2085.00993011]的中等结果。 Given that it should be able to yield a perfect solution, the provided solution is not really satisfying to me. 鉴于它应该能够提供一个完美的解决方案,因此所提供的解决方案对我来说并不真正令人满意。

Once this works, I should be able to add the constraints as follows. 一旦成功,我应该能够如下添加约束。

# add constraint for derivative = 0 in x = 500
constraints = [b + 2 * c * 500 + 3 * d * 500 * 500 == 0]
prob = cp.Problem(objective, constraints)

I'm not bound to CVXPY, so alternative solutions are also welcome. 我不限于CVXPY,因此也欢迎使用其他解决方案。

It seems you just have a problem with association and how numpy and cvxpy differ in what * means. 似乎您在关联方面以及numpy和cvxpy在*含义上有什么不同。 For example, c * x * x is not the same as x * x * c . 例如, c * x * xx * x * c The former is of course (c * x) * x and the second * is a dot product and thus the expression is a scalar. 前者当然是(c * x) * x ,第二个*是点积,因此表达式是一个标量。 The latter (x * x) * c is what you want, as it first does an element-wise multiply. 后者(x * x) * c是您想要的,因为它首先进行逐元素乘法。 After doing that you get a much more sensible solution :) 这样做之后,您将获得更明智的解决方案:)

a:  [2159.91670117]
b:  [-1.67850696]
c:  [0.00678545]
d:  [-1.13389519e-12]
[2059.92053699 2095.63343178 2267.05537873 2574.18637106 3017.02640194]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM