我正在尝试使用scipy.integrate中的ode求解器求解微分方程组。我的问题是,我正在获得奇异矩阵'当我的矩阵不应该是单数时出错。主要问题是当我试图在下面的代码中找到矩阵B的逆矩阵时。在下面的代码中,B是3x3矩阵,A是3x1矩阵,U也是3x1矩阵! 我该如何解决这个问题?
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint
import math
import parameter_projection as pp
from scipy.integrate import ode
import sympy as sm
c=10
k,k1,k2,k3=10,9,8,7
eta=2.5
gamma,gamma1,gamma2=2,3,10
a=[]
for i in range(30):
a.append(i)
a=np.array(a)
def aero(t,Y):
V,alpha,beta,p,q,r,phi,theta=Y[0],Y[1],Y[2],Y[3],Y[4],Y[5],Y[6],Y[7]
sg=np.cos(alpha)*np.cos(beta)*np.sin(theta)-np.sin(beta)*np.sin(phi)*np.cos(theta)-np.sin(alpha)*np.cos(beta)*np.cos(phi)*np.cos(theta)
smcg=np.cos(alpha)*np.sin(beta)*np.sin(theta)+np.cos(beta)*np.sin(phi)*np.cos(theta)-np.sin(alpha)*np.sin(beta)*np.cos(phi)*np.cos(theta)
cmcg=np.sin(theta)*np.sin(alpha)+np.cos(alpha)*np.cos(phi)*np.cos(theta)
#error
ev=V-np.sin(t)
ebeta=beta-np.sin(t)
etheta=theta-np.sin(t)
ethetad=q*np.cos(phi)-r*np.sin(phi)-np.cos(t)
sv,sbeta,stheta=ev,ebeta,etheta+ethetad
s=np.array([[sv],[sbeta],[stheta]])
A=np.array([[-a[1]*V**2*np.sin(beta)-a[2]*V**2*np.sin(beta)-a[4]*np.sin(gamma)-np.cos(t)],[p*np.sin(alpha)-r*np.cos(alpha)+a[16]*V+a[15]*smcg-np.cos(t)],[ethetad+np.cos(phi)*a[10]*p*r+np.cos(phi)*a[6]*(r**2-p**2)+np.cos(phi)*a[20]*V**2-np.cos(phi)*a[21]*sg+-q*np.sin(phi)*p-q*np.sin(phi)*q*np.sin(phi)*np.tan(theta)-q*np.sin(phi)*r*np.cos(phi)*np.tan(theta)-np.sin(phi)*a[11]*p*q+a[12]*q*r-a[13]*V**2+r*np.cos(phi)*p+r*q*np.cos(phi)*np.sin(phi)*np.tan(theta)+(r*np.cos(phi))**2*np.tan(theta)-np.cos(t)]])
B=np.array([[a[0]*np.cos(alpha)*np.sin(beta),a[7]*np.sin(beta),a[0]*np.sin(alpha)*np.cos(beta)],[-a[9]*np.cos(alpha)*np.sin(beta)/V,a[22]*np.cos(beta)/V,-a[9]*np.sin(alpha)*np.sin(beta)/V],[a[29]*np.cos(phi),a[26]*np.sin(alpha)*np.sin(beta)*np.cos(phi)-a[27]*np.sin(phi)*np.cos(alpha),-a[25]*np.cos(phi)]])
C=np.linalg.inv(B)*A
U=(C-np.linalg.inv(B)*k*s-np.linalg.inv(B)*eta*np.tanh(s))
Vdot=a[0]*np.cos(alpha)*np.sin(beta)*U[0]-a[1]*V**2*np.cos(beta)-a[2]*V**2*np.sin(beta)-a[3]*sg+a[7]*np.sin(beta)*U[1]+a[0]*np.sin(alpha)*np.cos(beta)*U[2]
alphadot=q-(p*np.cos(alpha)+r*np.sin(alpha))*np.sin(beta)/np.cos(beta)+a[4]*V-a[14]*cmcg-a[8]*np.sin(alpha)*U[0]/V+a[8]*np.cos(alpha)*U[2]/V
betadot=p*np.sin(alpha)-r*np.cos(alpha)+a[16]*V+a[17]*smcg-a[9]*np.cos(alpha)*np.sin(beta)*U[0]/V+a[22]*np.cos(beta)*U[1]/V-a[9]*np.sin(alpha)*np.sin(beta)*U[2]/V
pdot=a[5]*q*r+a[17]*p*q+a[18]*V**2-a[19]*smcg+a[23]*U[0]-a[28]*U[2]+a[24]*np.sin(alpha)*np.cos(beta)*U[1]
qdot=a[10]*p*r+a[6]*(r**2-p**2)+a[20]*V**2-a[21]*sg+a[29]*U[0]-a[25]*U[2]+a[26]*np.sin(alpha)*np.sin(beta)*U[1]
rdot=a[11]*p*q-a[12]*q*r+a[13]*V**2+a[27]*np.cos(alpha)*U[2]
phidot=p+q*np.sin(phi)*np.tan(theta)+r*np.cos(phi)*np.tan(theta)
thetadot=q*np.cos(phi)-r*np.sin(phi)
return[Vdot,alphadot,betadot,pdot,qdot,rdot,phidot,thetadot]
y0=[0.01,0.2,0,0,0,0,0,0.1]
t0=0
V=[]
alpha=[]
beta=[]
p=[]
q=[]
r=[]
phi=[]
theta=[]
t=[]
r=ode(aero).set_integrator('dopri5',method='bdf',nsteps=1e10)
r.set_initial_value(y0,t0)
t1=10
dt=.01
while r.successful() and r.t<t1:
r.integrate(r.t+dt)
V.append(r.y[0])
alpha.append(r.y[1])
beta.append(r.y[2])
p.append(r.y[3])
q.append(r.y[4])
r.append(r.y[5])
phi.append(r.y[6])
theta.append(r.y[7])
t.append(r.t)
V=np.array(V)
alpha=np.array(alpha)
beta=np.array(beta)
p=np.array(p)
q=np.array(q)
r=np.array(r)
phi=np.array(phi)
theta=np.array(theta)
plt.plot(t,V)
plt.show()
答案 0 :(得分:0)
对于beta=phi=0
的初始值以及设置a[0]=0
¸时的a[k]=k
,您的矩阵B
在第一步中会有第一行零。这是一个奇异的矩阵。
将测试数据更改为a[i]=i+1
会删除此错误,但会立即显示新错误
rv_cb_arr is NULL
Call-back cb_fcn_in___user__routines failed.
Traceback (most recent call last):
File "odeint-LA-singular_so45165407.py", line 60, in <module>
r.integrate(r.t+dt)
这可能是因为您的所有dot
变量仍然是数组,因此返回的衍生矢量是每个大小为3的np.array
列表。
这里的第一个猜测是你错误地认为*
是矩阵产品。这仅适用于将对象构造为np.matrix
的情况。使用np.array
使用dot
表示矩阵矢量产品,使用np.linalg.solve
代替带反转的产品。
事实确实如此,请改用以下几行
C = np.linalg.solve(B,A)
U = C-np.linalg.solve(B,k*s - eta*np.tanh(s))
之后,您会发现对组件数组和ODE求解器都使用变量名r
。修复你仍然认为步长变得太小。
(添加jul / 19)根据评论使用变体
U = -C-np.linalg.solve(B,k*s - eta*np.tanh(s))
我将集成循环更改为
t0=0.
y0=[0.01,0.2,0.,0.,0.,0.,0.,0.1]
names = [ "V", "alpha", "beta", "p", "q", "r", "phi", "theta" ]
sol = [ [yy] for yy in y0 ]
t=[t0]
solver=ode(aero).set_integrator('dopri5',nsteps=1e3)
solver.set_initial_value(y0,t0)
t1=3
dt=5e-3
for t1 in range(1,11):
if not solver.successful(): break;
while solver.successful() and solver.t<t1:
solver.integrate(solver.t+dt)
for k in range(8): sol[k].append(solver.y[k]);
t.append(solver.t)
print "step"
print len(t)
for k in range(8):
plt.subplot(4,2,k+1)
plt.plot(t,sol[k])
plt.ylabel(names[k])
plt.show()
其中解决方案组件的自动处理可以产生更好的代码,只要t
传递一个整数值,就会产生一个图。最终的图表是
alpha
中的奇点出现在t=3.292894674
,alphadot
中的值非常不稳定,从-1.2e06
到+2.9e06
不等,1e-09
的大小不同$ export HTTP_PROXY="http://proxyIP:PORT"
$ export HTTPS_PROXY="http://proxyIP:PORT"
1}}及时。