1
2
3
4
5
6
7
8
9
10
11 package nl.tudelft.simulation.jstats.ode;
12
13 import nl.tudelft.simulation.event.EventProducer;
14 import nl.tudelft.simulation.jstats.ode.integrators.NumericalIntegrator;
15
16 /***
17 * The DifferentialEquation is the abstract basis for
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 DifferentialEquation extends EventProducer implements
32 DifferentialEquationInterface
33 {
34
35 /***
36 * the integrator
37 *
38 * @uml.property name="integrator"
39 */
40 private NumericalIntegrator integrator = null;
41
42 /*** the initial value array */
43 protected double[] y0 = null;
44
45 /*** a timeStep */
46 protected double timeStep = Double.NaN;
47
48 /*** the first x value to start integration */
49 protected double x0 = Double.NaN;
50
51 /***
52 * constructs a new DifferentialEquation with default integrator.
53 *
54 * @param timeStep the timeStep to use.
55 */
56 public DifferentialEquation(final double timeStep)
57 {
58 this(timeStep, NumericalIntegrator.DEFAULT_INTEGRATOR);
59 }
60
61 /***
62 * constructs a new DifferentialEquation with a user-specified integrator.
63 *
64 * @param timeStep the timeStep to use.
65 * @param integrator the integrator to use.
66 */
67 public DifferentialEquation(final double timeStep,
68 final NumericalIntegrator integrator)
69 {
70 super();
71 this.timeStep = timeStep;
72 this.integrator = integrator;
73 }
74
75 /***
76 * constructs a new DifferentialEquation with a preselected integrator.
77 *
78 * @param timeStep the timeStep to use.
79 * @param integrationMethod the integrator to use.
80 */
81 public DifferentialEquation(final double timeStep,
82 final short integrationMethod)
83 {
84 super();
85 this.timeStep = timeStep;
86 this.integrator = NumericalIntegrator.resolve(integrationMethod,
87 timeStep, this);
88 }
89
90 /***
91 * @see nl.tudelft.simulation.jstats.ode.DifferentialEquationInterface#initialize(double,
92 * double[])
93 */
94 public void initialize(final double x, final double[] y)
95 {
96 this.x0 = x;
97 this.y0 = y;
98 }
99
100 /***
101 * @see nl.tudelft.simulation.jstats.ode.DifferentialEquationInterface#y(double)
102 */
103 public double[] y(final double x)
104 {
105
106 if (Double.isNaN(this.x0))
107 {
108 throw new RuntimeException("differential equation not initialized");
109 }
110
111 if (x < this.x0)
112 {
113 throw new RuntimeException("cannot compute values x<x0");
114 }
115 return this.integrateY(x, this.x0, this.y0);
116 }
117
118 /***
119 * integrates Y
120 *
121 * @param x the x-value
122 * @param initialX the initial X value
123 * @param initialY the initial Y value
124 * @return the new Y value
125 */
126 protected double[] integrateY(final double x, double initialX,
127 double[] initialY)
128 {
129
130 while (x > initialX + this.timeStep)
131 {
132 initialY = this.integrator.next(initialX, initialY);
133 initialX = initialX + this.timeStep;
134 }
135
136 double[] nextValue = this.integrator.next(initialX, initialY);
137 double ratio = (x - initialX) / this.timeStep;
138 for (int i = 0; i < initialY.length; i++)
139 {
140 initialY[i] = initialY[i] + ratio * (nextValue[i] - initialY[i]);
141 }
142 return initialY;
143 }
144
145 /***
146 * @return Returns the integrator.
147 *
148 * @uml.property name="integrator"
149 */
150 public NumericalIntegrator getIntegrator()
151 {
152 return this.integrator;
153 }
154
155 /***
156 * @param integrator The integrator to set.
157 *
158 * @uml.property name="integrator"
159 */
160 public void setIntegrator(final NumericalIntegrator integrator)
161 {
162 this.integrator = integrator;
163 }
164
165 }