试图使用solve_ivp的矢量化选项,奇怪的是它会抛出y0必须是1维的错误。 MWE:
from scipy.integrate import solve_ivp
import numpy as np
import math
def f(t, y):
theta = math.pi/4
ham = np.array([[1,0],[1,np.exp(-1j*theta*t)]])
return-1j * np.dot(ham,y)
def main():
y0 = np.eye(2,dtype= np.complex128)
t0 = 0
tmax = 10**(-6)
sol=solve_ivp( lambda t,y :f(t,y),(t0,tmax),y0,method='RK45',vectorized=True)
print(sol.y)
if __name__ == '__main__':
main()
主叫签名很有趣(t,y)。这里t是一个标量,ndarray y有两个选项:它可以有形状(n,);那么fun必须返回带有shape(n,)的array_like。或者,它可以具有形状(n,k);那么fun必须返回一个带有shape(n,k)的array_like,即每列对应y中的一列。两个选项之间的选择由矢量化参数决定(见下文)。矢量化实现允许通过有限差分(刚性求解器所需)更快地逼近雅可比行列式。
错误:
ValueError:
y0
必须是1维的。
Python 3.6.8
scipy.version'1.2.1'
这里vectorize
的含义有点令人困惑。这并不意味着y0
可以是2d,而是传递给你的函数的y
可以是2d。换句话说,如果解算器需要,可以在多个点同时评估func
。求解者需要多少分,而不是你。
更改f
以在每次通话时显示y
的形状:
def f(t, y):
print(y.shape)
theta = math.pi/4
ham = np.array([[1,0],[1,np.exp(-1j*theta*t)]])
return-1j * np.dot(ham,y)
一个样本电话:
In [47]: integrate.solve_ivp(f,(t0,tmax),[1j,0],method='RK45',vectorized=False)
(2,)
(2,)
(2,)
(2,)
(2,)
(2,)
(2,)
(2,)
Out[47]:
message: 'The solver successfully reached the end of the integration interval.'
nfev: 8
njev: 0
nlu: 0
sol: None
status: 0
success: True
t: array([0.e+00, 1.e-06])
t_events: None
y: array([[0.e+00+1.e+00j, 1.e-06+1.e+00j],
[0.e+00+0.e+00j, 1.e-06-1.e-12j]])
同样的电话,但与vectorize=True
:
In [48]: integrate.solve_ivp(f,(t0,tmax),[1j,0],method='RK45',vectorized=True)
(2, 1)
(2, 1)
(2, 1)
(2, 1)
(2, 1)
(2, 1)
(2, 1)
(2, 1)
Out[48]:
message: 'The solver successfully reached the end of the integration interval.'
nfev: 8
njev: 0
nlu: 0
sol: None
status: 0
success: True
t: array([0.e+00, 1.e-06])
t_events: None
y: array([[0.e+00+1.e+00j, 1.e-06+1.e+00j],
[0.e+00+0.e+00j, 1.e-06-1.e-12j]])
假的,传递给y
的f
是(2,),1d;如果是,它是(2,1)。如果解算器方法如此需要,我猜它可能是(2,2)甚至(2,3)。这可以加快执行速度,减少对f
的调用。在这种情况下,没关系。
quadrature
有一个类似的vec_func
布尔参数:
Numerical Quadrature of scalar valued function with vector input using scipy
相关的错误/问题讨论: