View Javadoc
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  
18  package org.hipparchus.ode.nonstiff;
19  
20  import org.hipparchus.ode.EquationsMapper;
21  import org.hipparchus.ode.ODEStateAndDerivative;
22  
23  /**
24   * This class represents an interpolator over the last step during an
25   * ODE integration for the 5(4) Dormand-Prince integrator.
26   *
27   * @see DormandPrince54Integrator
28   *
29   */
30  
31  class DormandPrince54StateInterpolator
32      extends RungeKuttaStateInterpolator {
33  
34      /** Last row of the Butcher-array internal weights, element 0. */
35      private static final double A70 =    35.0 /  384.0;
36  
37      // element 1 is zero, so it is neither stored nor used
38  
39      /** Last row of the Butcher-array internal weights, element 2. */
40      private static final double A72 =   500.0 / 1113.0;
41  
42      /** Last row of the Butcher-array internal weights, element 3. */
43      private static final double A73 =   125.0 /  192.0;
44  
45      /** Last row of the Butcher-array internal weights, element 4. */
46      private static final double A74 = -2187.0 / 6784.0;
47  
48      /** Last row of the Butcher-array internal weights, element 5. */
49      private static final double A75 =    11.0 /   84.0;
50  
51      /** Shampine (1986) Dense output, element 0. */
52      private static final double D0 =  -12715105075.0 /  11282082432.0;
53  
54      // element 1 is zero, so it is neither stored nor used
55  
56      /** Shampine (1986) Dense output, element 2. */
57      private static final double D2 =   87487479700.0 /  32700410799.0;
58  
59      /** Shampine (1986) Dense output, element 3. */
60      private static final double D3 =  -10690763975.0 /   1880347072.0;
61  
62      /** Shampine (1986) Dense output, element 4. */
63      private static final double D4 =  701980252875.0 / 199316789632.0;
64  
65      /** Shampine (1986) Dense output, element 5. */
66      private static final double D5 =   -1453857185.0 /    822651844.0;
67  
68      /** Shampine (1986) Dense output, element 6. */
69      private static final double D6 =      69997945.0 /     29380423.0;
70  
71      /** Serializable version identifier. */
72      private static final long serialVersionUID = 20160328L;
73  
74      /** Simple constructor.
75       * @param forward integration direction indicator
76       * @param yDotK slopes at the intermediate points
77       * @param globalPreviousState start of the global step
78       * @param globalCurrentState end of the global step
79       * @param softPreviousState start of the restricted step
80       * @param softCurrentState end of the restricted step
81       * @param mapper equations mapper for the all equations
82       */
83      DormandPrince54StateInterpolator(final boolean forward,
84                                       final double[][] yDotK,
85                                       final ODEStateAndDerivative globalPreviousState,
86                                       final ODEStateAndDerivative globalCurrentState,
87                                       final ODEStateAndDerivative softPreviousState,
88                                       final ODEStateAndDerivative softCurrentState,
89                                       final EquationsMapper mapper) {
90          super(forward, yDotK,
91                globalPreviousState, globalCurrentState, softPreviousState, softCurrentState,
92                mapper);
93      }
94  
95      /** {@inheritDoc} */
96      @Override
97      protected DormandPrince54StateInterpolator create(final boolean newForward, final double[][] newYDotK,
98                                                        final ODEStateAndDerivative newGlobalPreviousState,
99                                                        final ODEStateAndDerivative newGlobalCurrentState,
100                                                       final ODEStateAndDerivative newSoftPreviousState,
101                                                       final ODEStateAndDerivative newSoftCurrentState,
102                                                       final EquationsMapper newMapper) {
103         return new DormandPrince54StateInterpolator(newForward, newYDotK,
104                                                     newGlobalPreviousState, newGlobalCurrentState,
105                                                     newSoftPreviousState, newSoftCurrentState,
106                                                     newMapper);
107     }
108 
109     /** {@inheritDoc} */
110     @Override
111     protected ODEStateAndDerivative computeInterpolatedStateAndDerivatives(final EquationsMapper mapper,
112                                                                            final double time, final double theta,
113                                                                            final double thetaH, final double oneMinusThetaH) {
114 
115         // interpolate
116         final double eta = 1 - theta;
117         final double twoTheta = 2 * theta;
118         final double dot2 = 1 - twoTheta;
119         final double dot3 = theta * (2 - 3 * theta);
120         final double dot4 = twoTheta * (1 + theta * (twoTheta - 3));
121 
122         final double[] interpolatedState;
123         final double[] interpolatedDerivatives;
124         if (getGlobalPreviousState() != null && theta <= 0.5) {
125             final double f1        = thetaH;
126             final double f2        = f1 * eta;
127             final double f3        = f2 * theta;
128             final double f4        = f3 * eta;
129             final double coeff0    = f1 * A70 - f2   * (A70 - 1) + f3   * (2 * A70 - 1) + f4   * D0;
130             final double coeff1    = 0;
131             final double coeff2    = f1 * A72 - f2   * A72       + f3   * (2 * A72)     + f4   * D2;
132             final double coeff3    = f1 * A73 - f2   * A73       + f3   * (2 * A73)     + f4   * D3;
133             final double coeff4    = f1 * A74 - f2   * A74       + f3   * (2 * A74)     + f4   * D4;
134             final double coeff5    = f1 * A75 - f2   * A75       + f3   * (2 * A75)     + f4   * D5;
135             final double coeff6    = f4 * D6 - f3;
136             final double coeffDot0 =      A70 - dot2 * (A70 - 1) + dot3 * (2 * A70 - 1) + dot4 * D0;
137             final double coeffDot1 = 0;
138             final double coeffDot2 =      A72 - dot2 * A72       + dot3 * (2 * A72)     + dot4 * D2;
139             final double coeffDot3 =      A73 - dot2 * A73       + dot3 * (2 * A73)     + dot4 * D3;
140             final double coeffDot4 =      A74 - dot2 * A74       + dot3 * (2 * A74)     + dot4 * D4;
141             final double coeffDot5 =      A75 - dot2 * A75       + dot3 * (2 * A75)     + dot4 * D5;
142             final double coeffDot6 = dot4 * D6 - dot3;
143             interpolatedState       = previousStateLinearCombination(coeff0, coeff1, coeff2, coeff3,
144                                                                      coeff4, coeff5, coeff6);
145             interpolatedDerivatives = derivativeLinearCombination(coeffDot0, coeffDot1, coeffDot2, coeffDot3,
146                                                                   coeffDot4, coeffDot5, coeffDot6);
147         } else {
148             final double f1        = -oneMinusThetaH;
149             final double f2        = oneMinusThetaH * theta;
150             final double f3        = f2 * theta;
151             final double f4        = f3 * eta;
152             final double coeff0    = f1 * A70 - f2   * (A70 - 1) + f3   * (2 * A70 - 1) + f4   * D0;
153             final double coeff1    = 0;
154             final double coeff2    = f1 * A72 - f2   * A72       + f3   * (2 * A72)     + f4   * D2;
155             final double coeff3    = f1 * A73 - f2   * A73       + f3   * (2 * A73)     + f4   * D3;
156             final double coeff4    = f1 * A74 - f2   * A74       + f3   * (2 * A74)     + f4   * D4;
157             final double coeff5    = f1 * A75 - f2   * A75       + f3   * (2 * A75)     + f4   * D5;
158             final double coeff6    = f4 * D6 - f3;
159             final double coeffDot0 =      A70 - dot2 * (A70 - 1) + dot3 * (2 * A70 - 1) + dot4 * D0;
160             final double coeffDot1 = 0;
161             final double coeffDot2 =      A72 - dot2 * A72       + dot3 * (2 * A72)     + dot4 * D2;
162             final double coeffDot3 =      A73 - dot2 * A73       + dot3 * (2 * A73)     + dot4 * D3;
163             final double coeffDot4 =      A74 - dot2 * A74       + dot3 * (2 * A74)     + dot4 * D4;
164             final double coeffDot5 =      A75 - dot2 * A75       + dot3 * (2 * A75)     + dot4 * D5;
165             final double coeffDot6 = dot4 * D6 - dot3;
166             interpolatedState       = currentStateLinearCombination(coeff0, coeff1, coeff2, coeff3,
167                                                                     coeff4, coeff5, coeff6);
168             interpolatedDerivatives = derivativeLinearCombination(coeffDot0, coeffDot1, coeffDot2, coeffDot3,
169                                                                   coeffDot4, coeffDot5, coeffDot6);
170         }
171 
172         return mapper.mapStateAndDerivative(time, interpolatedState, interpolatedDerivatives);
173 
174     }
175 
176 }