У меня есть функция, которая принимает аргумент y_0
, который может быть списком или массивом, или может быть просто с плавающей точкой. Я хотел, чтобы это работало в случае, когда y_0
было одним числом с плавающей запятой, поэтому я попытался использовать np.asarray(y_0)
в приведенном ниже коде, чтобы, если был только один элемент, цикл продолжал работать. Однако я получил ошибку TypeError: iteration over a 0-d array
. Я мог бы использовать оператор if, чтобы проверить, является ли он одиночным или нет, и предпринять соответствующие действия. Тем не менее, мне было любопытно, есть ли способ заставить его перебирать один объект?
def vf_grapher(fn, t_0, t_n, dt, y_0, lintype='-r', sup_title=None,
title=None, xlab=None, ylab=None):
t = np.arange(t_0, t_n, dt)
y_min = .0
y_max = .0
fig, axs = plt.subplots()
fig.suptitle(sup_title)
axs.set_title(title)
axs.set_ylabel(ylab)
axs.set_xlabel(xlab)
for iv in np.asarray(y_0):
soln = rk4(dt, t, fn, iv)
plt.plot(t, soln, lintype)
if y_min > np.min(soln):
y_min = np.min(soln)
if y_max < np.max(soln):
y_max = np.max(soln)
Для минимального рабочего примера включите следующую функцию:
def rk4(dt, t, field, y_0):
"""
:param dt: float - the timestep
:param t: array - the time mesh
:param field: method - the vector field y' = f(t, y)
:param y_0: array - contains initial conditions
:return: ndarray - solution
"""
# Initialize solution matrix. Each row is the solution to the system
# for a given time step. Each column is the full solution for a single
# equation.
y = np.asarray(len(t) * [y_0])
for i in np.arange(len(t) - 1):
k1 = dt * field(t[i], y[i])
k2 = dt * field(t[i] + 0.5 * dt, y[i] + 0.5 * k1)
k3 = dt * field(t[i] + 0.5 * dt, y[i] + 0.5 * k2)
k4 = dt * field(t[i] + dt, y[i] + k3)
y[i + 1] = y[i] + (k1 + 2 * k2 + 2 * k3 + k4) / 6
return y
if __name__ == '__main__':
def f(t, x): return x**2 - x
vf_grapher(f, 0, 4, 0.1, (-0.9, 0.5, 1.01), xlab='t', ylab='x(t)',
sup_title=r'Solution Field for $\dot{x} = x^2 - x$')