<?xml version="1.0"?>

<!--
   Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
  -->

<document url="ode.html">

  <properties>
    <title>The Commons Math User Guide - Ordinary Differential Equations Integration</title>
  </properties>

  <body>
    <section name="15 Ordinary Differential Equations Integration">
      <subsection name="15.1 Overview" href="overview">
        <p>
          The ode package provides classes to solve Ordinary Differential Equations problems.
        </p>
        <p>
          This package solves Initial Value Problems of the form y'=f(t,y) with t<sub>0</sub>
          and y(t<sub>0</sub>)=y<sub>0</sub> known. The provided integrators compute an estimate
          of y(t) from t=t<sub>0</sub> to t=t<sub>1</sub>.
        </p>
        <p>
          All integrators provide dense output. This means that besides computing the state vector
          at discrete times, they also provide a cheap means to get both the state and its derivative
          between the time steps. They do so through classes extending the
          <a href="../apidocs/org/apache/commons/math4/ode/sampling/StepInterpolator.html">StepInterpolator</a>
          abstract class, which are made available to the user at the end of each step.
        </p>
        <p>
          All integrators handle multiple discrete events detection based on switching
          functions. This means that the integrator can be driven by user specified discrete events
          (occurring when the sign of user-supplied <i>switching function</i> changes). The steps are
          shortened as needed to ensure the events occur at step boundaries (even if the integrator
          is a fixed-step integrator). When the events are triggered, integration can
          be stopped (this is called a G-stop facility), the state vector can be changed, or integration
          can simply go on. The latter case is useful to handle discontinuities in the differential
          equations gracefully and get accurate dense output even close to the discontinuity.
        </p>
        <p>
          All integrators support setting a maximal number of evaluations of differential
          equations function. If this number is exceeded, an exception will be thrown during
          integration. This can be used to prevent infinite loops if for example error control or
          discrete events create a really large number of extremely small steps. By default, the
          maximal number of evaluation is set to <code>Integer.MAX_VALUE</code> (i.e. 2<sup>31</sup>-1
          or 2147483647). It is recommended to set this maximal number to a value suited to the ODE
          problem, integration range, and step size or error control settings.
        </p>
        <p>
          All integrators support expanding the main ODE with one or more secondary ODE to manage
          additional state that will be integrated together with the main state. This can be used
          for example to integrate variational equations and compute not only the main state but also
          its partial derivatives with respect to either the initial state or some parameters, these
          derivatives being handled be secondary ODE (see below for an example).
        </p>
        <p>
         Two parallel APIs are available. The first is devoted to solve ode for which the integration free
         variable t and the state y(t) are primitive double and primitive double array respectively. Starting
         with version 3.6, a second API is devoted to solve ode for which the integration free
         variable t and the state y(t) are <code>RealFieldElement</code> and <code>RealFieldElement</code>
         array respectively. This allow for example users to integrate ode where the computation values
         are for example <code>DerivativeStructure</code> elements, hence automatically computing
         partial derivatives with respect to some equations parameters without a need to set up the
         variational equations. Another example is to use <code>Dfp</code> elements in order to solve
         ode with extended precision. As of 3.6, the API are slightly different, mainly in the way they
         handle arrays. Both API will become more similar in 4.0 and future versions as the older
         primitive double API will be modified to match the newer field API. This cannot be done in
         3.6 for compatibility reasons.
        </p>
        <p>
          The user should describe his problem in his own classes which should implement the
          <a href="../apidocs/org/apache/commons/math4/ode/FirstOrderDifferentialEquations.html">FirstOrderDifferentialEquations</a>
          interface (or  <a href="../apidocs/org/apache/commons/math4/ode/FirstOrderFieldDifferentialEquations.html">FirstOrderFieldDifferentialEquations</a>
          interface). Then they should pass it to the integrator they prefer among all the classes that implement
          the <a href="../apidocs/org/apache/commons/math4/ode/FirstOrderIntegrator.html">FirstOrderIntegrator</a>
          interface (or the <a href="../apidocs/org/apache/commons/math4/ode/FirstOrderFieldIntegrator.html">FirstOrderFieldIntegrator</a>
          interface). The following example shows how to implement the simple two-dimensional problem using double primitives:
          <ul>
            <li>y'<sub>0</sub>(t) = &#x3c9; &#xD7; (c<sub>1</sub> - y<sub>1</sub>(t))</li>
            <li>y'<sub>1</sub>(t) = &#x3c9; &#xD7; (y<sub>0</sub>(t) - c<sub>0</sub>)</li>
          </ul>
          with some initial state y(t<sub>0</sub>) = (y<sub>0</sub>(t<sub>0</sub>), y<sub>1</sub>(t<sub>0</sub>)).
          In fact, the exact solution of this problem is that y(t) moves along a circle
          centered at c = (c<sub>0</sub>, c<sub>1</sub>) with constant angular rate &#x3c9;.
        </p>
        <source>
private static class CircleODE implements FirstOrderDifferentialEquations {

    private double[] c;
    private double omega;

    public CircleODE(double[] c, double omega) {
        this.c     = c;
        this.omega = omega;
    }

    public int getDimension() {
        return 2;
    }

    public void computeDerivatives(double t, double[] y, double[] yDot) {
        yDot[0] = omega * (c[1] - y[1]);
        yDot[1] = omega * (y[0] - c[0]);
    }

}
        </source>
        <p>
          Computing the state y(16.0) starting from y(0.0) = (0.0, 1.0) and integrating the ODE
          is done as follows (using Dormand-Prince 8(5,3) integrator as an example):
        </p>
        <source>
FirstOrderIntegrator dp853 = new DormandPrince853Integrator(1.0e-8, 100.0, 1.0e-10, 1.0e-10);
FirstOrderDifferentialEquations ode = new CircleODE(new double[] { 1.0, 1.0 }, 0.1);
double[] y = new double[] { 0.0, 1.0 }; // initial state
dp853.integrate(ode, 0.0, y, 16.0, y); // now y contains final state at time t=16.0
        </source>
      </subsection>
      <subsection name="15.2 Continuous Output" href="continuous">
        <p>
          The solution of the integration problem is provided by two means. The first one is aimed towards
          simple use: the state vector at the end of the integration process is copied in the y array of the
          <code>FirstOrderIntegrator.integrate</code> method, as shown by previous example. The second one
          should be used when more in-depth information is needed throughout the integration process. The user
          can register an object implementing the
          <a href="../apidocs/org/apache/commons/math4/ode/sampling/StepHandler.html">StepHandler</a> interface or a
          <a href="../apidocs/org/apache/commons/math4/ode/sampling/StepNormalizer.html">StepNormalizer</a> object wrapping
          a user-specified object implementing the
          <a href="../apidocs/org/apache/commons/math4/ode/sampling/FixedStepHandler.html">FixedStepHandler</a> interface
          into the integrator before calling the <code>FirstOrderIntegrator.integrate</code> method. The user object
          will be called appropriately during the integration process, allowing the user to process intermediate
          results. The default step handler does nothing. Considering again the previous example, we want to print the
          trajectory of the point to check it really is a circle arc. We simply add the following before the call
          to integrator.integrate:
        </p>
        <source>
StepHandler stepHandler = new StepHandler() {
    public void init(double t0, double[] y0, double t) {
    }

    public void handleStep(StepInterpolator interpolator, boolean isLast) {
        double   t = interpolator.getCurrentTime();
        double[] y = interpolator.getInterpolatedState();
        System.out.println(t + " " + y[0] + " " + y[1]);
    }
};
integrator.addStepHandler(stepHandler);
        </source>
        <p>
          <a href="../apidocs/org/apache/commons/math4/ode/ContinuousOutputModel.html">ContinuousOutputModel</a>
          is a special-purpose step handler that is able to store all steps and to provide transparent access to
          any intermediate result once the integration is over. An important feature of this class is that it
          implements the <code>Serializable</code> interface. This means that a complete continuous model of the
          integrated function throughout the integration range can be serialized and reused later (if stored into
          a persistent medium like a file system or a database) or elsewhere (if sent to another application).
          Only the result of the integration is stored, there is no reference to the integrated problem by itself.
        </p>
        <p>
          Other default implementations of the <a href="../apidocs/org/apache/commons/math4/ode/sampling/StepHandler.html">StepHandler</a>
          interface are available for general needs
          (<a href="../apidocs/org/apache/commons/math4/ode/sampling/DummyStepHandler.html">DummyStepHandler</a>,
          <a href="../apidocs/org/apache/commons/math4/ode/sampling/StepNormalizer.html">StepNormalizer</a>) and custom
          implementations can be developed for specific needs. As an example, if an application is to be
          completely driven by the integration process, then most of the application code will be run inside a
          step handler specific to this application.
        </p>
        <p>
          Some integrators (the simple ones) use fixed steps that are set at creation time. The more efficient
          integrators use variable steps that are handled internally in order to control the integration error
          of the main state with respect to a specified accuracy (these integrators extend the
          <a href="../apidocs/org/apache/commons/math4/ode/AdaptiveStepsizeIntegrator.html">AdaptiveStepsizeIntegrator</a>
          abstract class). The secondary equations are explicitly ignored for step size control, in order to get reproducible
          results regardless of the secondary equations being integrated or not. The step handler which is called after each
          successful step shows up the variable stepsize. The <a href="../apidocs/org/apache/commons/math4/ode/sampling/StepNormalizer.html">StepNormalizer</a>
          class can be used to convert the variable stepsize into a fixed stepsize that can be handled by classes
          implementing the <a href="../apidocs/org/apache/commons/math4/ode/sampling/FixedStepHandler.html">FixedStepHandler</a>
          interface. Adaptive stepsize integrators can automatically compute the initial stepsize by themselves,
          however the user can specify it if they prefer to retain full control over the integration or if the
          automatic guess is wrong.
        </p>
      </subsection>
      <subsection name="15.3 Discrete Events Handling" href="events">
        <p>
          ODE problems are continuous ones. However, sometimes discrete events must be
          taken into account. The most frequent case is the stop condition of the integrator
          is not defined by the time t but by a target condition on state y (say y[0] = 1.0
          for example).
        </p>
        <p>
          Discrete events detection is based on switching functions. The user provides
          a simple <a href="../apidocs/org/apache/commons/math4/ode/events/EventHandler.html">g(t, y)</a>
          function depending on the current time and state. The integrator will monitor
          the value of the function throughout integration range and will trigger the
          event when its sign changes. The magnitude of the value is almost irrelevant.
          For the sake of root finding, it should however be continuous (but not necessarily smooth)
          at least in the roots vicinity. The steps are shortened as needed to ensure the events occur
          at step boundaries (even if the integrator is a fixed-step integrator).
        </p>
        <p>
          When an event is triggered, the event time, current state and an indicator
          whether the switching function was increasing or decreasing at event time
          are provided to the user. Several different options are available to him:
        </p>
        <ul>
          <li>integration can be stopped (this is called a G-stop facility),</li>
          <li>the state vector or the derivatives can be changed,</li>
          <li>or integration can simply go on.</li>
        </ul>

        <p>
          The first case, G-stop, is the most common one. A typical use case is when an
          ODE must be solved up to some target state is reached, with a known value of
          the state but an unknown occurrence time. As an example, if we want to monitor
          a chemical reaction up to some predefined concentration for the first substance,
          we can use the following switching function setting:
        </p>
        <source>
public double g(double t, double[] y) {
  return y[0] - targetConcentration;
}

public int eventOccurred(double t, double[] y, boolean increasing) {
  return STOP;
}
       </source>

       <p>
         The second case, change state vector or derivatives is encountered when dealing
         with discontinuous dynamical models. A typical case would be the motion of a
         spacecraft when thrusters are fired for orbital maneuvers. The acceleration is
         smooth as long as no maneuvers are performed, depending only on gravity, drag,
         third body attraction, radiation pressure. Firing a thruster introduces a
         discontinuity that must be handled appropriately by the integrator. In such a case,
         we would use a switching function setting similar to this:
       </p>
       <source>
public double g(double t, double[] y) {
  return (t - tManeuverStart) * (t - tManeuverStop);
}

public int eventOccurred(double t, double[] y, boolean increasing) {
  return RESET_DERIVATIVES;
}
        </source>

        <p>
          The third case is useful mainly for monitoring purposes, a simple example is:
        </p>
        <source>
public double g(double t, double[] y) {
  return y[0] - y[1];
}

public int eventOccurred(double t, double[] y, boolean increasing) {
  logger.log("y0(t) and y1(t) curves cross at t = " + t);
  return CONTINUE;
}
        </source>
      </subsection>
      <subsection name="15.4 Available Integrators" href="integrators">
        <p>
          The tables below show the various integrators available for non-stiff problems. Note that the
          implementations of Adams-Bashforth and Adams-Moulton are adaptive stepsize, not fixed stepsize
          as is usual for these multi-step integrators. This is due to the fact the implementation relies
          on the Nordsieck vector representation of the state.
        </p>
        <p>
          <table border="1" align="center">
          <tr BGCOLOR="#CCCCFF"><td colspan="2"><font size="+1">Fixed Step Integrators</font></td></tr>
          <tr BGCOLOR="#EEEEFF"><font size="+1"><td>Name</td><td>Order</td></font></tr>
          <tr><td><a href="../apidocs/org/apache/commons/math4/ode/nonstiff/EulerIntegrator.html">Euler</a></td><td>1</td></tr>
          <tr><td><a href="../apidocs/org/apache/commons/math4/ode/nonstiff/MidpointIntegrator.html">Midpoint</a></td><td>2</td></tr>
          <tr><td><a href="../apidocs/org/apache/commons/math4/ode/nonstiff/ClassicalRungeKuttaIntegrator.html">Classical Runge-Kutta</a></td><td>4</td></tr>
          <tr><td><a href="../apidocs/org/apache/commons/math4/ode/nonstiff/GillIntegrator.html">Gill</a></td><td>4</td></tr>
          <tr><td><a href="../apidocs/org/apache/commons/math4/ode/nonstiff/ThreeEighthesIntegrator.html">3/8</a></td><td>4</td></tr>
          <tr><td><a href="../apidocs/org/apache/commons/math4/ode/nonstiff/LutherIntegrator.html">Luther</a></td><td>6</td></tr>
          </table>
        </p>
        <p>
          <table border="1" align="center">
          <tr BGCOLOR="#CCCCFF"><td colspan="3"><font size="+1">Adaptive Stepsize Integrators</font></td></tr>
          <tr BGCOLOR="#EEEEFF"><font size="+1"><td>Name</td><td>Integration Order</td><td>Error Estimation Order</td></font></tr>
          <tr><td><a href="../apidocs/org/apache/commons/math4/ode/nonstiff/HighamHall54Integrator.html">Higham and Hall</a></td><td>5</td><td>4</td></tr>
          <tr><td><a href="../apidocs/org/apache/commons/math4/ode/nonstiff/DormandPrince54Integrator.html">Dormand-Prince 5(4)</a></td><td>5</td><td>4</td></tr>
          <tr><td><a href="../apidocs/org/apache/commons/math4/ode/nonstiff/DormandPrince853Integrator.html">Dormand-Prince 8(5,3)</a></td><td>8</td><td>5 and 3</td></tr>
          <tr><td><a href="../apidocs/org/apache/commons/math4/ode/nonstiff/GraggBulirschStoerIntegrator.html">Gragg-Bulirsch-Stoer</a></td><td>variable (up to 18 by default)</td><td>variable</td></tr>
          <tr><td><a href="../apidocs/org/apache/commons/math4/ode/nonstiff/AdamsBashforthIntegrator.html">Adams-Bashforth</a></td><td>variable</td><td>variable</td></tr>
          <tr><td><a href="../apidocs/org/apache/commons/math4/ode/nonstiff/AdamsMoultonIntegrator.html">Adams-Moulton</a></td><td>variable</td><td>variable</td></tr>
          </table>
        </p>
      </subsection>
      <subsection name="15.5 Derivatives" href="derivatives">
        <p>
          If in addition to state y(t) the user needs to compute the sensitivity of the final state with respect to
          the initial state (dy/dy<sub>0</sub>) or the sensitivity of the final state with respect to some parameters
          of the ODE (dy/dp<sub>k</sub>), they need to register the variational equations as a set of secondary equations
          appended to the main state before the integration starts. Then the integration will propagate the compound
          state composed of both the main state and its partial derivatives. At the end of the integration, the Jacobian
          matrices are extracted from the integrated secondary state. The <a
          href="../apidocs/org/apache/commons/math4/ode/JacobianMatrices.html">JacobianMatrices</a> class can do most of
          this as long as the local derivatives are provided to it. It will set up the variational equations, register
          them as secondary equations into the ODE, and it will set up the initial values and retrieve the intermediate
          and final values as Jacobian matrices.
        </p>
        <p>
          If for example the original state dimension is 6 and there are 3 parameters, the compound state will be a 60
          elements array. The first 6 elements will be the original state, the next 36 elements will represent the 6x6
          Jacobian matrix of the final state with respect to the initial state, and the remaining 18 elements will
          represent the 6x3 Jacobian matrix of the final state with respect to the 3 parameters. The <a
          href="../apidocs/org/apache/commons/math4/ode/JacobianMatrices.html">JacobianMatrices</a> class does the mapping
          between the 60 elements compound state and the Jacobian matrices and sets up the correcsponding secondary equations.
        </p>
        <p>
          As the variational equations are considered to be secondary equations here, variable step integrators ignore
          them for step size control: they rely only on the main state. This feature is a design choice. The rationale is
          to get exactly the same steps, regardless of the Jacobians being computed or not, hence ensuring reproducible
          results in both cases.
        </p>
        <p>
          What remains of user responsibility is to provide the local Jacobians df(t, y, p)/dy and df(t, y, p)/dp<sub>k</sub>
          corresponding the the main ODE y'=f(t, y, p). The main ODE is as usual provided by the user as a class implementing
          the <a href="../apidocs/org/apache/commons/math4/ode/FirstOrderDifferentialEquations.html">FirstOrderDifferentialEquations</a>
          interface or a sub-interface.
        </p>
        <p>
          If the ODE is simple enough that the user can implement df(t, y, p)/dy directly, then instead of providing an
          implementation of the <a
          href="../apidocs/org/apache/commons/math4/ode/FirstOrderDifferentialEquations.html">FirstOrderDifferentialEquations</a>
          interface only, the user should rather provide an implementation of the <a
          href="../apidocs/org/apache/commons/math4/ode/MainStateJacobianProvider.html">MainStateJacobianProvider</a> interface,
          which extends the previous interface by adding a method to compute df(t, y, p)/dy. The user class is used as a
          constructor parameter of the <a href="../apidocs/org/apache/commons/math4/ode/JacobianMatrices.html">JacobianMatrices</a>
          class. If the ODE is too complex or the user simply does not bother implementing df(t, y, p)/dy directly, then
          the ODE can still be implemented using the simple <a
          href="../apidocs/org/apache/commons/math4/ode/FirstOrderDifferentialEquations.html">FirstOrderDifferentialEquations</a>
          interface and given as such to another constructor of the <a
          href="../apidocs/org/apache/commons/math4/ode/JacobianMatrices.html">JacobianMatrices</a> class, but in this case an array
          hy must also be provided that will contain the step size to use form each component of the main state vector y, and
          the Jacobian f(t, y, p)/dy will be computed internally using finite differences. This will of course trigger more evaluations
          of the ODE at each step and will suffer from finite differences errors, but it is much simpler to implement from a user
          point of view.
        </p>
        <p>
          The parameters are identified by a name (a simple user-defined string), which are also specified at <a
          href="../apidocs/org/apache/commons/math4/ode/JacobianMatrices.html">JacobianMatrices</a> class construction. If the ODE
          is simple enough that the user can implement df(t, y, p)/dp<sub>k</sub> directly for some of the parameters p<sub>k</sub>,
          then they can provide one or more classes implementing the <a
          href="../apidocs/org/apache/commons/math4/ode/ParameterJacobianProvider.html">ParameterJacobianProvider</a> interface by
          calling the JacobianMatrices.addParameterJacobianProvide method. The parameters are handled one at a time, but all the calls to
          ParameterJacobianProvider.computeParameterJacobian will be grouped in one sequence after the call to MainStateJacobianProvider.computeMainStateJacobian
          This feature can be used when all the derivatives share a lot of costly computation. In this case, the user
          is advised to compute all the needed derivatives at once during the call to computeMainStateJacobian, including the
          partial derivatives with respect to the parameters and to store the derivatives temporary. Then when the next calls to
          computeParameterJacobian will be triggerred, it will be sufficient to return the already computed derivatives. With this
          architecture, many computation can be saved. This of course implies that the classes implementing both interfaces know
          each other (they can even be the same class if desired, but it is not required). If the ODE is too complex or the user
          simply does not bother implementing df(t, y, p)/dp<sub>k</sub> directly for some k, then
          the JacobianMatrices.setParameterStep method should be called so finite differences are used to compute the derivatives
          for this parameter. It is possible to have some parameters for which derivatives are provided by a direct implementation
          while other parameters are computed using finite differences during the same integration.
        </p>
        <p>
          The following example corresponds to a simple case where all derivatives can be computed analytically. The state is
          a 2D point travelling along a circle. There are three parameters : the two coordinates of the center and the
          angular velocity.
        </p>
        <source>
public class CircleODE implements MainStateJacobianProvider, ParameterJacobianProvider {

    public static final String CENTER_X = "cx";
    public static final String CENTER_Y = "cy";
    public static final String OMEGA    = "omega";

    private double[] c;
    private double omega;
    private double[][] savedDfDp;

    public CircleODE(double[] c, double omega) {
        this.c     = c;
        this.omega = omega;
        this.savedDfDp = new double[2][3];
    }

    public int getDimension() {
        return 2;
    }

    public void computeDerivatives(double t, double[] y, double[] yDot) {
        // the state is a 2D point, the ODE therefore corresponds to the velocity
        yDot[0] = omega * (c[1] - y[1]);
        yDot[1] = omega * (y[0] - c[0]);
    }

    public Collection&lt;String&gt; getParametersNames() {
        return Arrays.asList(CENTER_X, CENTER_Y, OMEGA);
    }

    public boolean isSupported(String name) {
        return CENTER_X.equals(name) || CENTER_Y.equals(name) || OMEGA.equals(name);
    }

    public void computeMainStateJacobian(double t, double[] y, double[] yDot, double[][] dFdY) {

        // compute the Jacobian of the main state
        dFdY[0][0] = 0;
        dFdY[0][1] = -omega;
        dFdY[1][0] = omega;
        dFdY[1][1] = 0;

        // precompute the derivatives with respect to the parameters,
        // they will be provided back when computeParameterJacobian are called later on
        savedDfDp[0][0] = 0;
        savedDfDp[0][1] = omega;
        savedDfDp[0][2] = c[1] - y[1];
        savedDfDp[1][0] = -omega;
        savedDfDp[1][1] = 0;
        savedDfDp[1][2] = y[0] - c[0];

    }

    public void computeParameterJacobian(double t, double[] y, double[] yDot,
                                         String paramName, double[] dFdP) {
        // we simply return the derivatives precomputed earlier
        if (CENTER_X.equals(paramName)) {
            dFdP[0] = savedDfDp[0][0];
            dFdP[1] = savedDfDp[1][0];
        } else if (CENTER_Y.equals(paramName)) {
            dFdP[0] = savedDfDp[0][1];
            dFdP[1] = savedDfDp[1][1];
        } else {
            dFdP[0] = savedDfDp[0][2];
            dFdP[1] = savedDfDp[1][2];
        }
     }

}
        </source>
        <p>
          This ODE is integrated as follows:
        </p>
        <source>
        CircleODE circle = new CircleODE(new double[] {1.0,  1.0 }, 0.1);

        // here, we could select only a subset of the parameters, or use another order
        JacobianMatrices jm = new JacobianMatrices(circle, CircleODE.CENTER_X, CircleODE.CENTER_Y, CircleODE.OMEGA);
        jm.addParameterJacobianProvider(circle);

        ExpandableStatefulODE efode = new ExpandableStatefulODE(circle);
        efode.setTime(0);
        double[] y = { 1.0, 0.0 };
        efode.setPrimaryState(y);

        // create the variational equations and append them to the main equations, as secondary equations
        jm.registerVariationalEquations(efode);

        // integrate the compound state, with both main and additional equations
        DormandPrince853Integrator integrator = new DormandPrince853Integrator(1.0e-6, 1.0e3, 1.0e-10, 1.0e-12);
        integrator.setMaxEvaluations(5000);
        integrator.integrate(efode, 20.0);

        // retrieve the Jacobian of the final state with respect to initial state
        double[][] dYdY0 = new double[2][2];
        jm.getCurrentMainSetJacobian(dYdY0);

        // retrieve the Jacobians of the final state with resepct to the various parameters
        double[]   dYdCx = new double[2];
        double[]   dYdCy = new double[2];
        double[]   dYdOm = new double[2];
        jm.getCurrentParameterJacobian(CircleODE.CENTER_X, dYdCx);
        jm.getCurrentParameterJacobian(CircleODE.CENTER_Y, dYdCy);
        jm.getCurrentParameterJacobian(CircleODE.OMEGA,    dYdOm);
        </source>
      </subsection>
     </section>
  </body>
</document>
