ODE_SOLVER¶
An optional section that defines how an PoPy will solve the ordinary differential equations in the DERIVATIVES section.
Note the ODE_SOLVER section is optional, if you have no DERIVATIVES section then you do not need to have an ODE_SOLVER section.
The ODE_SOLVER section is available in the following scripts:-
i.e. Any script that processes PK/PD models and may have a DERIVATIVES section, may also have an ODE_SOLVER section.
ODE_SOLVER Options¶
There are three principle ODE_SOLVER options available:-
- NO_SOLVER - use if there is no DERIVATIVES section
- ANALYTIC - use if DERIVATIVES contains only analytic compartment functions
- CPPLSODA - numerical solver - use if DERIVATIVES contains
d[X]
equations - SCIPY_ODEINT - numerical solver - deprecated, slower, SciPy version of CPPLSODA.
The options above are tied to the nature of the DERIVATIVES section. Some examples of DERIVATIVES sections and appropriate ODE_SOLVER settings are shown below.
Example ODE_SOLVER using NO_SOLVER¶
In the case where the PoPy script contains no DERIVATIVES section or the DERIVATIVES section is null:-
DERIVATIVES: |
Then the PoPy script should contain no ODE_SOLVER section or the ODE_SOLVER should also be null:-
ODE_SOLVER:
NO_SOLVER: {}
If the DERIVATIVES section is null and ODE_SOLVER is set to ‘ANALYTIC’ or ‘SCIPY_ODEINT’, then PoPy should issue a warning, but the ODE_SOLVER section will otherwise have no effect.
Note, the simplest solution if you have no compartment model is to just remove the DERIVATIVES and ODE_SOLVER sections from the script completely.
Example ODE_SOLVER using ANALYTIC¶
In the case where the PoPy script contains a DERIVATIVES section consisting of only an analytic compartment function:-
DERIVATIVES: |
s[DEPOT,CENTRAL,PERI] = @dep_two_cmp_cl{dose:@bolus{amt:c[AMT]}
Then the ODE_SOLVER section should be:-
ODE_SOLVER:
ANALYTIC: {}
If the DERIVATIVES section contains only an analytic compartment function and ODE_SOLVER is set to ‘NO_SOLVER’ or ‘SCIPY_ODEINT’, then PoPy should issue a warning, but the ODE_SOLVER section will otherwise automatically switch to ‘ANALYTIC’.
Example ODE_SOLVER using CPPLSODA¶
In the case where the PoPy script contains a DERIVATIVES section consisting of ordinary differential equations with d[X]
variables on the left hand side and s[X]
on the right hand side, for example:-
DERIVATIVES: |
# s[DEPOT,CENTRAL,PERI] = @dep_two_cmp_cl{dose:@bolus{amt:c[AMT]}}
d[DEPOT] = @bolus{amt:c[AMT]} - m[KA]*s[DEPOT]
d[CENTRAL] = m[KA]*s[DEPOT] - s[CENTRAL]*m[CL]/m[V1] - s[CENTRAL]*m[Q]/m[V1] + s[PERI]*m[Q]/m[V2]
d[PERI] = s[CENTRAL]*m[Q]/m[V1] - s[PERI]*m[Q]/m[V2]
Then the ODE_SOLVER section should use ‘CPPLSODA’, for example:-
ODE_SOLVER:
CPPLSODA:
atol: 1e-06
rtol: 1e-06
max_nsteps: 10000000
If the DERIVATIVES section contains d[X]
equations and ODE_SOLVER is set to ‘NO_SOLVER’ or ‘ANALYTIC’, then PoPy should issue an error when checking the script, because a numerical solver is required.
CPPLSODA is a C++ version of the Fortran LSODA solver [Radhakrishnan1994]. The same ordinary differential equation solver method used by the Nonmem ADVAN13 routine.
Note that CPPLSODA exposes the following parameters of LSODA:-
- atol - Additive tolerance of the LSODA error control
- rtol - Relative tolerance of the LSODA error control
- max_nsteps - Maximum number of steps for LSODA integrator
All of the parameters above are optional with the following default values:-
- atol: 1e-12
- rtol: 1e-12
- max_nsteps: 10000000
Hence the following ODE_SOLVER section:-
ODE_SOLVER: {CPPLSODA: {}}
Is equivalent to:-
ODE_SOLVER:
CPPLSODA:
atol: 1e-12
rtol: 1e-12
max_nsteps: 10000000
Example ODE_SOLVER using SCIPY_ODEINT¶
Note ‘SCIPY_ODEINT’ is deprecated in favour of CPPLSODA above.
SCIPY_ODEINT is a wrapper around the following Python numerical ordinary differential equation solver from the SciPy package:-
scipy.integrate.odeint
Which in turn is a wrapper around the Fortran LSODA solver [Radhakrishnan1994]. The same ordinary differential equation solver that is used by the Nonmem ADVAN13 routine. You can read more about this integrator here in the SciPy documentation:-
http://lagrange.univ-lyon1.fr/docs/scipy/0.17.1/generated/scipy.integrate.odeint.html
Note that PoPy exposes the following parameters of LSODA:-
- atol - Additive tolerance of the LSODA error control
- rtol - Relative tolerance of the LSODA error control
- max_nsteps - Maximum number of steps for LSODA integrator (called ‘mxstep’ in link above)
All of the parameters above are optional with the following default values:-
- atol: 1e-12
- rtol: 1e-12
- max_nsteps: 10000000
Hence the following ODE_SOLVER section:-
ODE_SOLVER: {SCIPY_ODEINT: {}}
Is equivalent to:-
ODE_SOLVER:
SCIPY_ODEINT:
atol: 1e-12
rtol: 1e-12
max_nsteps: 10000000
Note it is recommended to use CPPLSODA instead, which is faster and will give very similar results.