[英]Combining Sympy with scipy.optimize.least_squares
我正在尝试计算 function E 达到其最小值的变量D和theta的值。
E = sqrt(x1-Dcos(theta)^2 + (y1-Dsin(theta)^2)) + sqrt(x2-2Dcos(theta)^2 + (y2-2Dsin(theta)^2)) + sqrt(x3-3Dcos(theta)^2 + (y3-3Dsin(theta)^2))
。
这里,(x1,y1), (x2,y2), (x3,y3) 是已知的。 现在我计算 E wrt 对 D 和 theta 的偏导数并将它们设置为零。 现在我有 2 个方程和 2 个未知数,所以理论上这个系统应该是完全可解的。 这里唯一的问题是这是高度非线性的。 所以分析解决方案是不可能的。 我在这里使用 Sympy 来计算偏导数并从 scipy.optimize 生成要在最小二乘法中使用的方程。 我确实得到了 D 和 theta 的解决方案,但它没有任何物理意义。 此外,least_squares 的成本值约为 17,所以我的解决方案不是很可靠,对吧? 有人可以帮我吗? 这是代码:
import sympy as sym
D, theta = sym.symbols("D, theta")
x1,x2,x3 = 9.0,22.0,24.0
y1,y2,y3 = 14.0,14.0,14.0
E = ((x1-D*sym.cos(theta))**2 + (y1-D*sym.sin(theta))**2)**0.5 + ((x2-2*D*sym.cos(theta))**2 + (y2-2*D*sym.sin(theta))**2)**0.5 + ((x3-3*D*sym.cos(theta))**2 + (y3-3*D*sym.sin(theta))**2)**0.5
gradient = sym.derive_by_array(E, (D, theta))
from scipy.optimize import least_squares as ls
grad = sym.lambdify((D, theta), gradient)
A = ls(lambda v: grad(v[0],v[1]), (8,0), bounds=([0, -22.5*np.pi/180], [12, 22.5*np.pi/180])) #theta should be between -22.5 degree and 22.5 degree and D should be between 0 and 12 but ideally not 0.
D2, theta2 = A.x # 0.04561884938833529 -0.3926990816987241
我还应该提到,计算D和theta是涉及拟合通过 (x1,y1)、(x2,y2)、(x3,y3) 和 (13,2) 的线的问题的一部分。 D 是拟合线上 (13,2) 和最接近 (x1,y1) 的第一个点之间的距离,2D 是类似地是 (13,2) 和最接近 (x2,y2) 的第二个点之间的距离,以及很快。 必须对大小为 (21,69) 的经纬网格上的所有网格点进行此分析。 也欢迎所有解决此问题的替代建议。 提前致谢!
您正在寻找使用等距序列(如11,18,25
9, 22, 24
。 这没有很好的拟合,因此较大的残值是合理的。
Doing the least square sum manually gives
(a-d-9)^2 + (a-22)^2 + (a+d-24)^2 = 3*a^2 +2*d^2 - 110*a - 30*d +const
so the optimum is at a = 55/3 = 18+1/3 and d = 15/2 = 7+1/2
再看一眼,您试图最小化范数之和,即从平行于x
轴的线上的点到通过原点的线上等距的点的距离之和。 您可以在不进行任何最小二乘梯度优化的情况下做到这一点(无论如何这都是一个奇怪的想法,为什么不直接使用fsolve
找到梯度的零位置?)
x = np.array([ 9.0,22.0,24.0])
y = np.array([14.0,14.0,14.0])
K = 1+np.arange(len(x))
target = lambda X,Y: sum(np.hypot(x-K*X, y-K*Y))
from scipy.optimize import fmin, minimize
#U = fmin(lambda u: target(*u), [4,4])
U = minimize(lambda u: target(*u), [4,4])
print(U)
X,Y = U.x
print(X,Y, np.hypot(X,Y), np.arctan2(Y,X))
K = np.arange(1+len(x))
plt.plot(x,y,'o', ms=8); plt.plot(K*X,K*Y, '-s', ms=4); plt.grid(); plt.show()
结果
fmin:
-----
Optimization terminated successfully.
Current function value: 16.987937
Iterations: 49
Function evaluations: 92
minimize:
---------
fun: 16.987921401556633
hess_inv: array([[2.72893764e-08, 6.01803467e-08],
[6.01803467e-08, 1.53257534e-07]])
jac: array([ 1.29665709, -0.08849001])
message: 'Desired error not necessarily achieved due to precision loss.'
nfev: 740
nit: 29
njev: 182
status: 2
success: False
x: array([8. , 4.66666667])
X: 8.000000, Y: 4.666667,
D: 9.261629, theta: 0.5280744
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.