[英]Euler's method scheme python
編輯:函數為u [t] = [[0,1],[-6,5]] * u,初始條件為u(0)= [[1],[1]]。 確切的答案是u_t = [[1],[2]] * 2 * e **(2 * t)-[[1],[3]] * e **(3 * t)
我正在做一個項目,卻對為什么不起作用感到迷惑。 我打算在以下代碼上運行Euler方法方案。
import numpy as np
from matplotlib import pyplot as plt
def Eulm():
x0=0
y0=1
z0=1
n=21
xf=2
y0=1
z0=1
w0=y0
q0=z0
w = [0] * (n+1)
q = [0] * (n+1)
w[0]=w0
q[0]=q0
x=np.linspace(x0,xf,n)
y=2*np.e**(2*x)-np.e**(3*x)
z=4*np.e**(2*x)-3*np.e**(3*x)
L=[0]
for i in range (1,n):
deltax=(xf-x0)/(n-1)
y0=y[0]
z0=z[0]
A=np.matrix([[1, -deltax], [6*deltax, 1-5*deltax]])
G=np.linalg.inv(A)
print(G)
b=np.matrix([y[i-1], z[i-1]])
b=b.transpose
w[i]=G[0][0]*w[0][i]+G[0][1]*q[0][i-1]
q[i]=G[1][0]*w[0][i-1]+G[1][1]*q[0][i-1]
plt.plot(x,y)
plt.xlabel('Time')
plt.ylabel('Numerical Solutions')
plt.title('Numerical Solutions with respect to Time')
plt.show()
我遇到了以下錯誤,並且由於應該在列表中進行迭代,因此我不確定為什么會出現此錯誤。
TypeError Traceback (most recent call last)
<ipython-input-49-da43a543ec92> in <module>()
----> 1 Eulm()
<ipython-input-47-022f3e9099b9> in Eulm()
29 b=np.matrix([y[i-1], z[i-1]])
30 b=b.transpose
---> 31 w[i]=G[0][0]*w[0][i]+G[0][1]*q[0][i-1]
32 q[i]=G[1][0]*w[0][i-1]+G[1][1]*q[0][i-1]
33 plt.plot(x,y)
TypeError: 'int' object is not subscriptable
任何幫助將不勝感激。 謝謝!
您的Euler方法的代碼/理論實現存在大量問題。 這是eulm
的簡單版本,可完成預期的工作:
import numpy as np
from matplotlib import pyplot as plt
def eulm(n=2001):
x0=0
y0=1
z0=1
xf=2
wq = np.zeros((n, 2))
wq[0] = y0,z0
x = np.linspace(x0,xf,n)
y = 2*np.exp(2*x) - np.exp(3*x)
z = 4*np.exp(2*x) - 3*np.exp(3*x)
A = np.array([[0, 1], [-6, 5]])
dx = (x[1] - x[0])
fig = plt.figure(figsize=(10,6))
ax = fig.gca()
ax.set_xlabel('Time')
ax.set_ylabel('Numerical Solutions')
ax.set_title('All Numerical Solutions with respect to Time,\n%d timesteps' % n)
for i in range (1,n):
wq[i] = wq[i - 1] + dx*(A @ wq[i - 1])
if i == n-1:
# add a legend in the final display
ax.plot(x, wq[:, 0], c='C0', label='approx y')
ax.plot(x, wq[:, 1], c='C1', label='approx z')
ax.legend()
fig.show()
else:
ax.plot(x, wq[:, 0], c='C0')
ax.plot(x, wq[:, 1], c='C1')
fig.show()
fig = plt.figure(figsize=(10,6))
ax = fig.gca()
ax.set_xlabel('Time')
ax.set_ylabel('Numerical Solutions')
ax.set_title('Final Numerical Solutions with respect to Time,\n%d timesteps' % n)
ax.plot(x, wq[:, 0], ':', c='k', lw=3, zorder=99, label='approx y')
ax.plot(x, y, c='C2', lw=15, label='exact y')
ax.plot(x, wq[:, 1], '--', c='k', lw=3, zorder=99, label='approx z')
ax.plot(x, z, c='C3', lw=15, label='exact z')
ax.legend()
fig.show()
return wq, x, y, z
我將w
和q
滾動成一個單獨的兩列數組wq
。 我擺脫了逆矩陣G
(我無法弄清楚您要如何處理它,無論如何它都不是標准Euler方法的一部分)。 我使用了來自Numpy的一些矩陣表示法簡化了下一步驟的wq
值的wq
( @
運算符最近添加到了Numpy中,並用作矩陣乘法運算符)。
對於足夠大的n
(以及足夠小的時間步長dx
), wq[:, 0]
和wq[:, 1]
的估計值收斂到y
和z
的精確值,並且誤差很小(大約~1%
當n=2001
)。 這是運行eulm()
產生的圖,如下所示:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.