我正在编写一个 python 代码,该代码实现了欧拉的方法来求解时间步长 h 的任意范围值的一阶 ODE。
我想到的最简单的解决方案是声明一个 Python 列表来存储“外部 for”循环末尾的结果:
y = []
for h in (0.05, 0.1, 0.2):
t = np.arange(0, 5 + h, h) ## Time-steps as np array
N = np.zeros(len(t)) ## Initialize number of U^{235} nuclei array.
N[0] = N_0
## Implementation of Euler's method, first-order case. One 'for' loop suffices.
for i in range(0, len(t) - 1):
N[i+1] = N[i] * (1.0 - h/tau)
y.append(t) ## Store results in python list. Each element is an array
## with the corresponding value of h
然后我尝试绘制存储在 y[0] 中的 h = 0.05 的结果作为 x 轴:
plt.scatter(y[0], N, marker='o', facecolors='none', s=60, lw=2)
但这会返回错误“ValueError:x 和 y 的大小必须相同”
我不明白为什么我会收到尺寸错误。 y[0] 不是一维列表吗?所以我不能使用列表作为绘图的轴?
我很困惑,因为它与变量 t 一起工作,因为它是一个 np.array:
t = np.arange(0, 5 + h, h) ## Time-steps as np array
N = np.zeros(len(t)) ## Initialize number of U^{235} nuclei array.
N[0] = N_0
## Implementation of Euler's method, first-order case. One 'for' loop suffices.
for i in range(0, len(t) - 1):
N[i+1] = N[i] * (1.0 - h/tau)
plt.scatter(t, N, marker='o', facecolors='none', s=60, lw=2)
您没有将各种
N
数组存储在列表中,因此您试图从第一次迭代(即t
)和最后一次迭代中绘制y[0]
。如果将所有内容都存储在字典中,则可以将时间和核数存储为值,将时间增量N
存储为键:
h
当你使用 numpy 时,出于性能原因你想避免循环(比如你有 1M 的时间增量)。我们可以把这个:
# Imports.
import matplotlib.pyplot as plt
import numpy as np
# Constants.
N_0 = 1000
TAU = 5
TIME_INCREMENTS = (0.05, 0.1, 0.2)
data = {}
for h in TIME_INCREMENTS :
t = np.arange(0, 5 + h, h) # Time-steps as np array.
N = np.zeros(len(t)) # Initialize number of U^{235} nuclei array.
N[0] = N_0
# Implementation of Euler's method, first-order case. One 'for' loop suffices.
for i in range(0, len(t) - 1):
N[i+1] = N[i] * (1.0 - h/TAU)
data[h] = (t, N)
fig, ax = plt.subplots()
for key, values in data.items():
ax.scatter(*values, marker='o', s=60, lw=2, label=f"h = {key:.2f}")
ax.legend()
进入这个:
N = np.zeros(len(t))
N[0] = N_0
for i in range(0, len(t) - 1):
N[i+1] = N[i] * (1.0 - h/TAU)