View Javadoc

1   /*
2    * @(#) DifferentialEquation.java Apr 20, 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;
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 		//If the ODE is not initialized, the cache is empty.
106 		if (Double.isNaN(this.x0))
107 		{
108 			throw new RuntimeException("differential equation not initialized");
109 		}
110 		// x<initialX this is not supported.
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 		// we request the new value from the integrator.
130 		while (x > initialX + this.timeStep)
131 		{
132 			initialY = this.integrator.next(initialX, initialY);
133 			initialX = initialX + this.timeStep;
134 		}
135 		//We are in our final step.
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 }