简体   繁体   English

结合 Sympy 与 scipy.optimize.least_squares

[英]Combining Sympy with scipy.optimize.least_squares

I'm trying to calculate the value of the variables D and theta for which the function E attains its minimum value.我正在尝试计算 function E 达到其最小值的变量Dtheta的值。

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)) . 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))

Here, (x1,y1), (x2,y2), (x3,y3) are known.这里,(x1,y1), (x2,y2), (x3,y3) 是已知的。 Now I calculate the partial derivatives of E wrt to D and theta and set them to zero.现在我计算 E wrt 对 D 和 theta 的偏导数并将它们设置为零。 Now I have 2 equations and 2 unknowns, so theoretically this system should be exactly solvable.现在我有 2 个方程和 2 个未知数,所以理论上这个系统应该是完全可解的。 The only issue here is that this is highly non-linear.这里唯一的问题是这是高度非线性的。 So analytical solutions are out of the question.所以分析解决方案是不可能的。 I'm using Sympy here to calculate the partial derivatives and generate the equations to be used in least_squares from scipy.optimize.我在这里使用 Sympy 来计算偏导数并从 scipy.optimize 生成要在最小二乘法中使用的方程。 I do get a solution for D and theta but it doesn't make any physical sense.我确实得到了 D 和 theta 的解决方案,但它没有任何物理意义。 Furthermore, the cost value of least_squares is ~17, so my solutions are not very reliable, right?此外,least_squares 的成本值约为 17,所以我的解决方案不是很可靠,对吧? Could someone help me out here?有人可以帮我吗? Here's the code:这是代码:

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

I should also mention that calculating D and theta is part of a problem that involves fitting a line through (x1,y1), (x2,y2), (x3,y3), and (13,2).我还应该提到,计算Dtheta是涉及拟合通过 (x1,y1)、(x2,y2)、(x3,y3) 和 (13,2) 的线的问题的一部分。 D is the distance between (13,2) and the first point closest to (x1,y1) on the fitted line, 2D is similarly the distance between (13,2) and the second point closest to (x2,y2), and so on. D 是拟合线上 (13,2) 和最接近 (x1,y1) 的第一个点之间的距离,2D 是类似地是 (13,2) 和最接近 (x2,y2) 的第二个点之间的距离,以及很快。 This analysis has to be done over all the gridpoints on a lat-lon grid of size (21,69).必须对大小为 (21,69) 的经纬网格上的所有网格点进行此分析。 All alternate suggestions to solve this problem are also welcome.也欢迎所有解决此问题的替代建议。 Thanks in advance!提前致谢!

You are looking to approximate the sequence 9, 22, 24 with an equidistant sequence like 11,18,25 .您正在寻找使用等距序列(如11,18,25 9, 22, 24 This does not have a good fit, so a large residual value is reasonable.这没有很好的拟合,因此较大的残值是合理的。

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  

On a second glance, you try to minimize the sum of norms, that is, the sum of distances from points on a line parallel to the x axis to points equidistant on a line through the origin.再看一眼,您试图最小化范数之和,即从平行于x轴的线上的点到通过原点的线上等距的点的距离之和。 You can do that without doing any least-squares gradient optimization (which is a strange idea anyway, why not just find the zero location of the gradient with fsolve ?)您可以在不进行任何最小二乘梯度优化的情况下做到这一点(无论如何这都是一个奇怪的想法,为什么不直接使用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()

with the results结果

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.

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