I am trying to use complex_ode method instead of ode method in scipy.integrate. The help page for complex_ode does not provide example, so I may have done something wrong.
This code works properly with scipy.integrate.ode:
from scipy.integrate import ode
y0, t0 = [1.0j, 2.0], 0
def f(t, y, arg1):
return [1j*arg1*y[0] + y[1], -arg1*y[1]**2]
def jac(t, y, arg1):
return [[1j*arg1, 1], [0, -arg1*2*y[1]]]
r = ode(f, jac).set_integrator('zvode', method='bdf', with_jacobian=True)
r.set_initial_value(y0, t0).set_f_params(2.0).set_jac_params(2.0)
t1 = 10
dt = 1
while r.successful() and r.t < t1:
r.integrate(r.t+dt)
print(r.t, r.y)
Now this other code tries to do the same with complex_ode.
from scipy.integrate import complex_ode
y0, t0 = [1.0j, 2.0], 0
def f(t, y, arg1):
return [1j*arg1*y[0] + y[1], -arg1*y[1]**2]
def jac(t, y, arg1):
return [[1j*arg1, 1], [0, -arg1*2*y[1]]]
r = complex_ode(f, jac)
r.set_initial_value(y0, t0).set_f_params(2.0).set_jac_params(2.0)
t1 = 10
dt = 1
while r.successful() and r.t < t1:
r.integrate(r.t+dt)
print(r.t, r.y)
But the r.integrate line complains with this error: 'float' object has no attribute 'getitem'.
Could someone please tell me what am I doing wrong?
The primary advantage is that solve_ivp offers several methods for solving differential equations whereas odeint is restricted to one. We get started by setting up our system of differential equations and some parameters of the simulation.
ode(f, jac=None)[source] A generic interface class to numeric integrators. Solve an equation system y ′ ( t ) = f ( t , y ) with (optional) jac = df/dy .
Numerical integration integrate module. It takes as input arguments the function f(x) to be integrated (the “integrand”), and the lower and upper limits a and b. It returns two values (in a tuple): the first one is the computed results and the second one is an estimation of the numerical error of that result.
This would appear to be a known bug in scipy.integrate. It seems that additional argument passing is broken in complex_ode
. You could try and see if they have fixed it in a newer release (although this bug report suggests they haven't), or just restrict yourself to your own wrapper functions without additional arguments when using complex_ode
. For example, a hacky solution for your example could be something like:
from scipy.integrate import complex_ode
class myfuncs(object):
def __init__(self, f, jac, fargs=[], jacargs=[]):
self._f = f
self._jac = jac
self.fargs=fargs
self.jacargs=jacargs
def f(self, t, y):
return self._f(t, y, *self.fargs)
def jac(self, t, y):
return self._jac(t, y, *self.jacargs)
def f(t, y, arg1):
return [1j*arg1*y[0] + y[1], -arg1*y[1]**2]
def jac(t, y, arg1):
return [[1j*arg1, 1], [0, -arg1*2*y[1]]]
y0, t0 = [1.0j, 2.0], 0
case = myfuncs(f, jac, fargs=[2.], jacargs=[2.])
r = complex_ode(case.f, case.jac)
r.set_initial_value(y0, t0)
t1 = 10
dt = 1
while r.successful() and r.t < t1:
r.integrate(r.t+dt)
print(r.t, r.y)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With