View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) 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 ASF 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    *      http://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.apache.commons.math.ode;
19  
20  /**
21   * This class implements a step interpolator for the classical fourth
22   * order Runge-Kutta integrator.
23   *
24   * <p>This interpolator allows to compute dense output inside the last
25   * step computed. The interpolation equation is consistent with the
26   * integration scheme :
27  
28   * <pre>
29   *   y(t_n + theta h) = y (t_n + h)
30   *                    + (1 - theta) (h/6) [ (-4 theta^2 + 5 theta - 1) y'_1
31   *                                          +(4 theta^2 - 2 theta - 2) (y'_2 + y'_3)
32   *                                          -(4 theta^2 +   theta + 1) y'_4
33   *                                        ]
34   * </pre>
35   *
36   * where theta belongs to [0 ; 1] and where y'_1 to y'_4 are the four
37   * evaluations of the derivatives already computed during the
38   * step.</p>
39   *
40   * @see ClassicalRungeKuttaIntegrator
41   * @version $Revision: 620312 $ $Date: 2008-02-10 12:28:59 -0700 (Sun, 10 Feb 2008) $
42   * @since 1.2
43   */
44  
45  class ClassicalRungeKuttaStepInterpolator
46    extends RungeKuttaStepInterpolator {
47      
48    /** Simple constructor.
49     * This constructor builds an instance that is not usable yet, the
50     * {@link RungeKuttaStepInterpolator#reinitialize} method should be
51     * called before using the instance in order to initialize the
52     * internal arrays. This constructor is used only in order to delay
53     * the initialization in some cases. The {@link RungeKuttaIntegrator}
54     * class uses the prototyping design pattern to create the step
55     * interpolators by cloning an uninitialized model and latter initializing
56     * the copy.
57     */
58    public ClassicalRungeKuttaStepInterpolator() {
59    }
60  
61    /** Copy constructor.
62     * @param interpolator interpolator to copy from. The copy is a deep
63     * copy: its arrays are separated from the original arrays of the
64     * instance
65     */
66    public ClassicalRungeKuttaStepInterpolator(ClassicalRungeKuttaStepInterpolator interpolator) {
67      super(interpolator);
68    }
69  
70    /** Really copy the finalized instance.
71     * @return a copy of the finalized instance
72     */
73    protected StepInterpolator doCopy() {
74      return new ClassicalRungeKuttaStepInterpolator(this);
75    }
76  
77    /** Compute the state at the interpolated time.
78     * This is the main processing method that should be implemented by
79     * the derived classes to perform the interpolation.
80     * @param theta normalized interpolation abscissa within the step
81     * (theta is zero at the previous time step and one at the current time step)
82     * @param oneMinusThetaH time gap between the interpolated time and
83     * the current time
84     * @throws DerivativeException this exception is propagated to the caller if the
85     * underlying user function triggers one
86     */
87    protected void computeInterpolatedState(double theta,
88                                            double oneMinusThetaH)
89      throws DerivativeException {
90  
91      double fourTheta = 4 * theta;
92      double s         = oneMinusThetaH / 6.0;
93      double coeff1    = s * ((-fourTheta + 5) * theta - 1);
94      double coeff23   = s * (( fourTheta - 2) * theta - 2);
95      double coeff4    = s * ((-fourTheta - 1) * theta - 1);
96  
97      for (int i = 0; i < interpolatedState.length; ++i) {
98        interpolatedState[i] = currentState[i] +
99                               coeff1  * yDotK[0][i] +
100                              coeff23 * (yDotK[1][i] + yDotK[2][i]) +
101                              coeff4  * yDotK[3][i];
102      }
103 
104   }
105 
106   /** Serializable version identifier */
107   private static final long serialVersionUID = -6576285612589783992L;
108 
109 }