DormandPrince54StateInterpolator.java

  1. /*
  2.  * Licensed to the Hipparchus project under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The Hipparchus project licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      https://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */

  17. package org.hipparchus.ode.nonstiff.interpolators;

  18. import org.hipparchus.ode.EquationsMapper;
  19. import org.hipparchus.ode.ODEStateAndDerivative;
  20. import org.hipparchus.ode.nonstiff.DormandPrince54Integrator;

  21. /**
  22.  * This class represents an interpolator over the last step during an
  23.  * ODE integration for the 5(4) Dormand-Prince integrator.
  24.  *
  25.  * @see DormandPrince54Integrator
  26.  *
  27.  */

  28. public class DormandPrince54StateInterpolator extends RungeKuttaStateInterpolator {

  29.     /** Last row of the Butcher-array internal weights, element 0. */
  30.     private static final double A70 =    35.0 /  384.0;

  31.     // element 1 is zero, so it is neither stored nor used

  32.     /** Last row of the Butcher-array internal weights, element 2. */
  33.     private static final double A72 =   500.0 / 1113.0;

  34.     /** Last row of the Butcher-array internal weights, element 3. */
  35.     private static final double A73 =   125.0 /  192.0;

  36.     /** Last row of the Butcher-array internal weights, element 4. */
  37.     private static final double A74 = -2187.0 / 6784.0;

  38.     /** Last row of the Butcher-array internal weights, element 5. */
  39.     private static final double A75 =    11.0 /   84.0;

  40.     /** Shampine (1986) Dense output, element 0. */
  41.     private static final double D0 =  -12715105075.0 /  11282082432.0;

  42.     // element 1 is zero, so it is neither stored nor used

  43.     /** Shampine (1986) Dense output, element 2. */
  44.     private static final double D2 =   87487479700.0 /  32700410799.0;

  45.     /** Shampine (1986) Dense output, element 3. */
  46.     private static final double D3 =  -10690763975.0 /   1880347072.0;

  47.     /** Shampine (1986) Dense output, element 4. */
  48.     private static final double D4 =  701980252875.0 / 199316789632.0;

  49.     /** Shampine (1986) Dense output, element 5. */
  50.     private static final double D5 =   -1453857185.0 /    822651844.0;

  51.     /** Shampine (1986) Dense output, element 6. */
  52.     private static final double D6 =      69997945.0 /     29380423.0;

  53.     /** Serializable version identifier. */
  54.     private static final long serialVersionUID = 20160328L;

  55.     /** Simple constructor.
  56.      * @param forward integration direction indicator
  57.      * @param yDotK slopes at the intermediate points
  58.      * @param globalPreviousState start of the global step
  59.      * @param globalCurrentState end of the global step
  60.      * @param softPreviousState start of the restricted step
  61.      * @param softCurrentState end of the restricted step
  62.      * @param mapper equations mapper for the all equations
  63.      */
  64.     public DormandPrince54StateInterpolator(final boolean forward,
  65.                                      final double[][] yDotK,
  66.                                      final ODEStateAndDerivative globalPreviousState,
  67.                                      final ODEStateAndDerivative globalCurrentState,
  68.                                      final ODEStateAndDerivative softPreviousState,
  69.                                      final ODEStateAndDerivative softCurrentState,
  70.                                      final EquationsMapper mapper) {
  71.         super(forward, yDotK, globalPreviousState, globalCurrentState, softPreviousState, softCurrentState, mapper);
  72.     }

  73.     /** {@inheritDoc} */
  74.     @Override
  75.     protected DormandPrince54StateInterpolator create(final boolean newForward, final double[][] newYDotK,
  76.                                                       final ODEStateAndDerivative newGlobalPreviousState,
  77.                                                       final ODEStateAndDerivative newGlobalCurrentState,
  78.                                                       final ODEStateAndDerivative newSoftPreviousState,
  79.                                                       final ODEStateAndDerivative newSoftCurrentState,
  80.                                                       final EquationsMapper newMapper) {
  81.         return new DormandPrince54StateInterpolator(newForward, newYDotK,
  82.                                                     newGlobalPreviousState, newGlobalCurrentState,
  83.                                                     newSoftPreviousState, newSoftCurrentState,
  84.                                                     newMapper);
  85.     }

  86.     /** {@inheritDoc} */
  87.     @Override
  88.     protected ODEStateAndDerivative computeInterpolatedStateAndDerivatives(final EquationsMapper mapper,
  89.                                                                            final double time, final double theta,
  90.                                                                            final double thetaH, final double oneMinusThetaH) {

  91.         // interpolate
  92.         final double eta = 1 - theta;
  93.         final double twoTheta = 2 * theta;
  94.         final double dot2 = 1 - twoTheta;
  95.         final double dot3 = theta * (2 - 3 * theta);
  96.         final double dot4 = twoTheta * (1 + theta * (twoTheta - 3));

  97.         final double[] interpolatedState;
  98.         final double[] interpolatedDerivatives;
  99.         if (getGlobalPreviousState() != null && theta <= 0.5) {
  100.             final double f1        = thetaH;
  101.             final double f2        = f1 * eta;
  102.             final double f3        = f2 * theta;
  103.             final double f4        = f3 * eta;
  104.             final double coeff0    = f1 * A70 - f2   * (A70 - 1) + f3   * (2 * A70 - 1) + f4   * D0;
  105.             final double coeff1    = 0;
  106.             final double coeff2    = f1 * A72 - f2   * A72       + f3   * (2 * A72)     + f4   * D2;
  107.             final double coeff3    = f1 * A73 - f2   * A73       + f3   * (2 * A73)     + f4   * D3;
  108.             final double coeff4    = f1 * A74 - f2   * A74       + f3   * (2 * A74)     + f4   * D4;
  109.             final double coeff5    = f1 * A75 - f2   * A75       + f3   * (2 * A75)     + f4   * D5;
  110.             final double coeff6    = f4 * D6 - f3;
  111.             final double coeffDot0 =      A70 - dot2 * (A70 - 1) + dot3 * (2 * A70 - 1) + dot4 * D0;
  112.             final double coeffDot1 = 0;
  113.             final double coeffDot2 =      A72 - dot2 * A72       + dot3 * (2 * A72)     + dot4 * D2;
  114.             final double coeffDot3 =      A73 - dot2 * A73       + dot3 * (2 * A73)     + dot4 * D3;
  115.             final double coeffDot4 =      A74 - dot2 * A74       + dot3 * (2 * A74)     + dot4 * D4;
  116.             final double coeffDot5 =      A75 - dot2 * A75       + dot3 * (2 * A75)     + dot4 * D5;
  117.             final double coeffDot6 = dot4 * D6 - dot3;
  118.             interpolatedState       = previousStateLinearCombination(coeff0, coeff1, coeff2, coeff3,
  119.                                                                      coeff4, coeff5, coeff6);
  120.             interpolatedDerivatives = derivativeLinearCombination(coeffDot0, coeffDot1, coeffDot2, coeffDot3,
  121.                                                                   coeffDot4, coeffDot5, coeffDot6);
  122.         } else {
  123.             final double f1        = -oneMinusThetaH;
  124.             final double f2        = oneMinusThetaH * theta;
  125.             final double f3        = f2 * theta;
  126.             final double f4        = f3 * eta;
  127.             final double coeff0    = f1 * A70 - f2   * (A70 - 1) + f3   * (2 * A70 - 1) + f4   * D0;
  128.             final double coeff1    = 0;
  129.             final double coeff2    = f1 * A72 - f2   * A72       + f3   * (2 * A72)     + f4   * D2;
  130.             final double coeff3    = f1 * A73 - f2   * A73       + f3   * (2 * A73)     + f4   * D3;
  131.             final double coeff4    = f1 * A74 - f2   * A74       + f3   * (2 * A74)     + f4   * D4;
  132.             final double coeff5    = f1 * A75 - f2   * A75       + f3   * (2 * A75)     + f4   * D5;
  133.             final double coeff6    = f4 * D6 - f3;
  134.             final double coeffDot0 =      A70 - dot2 * (A70 - 1) + dot3 * (2 * A70 - 1) + dot4 * D0;
  135.             final double coeffDot1 = 0;
  136.             final double coeffDot2 =      A72 - dot2 * A72       + dot3 * (2 * A72)     + dot4 * D2;
  137.             final double coeffDot3 =      A73 - dot2 * A73       + dot3 * (2 * A73)     + dot4 * D3;
  138.             final double coeffDot4 =      A74 - dot2 * A74       + dot3 * (2 * A74)     + dot4 * D4;
  139.             final double coeffDot5 =      A75 - dot2 * A75       + dot3 * (2 * A75)     + dot4 * D5;
  140.             final double coeffDot6 = dot4 * D6 - dot3;
  141.             interpolatedState       = currentStateLinearCombination(coeff0, coeff1, coeff2, coeff3,
  142.                                                                     coeff4, coeff5, coeff6);
  143.             interpolatedDerivatives = derivativeLinearCombination(coeffDot0, coeffDot1, coeffDot2, coeffDot3,
  144.                                                                   coeffDot4, coeffDot5, coeffDot6);
  145.         }

  146.         return mapper.mapStateAndDerivative(time, interpolatedState, interpolatedDerivatives);

  147.     }

  148. }