#python #numpy #scipy
#python #numpy #scipy
Вопрос:
Я попытался изучить, как работает spicy.integrate.ode. Приведенный ниже код является простым кодом для этого.
def func(t, z, p):
x = z[0]
y = z[1]
print('x :', x)
print('x.shape :', x.shape)
print('y :', y)
print('y.shape :', y.shape)
return [x*0, y*0]
t_ini = 0
t_fin = 1
x_ini = np.array([[2, 2]])
y_ini = np.array([[2, 2]])
solver = ode(func)
solver.set_integrator('dopri5')
solver.set_initial_value([x_ini, y_ini], t_ini)
solver.set_f_params([0])
solver.integrate(t_fin)
x_fin, y_fin = solver.y
print('x_fin :', x_fin)
print('y_fin :', y_fin)
Однако,
print('x :', x)
print('x.shape :', x.shape)
print('y :', y)
print('y.shape :', y.shape)
return [x*0, y*0]
не сработало. Результат кода был
x_fin : [[2. 2.]]
y_fin : [[2. 2.]]
.
Интересно, когда я изменил x_ini
и y_ini
в
x_ini = np.array([[2]])
y_ini = np.array([[2]])
print()
команда сработала, и результатом кода стало повторение
x : 2.0
x.shape : ()
y : 2.0
y.shape : ()
с двумя строками после повторения, которые
x_fin : [[2.]]
y_fin : [[2.]]
.
Было странно, что даже если я поставил x_ini
и y_ini
, имеющий (1, 1) форму, оба print(x.shape)
и print(y.shape)
показали () .
Итак, вопросы:
- Почему
print()
это не сработалоx_ini = y_ini = np.array([[2, 2]])
и что я должен сделать, чтобы заставить их работать? - Почему форма массивов numpy, которые являются
x
иy
стали () вместо (1, 1) . - Как сделать форму массивов numpy, которые являются x и y, равными (1, 1) во время интеграции с использованием scipy. Что мне делать, если форма обоих
x_ini
иy_ini
равна (2, 2), и я хочу сделать форму согласованной во время интеграции с использованием scipy.
Есть ли какие-нибудь ребята, которые знают об этом?
Ответ №1:
Я получаю предупреждение при использовании вашего массива начальных значений:
In [9]: x_ini = np.array([[2, 2]])
...: y_ini = np.array([[2, 2]])
In [10]: solver.set_initial_value([x_ini, y_ini], 0)
Out[10]: <scipy.integrate._ode.ode at 0x7f1ab8953d60>
In [11]: solver.integrate(.1)
/usr/local/lib/python3.8/dist-packages/scipy/integrate/_ode.py:1181: UserWarning: dopri5: input is not consistent
warnings.warn('{:s}: {:s}'.format(self.__class__.__name__,
Out[11]:
array([[[2., 2.]],
[[2., 2.]]])
Выходные данные такие же, как и входные
In [12]: np.array([x_ini, y_ini])
Out[12]:
array([[[2, 2]],
[[2, 2]]])
С помощью
x_ini = np.array([[2]])
y_ini = np.array([[2]])
Начальным значением является (2,1,1) массив
In [18]: np.array([x_ini, y_ini])
Out[18]:
array([[[2]],
[[2]]])
Это выполняется, но значения, передаваемые вашей функции, представляют собой массивы 0d
x : 2.0
x.shape : ()
y : 2.0
y.shape : ()
===
Давайте упростим func
:
In [20]: def func(t, z, p):
...: print(type(z), z.shape, z)
...: return z*0
...:
In [21]: solver = ode(func)
...: solver.set_integrator('dopri5')
Out[21]: <scipy.integrate._ode.ode at 0x7f1ab6debe50>
In [22]: solver.set_f_params([0])
Out[22]: <scipy.integrate._ode.ode at 0x7f1ab6debe50>
In [23]: solver.set_initial_value([1,2], 0)
Out[23]: <scipy.integrate._ode.ode at 0x7f1ab6debe50>
In [24]: solver.integrate(.1)
<class 'numpy.ndarray'> (2,) [1. 2.]
...
Если я изменю начальное значение на a (2,1,1), func
получит те же входные данные:
In [27]: solver.set_initial_value([[[1]],[[2]]], 0)
Out[27]: <scipy.integrate._ode.ode at 0x7f1ab6debe50>
In [28]: solver.integrate(.1)
<class 'numpy.ndarray'> (2,) [1. 2.]
Измените входные данные на массив из 3 элементов:
In [31]: solver.set_initial_value([1,2,3], 0)
Out[31]: <scipy.integrate._ode.ode at 0x7f1ab6debe50>
In [32]: solver.integrate(.1)
<class 'numpy.ndarray'> (3,) [1. 2. 3.]
Из документации:
f : callable ``f(t, y, *f_args)``
Right-hand side of the differential equation. t is a scalar,
``y.shape == (n,)``.
``f_args`` is set by calling ``set_f_params(*args)``.
`f` should return a scalar, array or list (not a tuple).
f
ВОЗВРАТ dy/dt
. Это y
будет одномерный массив, и он должен возвращать массив аналогичного размера. Обратите внимание на y.shape
требование.
То y
, что ode
передается функции, является производным от массива начальных значений. Входные данные (2,1,1) сглаживаются до (2,). A (2,1,2) выдает предупреждение.