Here is my code which integrates two coupled ODEs
from scipy.integrate import odeint
import numpy as np
from numba import jit, njit
# Defining the RHS of the ODEs
@njit
def odes(x, t):
dAdt = 1. - x[0] - x[0]*x[1]
dBdt = x[0]*x[1] - x[1]
return [dAdt, dBdt]
# Function to run the ODE solver
#@njit
def runODE(x0N, tN):
x = odeint(odes, x0N, tN)
return x
#Initial conditons
x0N = [-1, 1]
tN = np.linspace(0, 15, 1000)
# Run ODE integrator
runODE(x0N, tN)
In Jupyter, this code works properly, but if I uncomment the second @njit
, which is just above def runODE(x0N, tN):
, the code does not work. It throws this error message
TypingError: Failed in nopython mode pipeline (step: nopython frontend)
Untyped global name 'odeint': Cannot determine Numba type of <class 'function'>
File "../../../var/folders/93/q048873x79gdg4m651rg7gxm0000gn/T/ipykernel_71195/259662853.py", line 17:
<source missing, REPL/exec in use?>
Why is the code breaking down and How to fix it?
First you have to know how Numba works.
Numba's @jit
decorator has two modes, nopython mode and object mode. @njit
is alias for @jit(nopython=True)
. When @njit
is active then nopython mode is activated which should give the best performance for an algorithm you made in python.
But when you use other libraries such as pandas (or in your case odeint) and use @jit
you'll get a warning that it'll be set in object mode, meaning you are using an object in your function being odeint.
This will still compile, however, you basically should just comment it out because you are not using nopython mode. But if you had loops in your function, solving the differential equation using numerical methods you would then use nopython mode to "best efficiency".
Overall, you are using the odeint class and trying to use numba in nopython mode while you are using objects.