## 82 Package odepack ¶

### 82.1 Introduction to ODEPACK ¶

> ODEPACK is a collection of Fortran solvers for the initial value problem for ordinary differential equation systems. It consists of nine solvers, namely a basic solver called LSODE and eight variants of it – LSODES, LSODA, LSODAR, LSODPK, LSODKR, LSODI, LSOIBT, and LSODIS. The collection is suitable for both stiff and nonstiff systems. It includes solvers for systems given in explicit form, dy/dt = f(t,y), and also solvers for systems given in linearly implicit form, A(t,y) dy/dt = g(t,y). Two of the solvers use general sparse matrix solvers for the linear systems that arise. Two others use iterative (preconditioned Krylov) methods instead of direct methods for these linear systems. The most recent addition is LSODIS, which solves implicit problems with general sparse treatment of all matrices involved.

9

References: [1] Fortran Code is from https://www.netlib.org/odepack/

Categories: Numerical methods · Share packages · Package odepack ·

#### 82.1.1 Getting Started with ODEPACK ¶

Of the eight variants of the solver, Maxima currently only has an interface to `dlsode`.

Let’s say we have this system of equations to solve: $$ \eqalign{ f_1 &= -0.04 y_1 + 10^4 y_2 y_3 \cr f_3 &= 3\times 10^7 y_2^2 \cr {dy_1 \over dt} &= f_1 \cr {dy_2 \over dt} &= -f_1 - f_3 \cr {dy_3 \over dt} &= f_3 \cr } $$

The independent variable is \(t\); the dependent variables are \(y_1,\) \(y_2,\) and \(y_3.\)

To start the solution, set up the differential equations to solved:

    (%i1) load("dlsode")$
    (%i2) f1: -.04d0*y1 + 1d4*y2*y3$
    (%i3) f3: 3d7*y2*y2$
    (%i4) f2: -f1 - f3$

    (%i5) fex: [f1, f2, f3];
    (%o5) [10000.0 y2 y3 - 0.04 y1,
                                              2                    2
                    - 10000.0 y2 y3 - 3.0e7 y2  + 0.04 y1, 3.0e7 y2 ]

Initialize the solver, where we have selected method 21:

    (%i1) load("dlsode")$
    (%i2) f1: -.04d0*y1 + 1d4*y2*y3$
    (%i3) f3: 3d7*y2*y2$
    (%i4) f2: -f1 - f3$

    (%i5) fex: [f1, f2, f3];
    (%o5) [10000.0 y2 y3 - 0.04 y1,
                                              2                    2
                    - 10000.0 y2 y3 - 3.0e7 y2  + 0.04 y1, 3.0e7 y2 ]

    (%i6) state : dlsode_init(fex, ['t,y1,y2,y3], 21);
    (%o6) [[f, #<Function "LAMBDA ($T $Y1 $Y2 $Y3)" {6177C099}>],
    [vars, [t, y1, y2, y3]], [mf, 21], [neq, 3], [lrw, 58],
    [liw, 23], [rwork, {Lisp Array: #(0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.\
    0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
                   0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0\
    .0 0.0 0.0 0.0
                   0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0\
    .0 0.0 0.0 0.0
                   0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0)}],
    [iwork,
    {Lisp Array: #(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)}],
    [fjac, #<Function "LAMBDA ($T $Y1 $Y2 $Y3)" {616B2099}>]]

The arrays rwork and iwork carry state between calls to `dlsode_step`, so they should not be modified by the user. In fact, this state returned from `dlsode_init` should not be modified by the user at all.

Now that the algorithm has been initialized we can compute solutions to the differential equation, using the state returned above.

For this example, we want to compute the solution at times \(0.4\times 10^k\) for \(k\) from 0 to 11, with the initial values of 1, 0, 0 for the dependent variables and with a relative tolerance of \(10^{-4}\) and absolute tolerances of \(10^{-6},\) \(10^{-10},\) and \(10^{-6}\) for the dependent variables.

Then, putting everything together

    (%i1) load("dlsode")$
    (%i2) f1: -.04d0*y1 + 1d4*y2*y3$
    (%i3) f3: 3d7*y2*y2$
    (%i4) f2: -f1 - f3$

    (%i5) fex: [f1, f2, f3];
    (%o5) [10000.0 y2 y3 - 0.04 y1,
                                              2                    2
                    - 10000.0 y2 y3 - 3.0e7 y2  + 0.04 y1, 3.0e7 y2 ]

    (%i6) state : dlsode_init(fex, ['t,y1,y2,y3], 21)$
    (%i7) y: [1d0, 0d0, 0d0]$
    (%i8) t: 0d0$
    (%i9) rtol : 1d-4$
    (%i10) atol: [1d-6, 1d-10, 1d-6]$
    (%i11) istate: 1$
    (%i12) t:0d0$

    (%i13) tout:.4d0$

    (%i14) for k : 1 thru 12 do
      block([],
        result: dlsode_step(y, t, tout, rtol, atol, istate, state),
        printf(true, "At t = ~12,4,2e   y = ~{~14,6,2e~}~%", result[1], result[2]),
        istate : result[3],
        tout : tout * 10);
    At t =   4.0000e-01   y =   9.851726e-01  3.386406e-05  1.479357e-02
    At t =   4.0000e+00   y =   9.055142e-01  2.240418e-05  9.446344e-02
    At t =   4.0000e+01   y =   7.158050e-01  9.184616e-06  2.841858e-01
    At t =   4.0000e+02   y =   4.504846e-01  3.222434e-06  5.495122e-01
    At t =   4.0000e+03   y =   1.831701e-01  8.940379e-07  8.168290e-01
    At t =   4.0000e+04   y =   3.897016e-02  1.621193e-07  9.610297e-01
    At t =   4.0000e+05   y =   4.935213e-03  1.983756e-08  9.950648e-01
    At t =   4.0000e+06   y =   5.159269e-04  2.064759e-09  9.994841e-01
    At t =   4.0000e+07   y =   5.306413e-05  2.122677e-10  9.999469e-01
    At t =   4.0000e+08   y =   5.494530e-06  2.197824e-11  9.999945e-01
    At t =   4.0000e+09   y =   5.129458e-07  2.051784e-12  9.999995e-01
    At t =   4.0000e+10   y =  -7.170563e-08 -2.868225e-13  1.000000e+00
    (%o14)                        done

    (%i15) result;
    (%o15) [4.0e10, [- 7.170562924983933e-8,
    - 2.868224674710487e-13, 1.000000071705913], 2,
    [[n_steps, 330], [n_f_eval, 405], [n_j_eval, 69],
    [method_order, 1], [len_rwork, 58], [len_iwork, 23]]]

### 82.2 Functions and Variables for odepack ¶

Function: dlsode_init (fex, vars, method) ¶

  This must be called before running the solver. This function returns a state object for use in the solver. The user must not modify the state.

  The ODE to be solved is given in fex, which is a list of the equations. vars is a list of independent variable and the dependent variables. The list of dependent variables must be in the same order as the equations if fex. Finally, method indicates the method to be used by the solver:

  > `10`

  >   Nonstiff (Adams) method, no Jacobian used.

  > `21`

  >   Stiff (BDF) method, user-supplied full Jacobian.

  > `22`

  >   Stiff method, internally generated full Jacobian.

  The returned state object is a list of lists. The sublist is a list of two elements:

  > `f`

  >   The compiled function for the ODE.

  > `vars`

  >   The list independent and dependent variables (vars).

  > `mf`

  >   The method to be used (method).

  > `neq`

  >   The number of equations.

  > `lrw`

  >   Length of the work vector for real values.

  > `liw`

  >   Length of the work vector for integer values.

  > `rwork`

  >   Lisp array holding the real-valued work vector.

  > `iwork`

  >   Lisp array holding the integer-valued work vector.

  > `fjac`

  >   Compiled analytical Jacobian of the equations

  See also dlsode_step. See Getting Started with ODEPACK for an example of usage.

  Categories: Package odepack ·

Function: dlsode_step (inity, t, tout, rtol, atol, istate, state) ¶

  Performs one step of the solver, returning the values of the independent and dependent variables, a success or error code.

  The parameters for `dlsode_step` are:

  > `inity`

  >   For the first call (when istate = 1), the initial values

  > `t`

  >   Current value of the independent value

  > `tout`

  >   Next point where output is desired which must not be equal to t.

  > `rtol`

  >   relative tolerance parameter

  > `atol`

  >   Absolute tolerance parameter, scalar of vector. If scalar, it applies to all dependent variables. Otherwise it must be the tolerance for each dependent variable.

  >   Use rtol = 0 for pure absolute error and use atol = 0 for pure relative error.

  > `istate`

  >   1 for the first call to dlsode, 2 for subsequent calls.

  > `state`

  >   state returned by dlsode_init.

  The output is a list of the following items:

  > `t`

  >   independent variable value

  > `y`

  >   list of values of the dependent variables at time t.

  > `istate`

  >   Integration status:

  >   > `1`

  >   >   no work because tout = tt

  >   > `2`

  >   >   successful result

  >   > `-1`

  >   >   Excess work done on this call

  >   > `-2`

  >   >   Excess accuracy requested

  >   > `-3`

  >   >   Illegal input detected

  >   > `-4`

  >   >   Repeated error test failures

  >   > `-5`

  >   >   Repeated convergence failures (perhaps bad Jacobian or wrong choice of mf or tolerances)

  >   > `-6`

  >   >   Error weight because zero during problem (solution component is vanished and atol(i) = 0.

  > `info`

  >   association list of various bits of information:

  >   > `n_steps`

  >   >   total steps taken thus far

  >   > `n_f_eval`

  >   >   total number of function evals

  >   > `n_j_eval`

  >   >   total number of Jacobian evals

  >   > `method_order`

  >   >   method order

  >   > `len_rwork`

  >   >   Actual length used for real work array

  >   > `len_iwork`

  >   >   Actual length used for integer work array

  See also dlsode_init. See Getting Started with ODEPACK for an example of usage.

  Categories: Package odepack ·

#### Footnotes

##### (9)

From https://www.netlib.org/odepack/opkd-sum

JavaScript license information