<?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="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/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="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/ode/FirstOrderDifferentialEquations.html">FirstOrderDifferentialEquations</a>
          interface (or  <a href="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/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="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/ode/FirstOrderIntegrator.html">FirstOrderIntegrator</a>
          interface (or the <a href="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/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="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/ode/sampling/StepHandler.html">StepHandler</a> interface or a
          <a href="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/ode/sampling/StepNormalizer.html">StepNormalizer</a> object wrapping
          a user-specified object implementing the
          <a href="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/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="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/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="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/ode/sampling/StepHandler.html">StepHandler</a>
          interface are available for general needs
          (<a href="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/ode/sampling/DummyStepHandler.html">DummyStepHandler</a>,
          <a href="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/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="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/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="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/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="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/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="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/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="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/ode/nonstiff/EulerIntegrator.html">Euler</a></td><td>1</td></tr>
          <tr><td><a href="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/ode/nonstiff/MidpointIntegrator.html">Midpoint</a></td><td>2</td></tr>
          <tr><td><a href="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/ode/nonstiff/ClassicalRungeKuttaIntegrator.html">Classical Runge-Kutta</a></td><td>4</td></tr>
          <tr><td><a href="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/ode/nonstiff/GillIntegrator.html">Gill</a></td><td>4</td></tr>
          <tr><td><a href="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/ode/nonstiff/ThreeEighthesIntegrator.html">3/8</a></td><td>4</td></tr>
          <tr><td><a href="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/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="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/ode/nonstiff/HighamHall54Integrator.html">Higham and Hall</a></td><td>5</td><td>4</td></tr>
          <tr><td><a href="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/ode/nonstiff/DormandPrince54Integrator.html">Dormand-Prince 5(4)</a></td><td>5</td><td>4</td></tr>
          <tr><td><a href="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/ode/nonstiff/DormandPrince853Integrator.html">Dormand-Prince 8(5,3)</a></td><td>8</td><td>5 and 3</td></tr>
          <tr><td><a href="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/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="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/ode/nonstiff/AdamsBashforthIntegrator.html">Adams-Bashforth</a></td><td>variable</td><td>variable</td></tr>
          <tr><td><a href="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/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="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/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="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/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="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/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="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/ode/FirstOrderDifferentialEquations.html">FirstOrderDifferentialEquations</a>
          interface only, the user should rather provide an implementation of the <a
          href="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/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="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/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="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/ode/FirstOrderDifferentialEquations.html">FirstOrderDifferentialEquations</a>
          interface and given as such to another constructor of the <a
          href="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/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="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/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="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/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>
