org.apache.commons.math3.ode.nonstiff

## Class AdamsNordsieckTransformer

- java.lang.Object
- - org.apache.commons.math3.ode.nonstiff.AdamsNordsieckTransformer

-     public class AdamsNordsieckTransformer
      extends java.lang.Object

  Transformer to Nordsieck vectors for Adams integrators.

  This class is used by `Adams-Bashforth` and `Adams-Moulton` integrators to convert between classical representation with several previous first derivatives and Nordsieck representation with higher order scaled derivatives.

  We define scaled derivatives si(n) at step n as:

       s1(n) = h y'n for first derivative
       s2(n) = h2/2 y''n for second derivative
       s3(n) = h3/6 y'''n for third derivative
       ...
       sk(n) = hk/k! y(k)n for kth derivative

  With the previous definition, the classical representation of multistep methods uses first derivatives only, i.e. it handles yn, s1(n) and qn where qn is defined as:

         qn = [ s1(n-1) s1(n-2) ... s1(n-(k-1)) ]T

  (we omit the k index in the notation for clarity).

  Another possible representation uses the Nordsieck vector with higher degrees scaled derivatives all taken at the same step, i.e it handles yn, s1(n) and rn) where rn is defined as:

       rn = [ s2(n), s3(n) ... sk(n) ]T

  (here again we omit the k index in the notation for clarity)

  Taylor series formulas show that for any index offset i, s1(n-i) can be computed from s1(n), s2(n) ... sk(n), the formula being exact for degree k polynomials.

       s1(n-i) = s1(n) + ∑j>1 j (-i)j-1 sj(n)

  The previous formula can be used with several values for i to compute the transform between classical representation and Nordsieck vector at step end. The transform between rn and qn resulting from the Taylor series formulas above is:

       qn = s1(n) u + P rn

  where u is the [ 1 1 ... 1 ]T vector and P is the (k-1)×(k-1) matrix built with the j (-i)j-1 terms:

              [  -2   3   -4    5  ... ]
              [  -4  12  -32   80  ... ]
         P =  [  -6  27 -108  405  ... ]
              [  -8  48 -256 1280  ... ]
              [          ...           ]

  Changing -i into +i in the formula above can be used to compute a similar transform between classical representation and Nordsieck vector at step start. The resulting matrix is simply the absolute value of matrix P.

  For `Adams-Bashforth` method, the Nordsieck vector at step n+1 is computed from the Nordsieck vector at step n as follows:

  - yn+1 = yn + s1(n) + uT rn
  - s1(n+1) = h f(tn+1, yn+1)
  - rn+1 = (s1(n) - s1(n+1)) P-1 u + P-1 A P rn
  where A is a rows shifting matrix (the lower left part is an identity matrix):

              [ 0 0   ...  0 0 | 0 ]
              [ ---------------+---]
              [ 1 0   ...  0 0 | 0 ]
          A = [ 0 1   ...  0 0 | 0 ]
              [       ...      | 0 ]
              [ 0 0   ...  1 0 | 0 ]
              [ 0 0   ...  0 1 | 0 ]

  For `Adams-Moulton` method, the predicted Nordsieck vector at step n+1 is computed from the Nordsieck vector at step n as follows:

  - Yn+1 = yn + s1(n) + uT rn
  - S1(n+1) = h f(tn+1, Yn+1)
  - Rn+1 = (s1(n) - s1(n+1)) P-1 u + P-1 A P rn
  From this predicted vector, the corrected vector is computed as follows:
  - yn+1 = yn + S1(n+1) + [ -1 +1 -1 +1 ... ±1 ] rn+1
  - s1(n+1) = h f(tn+1, yn+1)
  - rn+1 = Rn+1 + (s1(n+1) - S1(n+1)) P-1 u
  where the upper case Yn+1, S1(n+1) and Rn+1 represent the predicted states whereas the lower case yn+1, sn+1 and rn+1 represent the corrected states.

  We observe that both methods use similar update formulas. In both cases a P-1u vector and a P-1 A P matrix are used that do not depend on the state, they only depend on k. This class handles these transformations.

  Since:
    2.0
  Version:
    $Id: AdamsNordsieckTransformer.java 1416643 2012-12-03 19:37:14Z tn $

- - ### Field Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `private double[]` | `c1` Update coefficients of the higher order derivatives wrt y'.
    `private static java.util.Map<java.lang.Integer,AdamsNordsieckTransformer>` | `CACHE` Cache for already computed coefficients.
    `private Array2DRowRealMatrix` | `update` Update matrix for the higher order derivatives h2/2y'', h3/6 y''' ...

  - ### Constructor Summary

    Constructors
    Modifier | Constructor and Description
    --- | ---
    `private` | `AdamsNordsieckTransformer(int nSteps)` Simple constructor.

  - ### Method Summary

    Methods
    Modifier and Type | Method and Description
    --- | ---
    `private FieldMatrix<BigFraction>` | `buildP(int nSteps)` Build the P matrix.
    `static AdamsNordsieckTransformer` | `getInstance(int nSteps)` Get the Nordsieck transformer for a given number of steps.
    `int` | `getNSteps()` Get the number of steps of the method (excluding the one being computed).
    `Array2DRowRealMatrix` | `initializeHighOrderDerivatives(double h, double[] t, double[][] y, double[][] yDot)` Initialize the high order scaled derivatives at step start.
    `Array2DRowRealMatrix` | `updateHighOrderDerivativesPhase1(Array2DRowRealMatrix highOrder)` Update the high order scaled derivatives for Adams integrators (phase 1).
    `void` | `updateHighOrderDerivativesPhase2(double[] start, double[] end, Array2DRowRealMatrix highOrder)` Update the high order scaled derivatives Adams integrators (phase 2).

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Field Detail

    - #### CACHE

          private static final java.util.Map<java.lang.Integer,AdamsNordsieckTransformer> CACHE

      Cache for already computed coefficients.

    - #### update

          private final Array2DRowRealMatrix update

      Update matrix for the higher order derivatives h2/2y'', h3/6 y''' ...

    - #### c1

          private final double[] c1

      Update coefficients of the higher order derivatives wrt y'.

  - ### Constructor Detail

    - #### AdamsNordsieckTransformer

          private AdamsNordsieckTransformer(int nSteps)

      Simple constructor.
      Parameters:
        `nSteps` - number of steps of the multistep method (excluding the one being computed)

  - ### Method Detail

    - #### getInstance

          public static AdamsNordsieckTransformer getInstance(int nSteps)

      Get the Nordsieck transformer for a given number of steps.
      Parameters:
        `nSteps` - number of steps of the multistep method (excluding the one being computed)
      Returns:
        Nordsieck transformer for the specified number of steps

    - #### getNSteps

          public int getNSteps()

      Get the number of steps of the method (excluding the one being computed).
      Returns:
        number of steps of the method (excluding the one being computed)

    - #### buildP

          private FieldMatrix<BigFraction> buildP(int nSteps)

      Build the P matrix.

      The P matrix general terms are shifted j (-i)j-1 terms:

                  [  -2   3   -4    5  ... ]
                  [  -4  12  -32   80  ... ]
             P =  [  -6  27 -108  405  ... ]
                  [  -8  48 -256 1280  ... ]
                  [          ...           ]

      Parameters:
        `nSteps` - number of steps of the multistep method (excluding the one being computed)
      Returns:
        P matrix

    - #### initializeHighOrderDerivatives

          public Array2DRowRealMatrix initializeHighOrderDerivatives(double h,
                                                            double[] t,
                                                            double[][] y,
                                                            double[][] yDot)

      Initialize the high order scaled derivatives at step start.
      Parameters:
        `h` - step size to use for scaling
        `t` - first steps times
        `y` - first steps states
        `yDot` - first steps derivatives
      Returns:
        Nordieck vector at first step (h2/2 y''n, h3/6 y'''n ... hk/k! y(k)n)

    - #### updateHighOrderDerivativesPhase1

          public Array2DRowRealMatrix updateHighOrderDerivativesPhase1(Array2DRowRealMatrix highOrder)

      Update the high order scaled derivatives for Adams integrators (phase 1).

      The complete update of high order derivatives has a form similar to:

           rn+1 = (s1(n) - s1(n+1)) P-1 u + P-1 A P rn

      this method computes the P-1 A P rn part.
      Parameters:
        `highOrder` - high order scaled derivatives (h2/2 y'', ... hk/k! y(k))
      Returns:
        updated high order derivatives
      See Also:
        `updateHighOrderDerivativesPhase2(double[], double[], Array2DRowRealMatrix)`

    - #### updateHighOrderDerivativesPhase2

          public void updateHighOrderDerivativesPhase2(double[] start,
                                              double[] end,
                                              Array2DRowRealMatrix highOrder)

      Update the high order scaled derivatives Adams integrators (phase 2).

      The complete update of high order derivatives has a form similar to:

           rn+1 = (s1(n) - s1(n+1)) P-1 u + P-1 A P rn

      this method computes the (s1(n) - s1(n+1)) P-1 u part.

      Phase 1 of the update must already have been performed.

      Parameters:
        `start` - first order scaled derivatives at step start
        `end` - first order scaled derivatives at step end
        `highOrder` - high order scaled derivatives, will be modified (h2/2 y'', ... hk/k! y(k))
      See Also:
        `updateHighOrderDerivativesPhase1(Array2DRowRealMatrix)`

Copyright (c) 2003-2013 Apache Software Foundation