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 3/8 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/8) [ (1 - 7 theta + 8 theta^2) y'_1
31   *                                      + 3 (1 +   theta - 4 theta^2) y'_2
32   *                                      + 3 (1 +   theta)             y'_3
33   *                                      +   (1 +   theta + 4 theta^2) y'_4
34   *                                        ]
35   * </pre>
36   *
37   * where theta belongs to [0 ; 1] and where y'_1 to y'_4 are the four
38   * evaluations of the derivatives already computed during the
39   * step.</p>
40   *
41   * @see ThreeEighthesIntegrator
42   * @version $Revision: 620312 $ $Date: 2008-02-10 12:28:59 -0700 (Sun, 10 Feb 2008) $
43   * @since 1.2
44   */
45  
46  class ThreeEighthesStepInterpolator
47    extends RungeKuttaStepInterpolator {
48      
49    /** Simple constructor.
50     * This constructor builds an instance that is not usable yet, the
51     * {@link AbstractStepInterpolator#reinitialize} method should be called
52     * before using the instance in order to initialize the internal arrays. This
53     * constructor is used only in order to delay the initialization in
54     * some cases. The {@link RungeKuttaIntegrator} class uses the
55     * prototyping design pattern to create the step interpolators by
56     * cloning an uninitialized model and latter initializing the copy.
57     */
58    public ThreeEighthesStepInterpolator() {
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 ThreeEighthesStepInterpolator(ThreeEighthesStepInterpolator 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 ThreeEighthesStepInterpolator(this);
75    }
76  
77  
78    /** Compute the state at the interpolated time.
79     * This is the main processing method that should be implemented by
80     * the derived classes to perform the interpolation.
81     * @param theta normalized interpolation abscissa within the step
82     * (theta is zero at the previous time step and one at the current time step)
83     * @param oneMinusThetaH time gap between the interpolated time and
84     * the current time
85     * @throws DerivativeException this exception is propagated to the caller if the
86     * underlying user function triggers one
87     */
88    protected void computeInterpolatedState(double theta,
89                                            double oneMinusThetaH)
90      throws DerivativeException {
91  
92      double fourTheta2 = 4 * theta * theta;
93      double s          = oneMinusThetaH / 8.0;
94      double coeff1     = s * (1 - 7 * theta + 2 * fourTheta2);
95      double coeff2     = 3 * s * (1 + theta - fourTheta2);
96      double coeff3     = 3 * s * (1 + theta);
97      double coeff4     = s * (1 + theta + fourTheta2);
98  
99      for (int i = 0; i < interpolatedState.length; ++i) {
100       interpolatedState[i] = currentState[i] -
101                              coeff1 * yDotK[0][i] - coeff2 * yDotK[1][i] -
102                              coeff3 * yDotK[2][i] - coeff4 * yDotK[3][i];
103      }
104 
105   }
106 
107   /** Serializable version identifier */
108   private static final long serialVersionUID = -3345024435978721931L;
109 
110 }