簡體   English   中英

結合 Sympy 與 scipy.optimize.least_squares

[英]Combining Sympy with scipy.optimize.least_squares

我正在嘗試計算 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))

這里,(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

我還應該提到,計算Dtheta是涉及擬合通過 (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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM