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.interpolators;
19  
20  import org.hipparchus.ode.EquationsMapper;
21  import org.hipparchus.ode.ODEStateAndDerivative;
22  import org.hipparchus.ode.nonstiff.MidpointIntegrator;
23  
24  /**
25   * This class implements a step interpolator for second order
26   * Runge-Kutta integrator.
27   *
28   * <p>This interpolator computes dense output inside the last
29   * step computed. The interpolation equation is consistent with the
30   * integration scheme :</p>
31   * <ul>
32   *   <li>Using reference point at step start:<br>
33   *   y(t<sub>n</sub> + &theta; h) = y (t<sub>n</sub>) + &theta; h [(1 - &theta;) y'<sub>1</sub> + &theta; y'<sub>2</sub>]
34   *   </li>
35   *   <li>Using reference point at step end:<br>
36   *   y(t<sub>n</sub> + &theta; h) = y (t<sub>n</sub> + h) + (1-&theta;) h [&theta; y'<sub>1</sub> - (1+&theta;) y'<sub>2</sub>]
37   *   </li>
38   * </ul>
39   *
40   * <p>where &theta; belongs to [0 ; 1] and where y'<sub>1</sub> and y'<sub>2</sub> are the two
41   * evaluations of the derivatives already computed during the
42   * step.</p>
43   *
44   * @see MidpointIntegrator
45   */
46  
47  public class MidpointStateInterpolator extends RungeKuttaStateInterpolator {
48  
49      /** Serializable version identifier. */
50      private static final long serialVersionUID = 20160328L;
51  
52      /** Simple constructor.
53       * @param forward integration direction indicator
54       * @param yDotK slopes at the intermediate points
55       * @param globalPreviousState start of the global step
56       * @param globalCurrentState end of the global step
57       * @param softPreviousState start of the restricted step
58       * @param softCurrentState end of the restricted step
59       * @param mapper equations mapper for the all equations
60       */
61      public MidpointStateInterpolator(final boolean forward,
62                                       final double[][] yDotK,
63                                       final ODEStateAndDerivative globalPreviousState,
64                                       final ODEStateAndDerivative globalCurrentState,
65                                       final ODEStateAndDerivative softPreviousState,
66                                       final ODEStateAndDerivative softCurrentState,
67                                       final EquationsMapper mapper) {
68          super(forward, yDotK, globalPreviousState, globalCurrentState, softPreviousState, softCurrentState, mapper);
69      }
70  
71      /** {@inheritDoc} */
72      @Override
73      protected MidpointStateInterpolator create(final boolean newForward, final double[][] newYDotK,
74                                                 final ODEStateAndDerivative newGlobalPreviousState,
75                                                 final ODEStateAndDerivative newGlobalCurrentState,
76                                                 final ODEStateAndDerivative newSoftPreviousState,
77                                                 final ODEStateAndDerivative newSoftCurrentState,
78                                                 final EquationsMapper newMapper) {
79          return new MidpointStateInterpolator(newForward, newYDotK,
80                                               newGlobalPreviousState, newGlobalCurrentState,
81                                               newSoftPreviousState, newSoftCurrentState,
82                                               newMapper);
83      }
84  
85      /** {@inheritDoc} */
86      @Override
87      protected ODEStateAndDerivative computeInterpolatedStateAndDerivatives(final EquationsMapper mapper,
88                                                                             final double time, final double theta,
89                                                                             final double thetaH, final double oneMinusThetaH) {
90          final double coeffDot2 = 2 * theta;
91          final double coeffDot1 = 1 - coeffDot2;
92  
93          final double[] interpolatedState;
94          final double[] interpolatedDerivatives;
95          if (getGlobalPreviousState() != null && theta <= 0.5) {
96  
97              final double coeff1     = theta * oneMinusThetaH;
98              final double coeff2     = theta * thetaH;
99              interpolatedState       = previousStateLinearCombination(coeff1, coeff2);
100             interpolatedDerivatives = derivativeLinearCombination(coeffDot1, coeffDot2);
101         } else {
102             final double coeff1     =  oneMinusThetaH * theta;
103             final double coeff2     = -oneMinusThetaH * (1.0 + theta);
104             interpolatedState       = currentStateLinearCombination(coeff1, coeff2);
105             interpolatedDerivatives = derivativeLinearCombination(coeffDot1, coeffDot2);
106         }
107 
108         return mapper.mapStateAndDerivative(time, interpolatedState, interpolatedDerivatives);
109 
110     }
111 
112 }