微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在使用 scipy 集成期间,如何使用 print() 命令并使 numpy 数组的形状保持一致?

如何解决在使用 scipy 集成期间,如何使用 print() 命令并使 numpy 数组的形状保持一致?

我尝试研究了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_iniy_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_iniy_ini 设为 (1,1) 形状,print(x.shape)print(y.shape)显示 ()。

所以问题是:

  1. 为什么 print()x_ini = y_ini = np.array([[2,2]]) 不起作用,我应该怎样做才能使它们起作用?
  2. 为什么 xy 的 numpy 数组的形状变成 () 而不是 (1,1)。
  3. 如何在使用 scipy 的集成过程中使 x 和 y 的 numpy 数组的形状为 (1,1)。如果 x_iniy_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/dty 将是一个一维数组,它应该返回一个类似大小的数组。请注意 y.shape 要求。

y 传递给函数的 ode 来自初始值数组。 (2,1) 输入被展平为 (2,)。 A (2,2) 产生警告。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。