1
2
3
4
5
6
7
8
9
10
11 package nl.tudelft.simulation.jstats.ode.integrators;
12
13 import nl.tudelft.simulation.jstats.ode.DifferentialEquationInterface;
14
15 /***
16 * Provides basic methods for all numerical integration methods. They mostly
17 * include matrix computation.
18 * <p>
19 * (c) copyright 2003 <a href="http://www.simulation.tudelft.nl">Delft
20 * University of Technology </a>, the Netherlands. <br>
21 * See for project information <a
22 * href="http://www.simulation.tudelft.nl">www.simulation.tudelft.nl </a> <br>
23 * License of use: <a href="http://www.gnu.org/copyleft/gpl.html">General Public
24 * License (GPL) </a>, no warranty <br>
25 *
26 * @author <a href="http://www.tbm.tudelft.nl/webstaf/peterja/index.htm">Peter
27 * Jacobs </a>
28 * @version 1.2 Apr 20, 2004
29 * @since 1.4
30 */
31 public abstract class NumericalIntegrator
32 {
33 /*** Euler's integration */
34 public static final short EULER = 0;
35
36 /*** Heun's integration */
37 public static final short HEUN = 1;
38
39 /*** RungeKutta's (3rd level) integration */
40 public static final short RUNGEKUTTA3 = 2;
41
42 /*** RungeKutta's (4th level) integration */
43 public static final short RUNGEKUTTA4 = 3;
44
45 /*** Adam's integration */
46 public static final short ADAMS = 4;
47
48 /*** Gill's integration */
49 public static final short GILL = 5;
50
51 /*** Milne's integration */
52 public static final short MILNE = 6;
53
54 /*** Runge-Kutta-Fehlberg integration */
55 public static final short RUNGEKUTTAFEHLBERG = 7;
56
57 /*** Runge-Kutta-Cash-Carp integration */
58 public static final short RUNGEKUTTACASHCARP = 8;
59
60 /*** The default integrator */
61 public static final short DEFAULT_INTEGRATOR = NumericalIntegrator.RUNGEKUTTA4;
62
63 /***
64 * @param integrationMethod the type of integrator to create
65 * @param timeStep the starting timestep to use
66 * @param equation the differential equation
67 * @return the integrator
68 */
69 public static NumericalIntegrator resolve(final short integrationMethod,
70 final double timeStep, final DifferentialEquationInterface equation)
71 {
72 switch (integrationMethod)
73 {
74 case NumericalIntegrator.ADAMS :
75 return new Adams(timeStep, equation);
76 case NumericalIntegrator.EULER :
77 return new Euler(timeStep, equation);
78 case NumericalIntegrator.HEUN :
79 return new Heun(timeStep, equation);
80 case NumericalIntegrator.RUNGEKUTTA3 :
81 return new RungeKutta3(timeStep, equation);
82 case NumericalIntegrator.RUNGEKUTTA4 :
83 return new RungeKutta4(timeStep, equation);
84 case NumericalIntegrator.GILL :
85 return new Gill(timeStep, equation);
86 case NumericalIntegrator.MILNE :
87 return new Milne(timeStep, equation);
88 case NumericalIntegrator.RUNGEKUTTAFEHLBERG :
89 return new RungeKuttaFehlberg(timeStep, equation);
90 case NumericalIntegrator.RUNGEKUTTACASHCARP :
91 return new RungeKuttaCashCarp(timeStep, equation);
92 default :
93 throw new IllegalArgumentException("unknown integration method");
94 }
95 }
96
97 /*** the timeStep to use */
98 protected double timeStep = Double.NaN;
99
100 /*** the calculated error of the last step */
101 protected double[] error = null;
102
103 /*** the equation to integrate */
104 protected DifferentialEquationInterface equation = null;
105
106 /***
107 * constructs a new NumericalIntegrator
108 *
109 * @param timeStep the timeStep
110 * @param equation the differentialEquation
111 */
112 public NumericalIntegrator(final double timeStep,
113 final DifferentialEquationInterface equation)
114 {
115 this.timeStep = timeStep;
116 this.equation = equation;
117 }
118
119 /***
120 * computes the next value
121 *
122 * @param x the x value corresponding to the last y-value computed
123 * @param y the last y value
124 *
125 * @return the new value
126 */
127 public abstract double[] next(final double x, final double[] y);
128
129 /***
130 * multiplies a vector with a constant
131 *
132 * @param constant the constant
133 * @param vector the vector
134 * @return the new vector
135 */
136 protected double[] multiply(final double constant, final double[] vector)
137 {
138 double[] prod = new double[vector.length];
139 for (int i = 0; i < vector.length; i++)
140 {
141 prod[i] = constant * vector[i];
142 }
143 return prod;
144 }
145
146 /***
147 * adds two vectors
148 *
149 * @param a vector a
150 * @param b vector b
151 * @return the new vector
152 */
153 protected double[] add(final double[] a, final double[] b)
154 {
155 double[] sum = new double[a.length];
156 for (int i = 0; i < a.length; i++)
157 {
158 sum[i] = a[i] + b[i];
159 }
160 return sum;
161 }
162
163 /***
164 * adds a number of vectors
165 *
166 * @param a vector a
167 * @param b vector b
168 * @param c vector c
169 * @return the new vector
170 */
171 protected double[] add(final double[] a, final double[] b, final double[] c)
172 {
173 double[] sum = new double[a.length];
174 for (int i = 0; i < a.length; i++)
175 {
176 sum[i] = a[i] + b[i] + c[i];
177 }
178 return sum;
179 }
180
181 /***
182 * adds a number of vectors
183 *
184 * @param a vector a
185 * @param b vector b
186 * @param c vector c
187 * @param d vector d
188 * @return the sum
189 */
190 protected double[] add(final double[] a, final double[] b,
191 final double[] c, final double[] d)
192 {
193 double[] sum = new double[a.length];
194 for (int i = 0; i < a.length; i++)
195 {
196 sum[i] = a[i] + b[i] + c[i] + d[i];
197 }
198 return sum;
199 }
200
201 /***
202 * adds a number of vectors
203 *
204 * @param a vector a
205 * @param b vector b
206 * @param c vector c
207 * @param d vector d
208 * @param e vector e
209 * @return the sum
210 */
211 protected double[] add(final double[] a, final double[] b,
212 final double[] c, final double[] d, final double[] e)
213 {
214 double[] sum = new double[a.length];
215 for (int i = 0; i < a.length; i++)
216 {
217 sum[i] = a[i] + b[i] + c[i] + d[i] + e[i];
218 }
219 return sum;
220 }
221
222 /***
223 * adds a number of vectors
224 *
225 * @param a vector a
226 * @param b vector b
227 * @param c vector c
228 * @param d vector d
229 * @param e vector e
230 * @param f vector f
231 * @return the sum
232 */
233 protected double[] add(final double[] a, final double[] b,
234 final double[] c, final double[] d, final double[] e,
235 final double[] f)
236 {
237 double[] sum = new double[a.length];
238 for (int i = 0; i < a.length; i++)
239 {
240 sum[i] = a[i] + b[i] + c[i] + d[i] + e[i] + f[i];
241 }
242 return sum;
243 }
244
245 /***
246 * @return Returns the timeStep.
247 */
248 public double getTimeStep()
249 {
250 return this.timeStep;
251 }
252
253 /***
254 * @param timeStep The timeStep to set.
255 */
256 public void setTimeStep(final double timeStep)
257 {
258 this.timeStep = timeStep;
259 }
260
261 /***
262 * @return Returns the error.
263 */
264 public double[] getError()
265 {
266 return this.error;
267 }
268 }