簡體   English   中英

符號矩陣和numpy使用錯誤“ TypeError:輸入類型不支持ufunc'isfinite'。”

[英]Symbolic matrix and numpy usage error “TypeError: ufunc 'isfinite' not supported for the input types..”

我試圖使用最小化功能執行scipy.opimization。 我正在尋找所有像Iz,Iy,J,kz,ky,Yc,Yg這樣的變量,以使向量K_P_X和f之間的誤差最小。 也就是說, objective function K_P_X-f應該最小。 我認為我的錯誤與涉及numpy.linalg.norm(sol-f)的計算有關,其中sol被分配了符號向量(K_P_X)。 由於數據類型沖突,我收到此錯誤。 如果是這樣,請問Q1。 任何人都可以提出一種更好的方法來表示等式約束方程式(即constr1()),從而避免出現此錯誤。 完整的代碼如下

import scipy.optimize as optimize
from sympy import symbols,zeros,Matrix,Transpose
import numpy


#Symobolic K matrix
Zc,Yc,Zg,Yg=symbols("Zc Yc Zg Yg",real=True)
A,Iz,Iy,J,kz,ky,E,G,L=symbols("A Iz Iy J kz ky E G L",real=True,positive=True)
E=10400000;G=3909800;L=5

def phi_z():
    phi_z=(12*E*Iy)/(kz*A*G*L**2)
    return phi_z
def phi_y():
    phi_y=(12*E*Iz)/(ky*A*G*L**2)
    return phi_y

K_P=zeros(12,12)
K1=Matrix(([E*A/L,0,0],[0,(12*E*Iz)/((1+phi_y())*L**3),0],[0,0,(12*E*Iy)/((1+phi_z())*L**3)]))
K2=Matrix(([G*J/L,0,0],[0,E*Iy/L,0],[0,0,E*Iz/L]))
Q1=Matrix(([0,Zg,-Yg],[-Zc,0,L/2],[Yc,-L/2,0]))
Q1_T=Transpose(Q1)
Q2=Matrix(([0,Zg,-Yg],[-Zc,0,-L/2],[Yc,L/2,0]))
Q2_T=Transpose(Q2)
K11=K1; K12=K1*Q1; K13=-K1; K14=-K1*Q2; K22=Q1_T*K1*Q1+K2; K23=-Q1_T*K1; K24=-Q1_T*K1*Q2-K2; K33=K1; K34=K1*Q2; K44=Q2_T*K1*Q2+K2

K_P[0:3,0:3]=K11; K_P[0:3,3:6]=K12; K_P[0:3,6:9]=K13; K_P[0:3,9:12]=K14; K_P[3:6,3:6]=K22; K_P[3:6,6:9]=K23; K_P[3:6,9:12]=K24 ;K_P[6:9,6:9]=K33; K_P[6:9,9:12]=K34; K_P[9:12,9:12]=K44

##Converting Upper triangular stiffness matrix to Symmetric stiffness matrix##           
for i in range(0,12):           
    for j in range(0,12):
        K_P[j,i]=K_P[i,j]

K_P = K_P.subs({A: 7.55})
K_P = K_P.subs({Zc: 0})
K_P = K_P.subs({Zg: 0})

X= numpy.matrix([[1],[1],[1],[1],[1],[1],[1],[1],[1],[1],[1],[1]])
K_P_X=K_P*X
f= numpy.matrix([[-9346.76033789],[1595512.77906],[-1596283.83112],[274222.872543],[4234010.18889],[4255484.3549],[9346.76033789],[-1595512.77906],[1596283.83112],[-275173.513088],[3747408.91068],[3722085.0499]])
function=K_P_X-f

def Obj_func(variables):
    Iz,Iy,J,kz,ky,Yc,Yg=variables
    function=K_P_X-f #K_P_X matrix contains the variables like Iz,Iy,J,kz,ky,Yc,Yg.
    return function

def constr1(variables):
    sol = K_P_X     #Here the variables are in the symbolic vector K_P_X
    if numpy.allclose(sol, f):
        return 0.00 #If Error is equal to zero hence required accuracy is reached. So stop optimization
    else:
        return numpy.linalg.norm(sol-f)

initial_guess=[10,10,10,0.1,0.1,0.001,0.001]
cons = ({'type':'eq', 'fun': constr1},{'type': 'ineq', 'fun': lambda variables: -variables[3]+1},{'type': 'ineq', 'fun': lambda variables: variables[3]-0.001},{'type': 'ineq', 'fun': lambda variables: -variables[4]+1},{'type': 'ineq', 'fun': lambda variables: variables[4]-0.001},{'type': 'ineq', 'fun': lambda variables: -variables[5]+0.5},{'type': 'ineq', 'fun': lambda variables: variables[5]-0},{'type': 'ineq', 'fun': lambda variables: -variables[6]+0.5},{'type': 'ineq', 'fun': lambda variables: variables[6]-0})
bnds = ((1, 60), (1, 60),(1, 60),(0.1, 1),(0.1, 1),(0.001, 0.5),(0.001, 0.5))
res=optimize.minimize(Obj_func,initial_guess, bounds=bnds,constraints=cons)

我會在這里列出一些錯誤的地方。

  • 正如hpaulj所說,您不能直接將SymPy對象傳遞給SciPy或NumPy。 但是您可以進行lambdify ,然后在最小化例程中使用它
  • 您的最小化設置沒有意義。 最小化一個函數的約束是該函數必須為零...這不是約束最小化的含義。 約束與目標有所不同。
  • 最好在這里使用least_squares ,它專門用於最小化差異的范數(某些矢量函數-目標矢量)。

考慮到這一點,下面是修改后的腳本:

import scipy.optimize as optimize
from sympy import symbols, Matrix, lambdify
import numpy

Iz,Iy,J,kz,ky,Yc,Yg = symbols("Iz Iy J kz ky Yc Yg",real=True,positive=True)
K_P_X = Matrix([[37.7776503296448*Yg + 8.23411191827681],[-340.454138522391*Iz/(21.1513673253807*Iz/ky + 125)],[-9.4135635827062*Iy*Yc/(21.1513673253807*Iy/kz + 125) - 368.454956983948*Iy/(21.1513673253807*Iy/kz + 125)],[-9.4135635827062*Iy*Yc**2/(21.1513673253807*Iy/kz + 125) - 368.454956983948*Iy*Yc/(21.1513673253807*Iy/kz + 125) - 0.0589826136148473*J],[23.5339089567655*Iy*Yc/(21.1513673253807*Iy/kz + 125) + 2.62756822555969*Iy + 921.137392459871*Iy/(21.1513673253807*Iy/kz + 125)],[-5.00660515891599*Iz - 851.135346305977*Iz/(21.1513673253807*Iz/ky + 125) - 37.7776503296448*Yg**2 - 8.23411191827681*Yg],[-37.7776503296448*Yg - 8.23411191827681],[340.454138522391*Iz/(21.1513673253807*Iz/ky + 125)],[9.4135635827062*Iy*Yc/(21.1513673253807*Iy/kz + 125) + 368.454956983948*Iy/(21.1513673253807*Iy/kz + 125)],[9.4135635827062*Iy*Yc**2/(21.1513673253807*Iy/kz + 125) + 368.454956983948*Iy*Yc/(21.1513673253807*Iy/kz + 125) + 0.0589826136148473*J],[23.5339089567655*Iy*Yc/(21.1513673253807*Iy/kz + 125) - 2.62756822555969*Iy + 921.137392459871*Iy/(21.1513673253807*Iy/kz + 125)],[5.00660515891599*Iz - 851.135346305977*Iz/(21.1513673253807*Iz/ky + 125) + 37.7776503296448*Yg**2 + 8.23411191827681*Yg]])
f = Matrix([[-1],[-1],[-1],[-1.00059553353],[3.99999996539],[-5.99940443072],[1],[1],[1],[1],[1],[1]])
obj = lambdify([Iz,Iy,J,kz,ky,Yc,Yg], tuple(K_P_X - f))
initial_guess=[10,10,10,0.1,0.1,0.001,0.001]
bnds = ((1, 60), (1, 60),(1, 60),(0.1, 1),(0.1, 1),(0.001, 0.5),(0.001, 0.5))
lower = [a for (a, b) in bnds]
upper = [b for (a, b) in bnds]
res = optimize.least_squares(lambda x: obj(x[0], x[1], x[2], x[3], x[4], x[5], x[6]), initial_guess, bounds=(lower, upper))
print(res)

變化:

  • lambdify之前,我們應該有一個SymPy表達式。 因此, K_P_Xf現在都是SymPy矩陣。
  • Lambdified函數采用7個標量參數,並返回K_P_X - f的元組K_P_X - f
  • 邊界被分為上下兩部分,如least_squares的語法要求
  • 我們無法將obj直接傳遞給least_squares ,因為它將接收一個數組參數而不是7個標量。 因此,用於解壓縮向量的附加lambda步驟。

信不信由你,最小化的工作。 它返回最小點res.x作為

  [  1.00000000e+00,   1.00000000e+00,   1.69406332e+01,
     1.00000000e-01,   1.00000000e-01,   1.00000000e-03,
     1.00000000e-03]

一開始看起來很可疑,但這僅僅是因為該點碰到了您放置的邊界(10、1、0.1等)。 只有第三個變量以無效約束結束。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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