View Javadoc

1   /*
2    * @(#) RungeKuttaFehlberg.java May 12, 2004
3    * 
4    * Copyright (c) 2003 Delft University of Technology Jaffalaan 5, 2628 BX Delft,
5    * the Netherlands All rights reserved.
6    * 
7    * This software is proprietary information of Delft University of Technology
8    * The code is published under the General Public License
9    */
10  
11  package nl.tudelft.simulation.jstats.ode.integrators;
12  
13  import nl.tudelft.simulation.jstats.ode.DifferentialEquationInterface;
14  
15  /***
16   * The RungeKuttaFehlberg.java numerical integrator.
17   * <p>
18   * (c) copyright 2004 <a href="http://www.simulation.tudelft.nl">Delft
19   * University of Technology </a>, the Netherlands. <br>
20   * See for project information <a
21   * href="http://www.simulation.tudelft.nl">www.simulation.tudelft.nl </a> <br>
22   * License of use: <a href="http://www.gnu.org/copyleft/gpl.html">General Public
23   * License (GPL) </a>, no warranty <br>
24   * 
25   * @author <a
26   *         href="http://www.tbm.tudelft.nl/webstaf/alexandv/index.htm">Alexander
27   *         Verbraeck </a>
28   * @version 1.0 May 12, 2004
29   * @since 1.4
30   */
31  public class RungeKuttaFehlberg extends NumericalIntegrator
32  {
33  	/*** the parameters for a_i, in f(x_n + a_i h, .) */
34  	protected static double[] a = new double[]{0d, 1d / 4d, 3d / 8d, 12d / 13d,
35  			1d, 1d / 2d};
36  
37  	/*** the parameters for b_ij, in f(., y_n + b_p1 k1 + bp2 k2 + ...) */
38  	protected static double[][] b = new double[][]{{0d, 0d, 0d, 0d, 0d},
39  			{1d / 4d, 3d / 32d, 1932d / 2197d, 439d / 216d, -8d / 27d},
40  			{0d, 9d / 32d, -7200d / 2197d, -8d, 2d},
41  			{0d, 0d, 7296d / 2197d, 3680d / 513d, -3544d / 2565d},
42  			{0d, 0d, 0d, -845d / 4104d, 1859d / 4104d},
43  			{0d, 0d, 0d, 0d, -11d / 40d}};
44  
45  	/*** the parameters for c_i, in y_n+1 = y_n + c_1 k_1 + c_2 k_2 + ... */
46  	protected static double[] c = new double[]{16d / 135d, 0d, 6656d / 12825d,
47  			28561d / 56430d, -9d / 50d, 2d / 55d};
48  
49  	/*** the parameters for c4_i, in y_n+1 = y_n + c4_1 k_1 + c4_2 k_2 + ... */
50  	protected static double[] c4 = new double[]{25d / 216d, 0d, 1408d / 2565d,
51  			2197d / 4104d, -1d / 5d, 0d};
52  
53  	/*** the numer of k-s in the method */
54  	protected static int nk = 6;
55  
56  	/***
57  	 * constructs a new RungeKuttaFehlberg
58  	 * 
59  	 * @param timeStep the timeStep
60  	 * @param equation the differentialEquation
61  	 */
62  	public RungeKuttaFehlberg(final double timeStep,
63  			final DifferentialEquationInterface equation)
64  	{
65  		super(timeStep, equation);
66  	}
67  
68  	/***
69  	 * @see nl.tudelft.simulation.jstats.ode.integrators.NumericalIntegrator
70  	 *      #next(double,double[])
71  	 */
72  	public double[] next(final double x, final double[] y)
73  	{
74  		double[][] k = new double[nk][];
75  		for (int i = 0; i < nk; i++)
76  		{
77  			double[] ysum = (double[]) y.clone();
78  			for (int j = 0; j < i; j++)
79  			{
80  				if (b[i][j] != 0.0)
81  				{
82  					ysum = this.add(ysum, this.multiply(b[i][j], k[j]));
83  				}
84  			}
85  			k[i] = this.multiply(this.timeStep, this.equation.dy(x + a[i]
86  					* this.timeStep, ysum));
87  		}
88  		double[] sum = (double[]) y.clone();
89  		super.error = new double[y.length];
90  		for (int i = 0; i < nk; i++)
91  		{
92  			sum = this.add(sum, this.multiply(c[i], k[i]));
93  			super.error = this.add(super.error, this.multiply(c[i] - c4[i],
94  					k[i]));
95  		}
96  		return sum;
97  	}
98  }