<?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.
  -->
  
<?xml-stylesheet type="text/xsl" href="./xdoc.xsl"?>
<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>
