问题描述
我尝试研究了spice.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]])
不起作用,我应该怎样做才能使它们起作用? - 为什么
x
和y
的 numpy 数组的形状变成 () 而不是 (1,1)。 - 如何在使用 scipy 的集成过程中使 x 和 y 的 numpy 数组的形状为 (1,1)。如果
x_ini
和y_ini
的形状都是 (2,2) 并且我想在使用 scipy 的集成过程中使形状保持一致,我该怎么办。
有知道的小伙伴吗?
解决方法
我在使用您的初始值数组时收到警告:
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.]
...
如果我将初始值更改为 (2,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) 输入被展平为 (2,)。 A (2,2) 产生警告。