comparison libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/nonstiff/GraggBulirschStoerIntegrator.html @ 13:cbf34dd4d7e6

commons-math-2.1 added
author dwinter
date Tue, 04 Jan 2011 10:02:07 +0100
parents
children
comparison
equal deleted inserted replaced
12:970d26a94fb7 13:cbf34dd4d7e6
1 <HTML>
2 <BODY BGCOLOR="white">
3 <PRE>
4 <FONT color="green">001</FONT> /*<a name="line.1"></a>
5 <FONT color="green">002</FONT> * Licensed to the Apache Software Foundation (ASF) under one or more<a name="line.2"></a>
6 <FONT color="green">003</FONT> * contributor license agreements. See the NOTICE file distributed with<a name="line.3"></a>
7 <FONT color="green">004</FONT> * this work for additional information regarding copyright ownership.<a name="line.4"></a>
8 <FONT color="green">005</FONT> * The ASF licenses this file to You under the Apache License, Version 2.0<a name="line.5"></a>
9 <FONT color="green">006</FONT> * (the "License"); you may not use this file except in compliance with<a name="line.6"></a>
10 <FONT color="green">007</FONT> * the License. You may obtain a copy of the License at<a name="line.7"></a>
11 <FONT color="green">008</FONT> *<a name="line.8"></a>
12 <FONT color="green">009</FONT> * http://www.apache.org/licenses/LICENSE-2.0<a name="line.9"></a>
13 <FONT color="green">010</FONT> *<a name="line.10"></a>
14 <FONT color="green">011</FONT> * Unless required by applicable law or agreed to in writing, software<a name="line.11"></a>
15 <FONT color="green">012</FONT> * distributed under the License is distributed on an "AS IS" BASIS,<a name="line.12"></a>
16 <FONT color="green">013</FONT> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.<a name="line.13"></a>
17 <FONT color="green">014</FONT> * See the License for the specific language governing permissions and<a name="line.14"></a>
18 <FONT color="green">015</FONT> * limitations under the License.<a name="line.15"></a>
19 <FONT color="green">016</FONT> */<a name="line.16"></a>
20 <FONT color="green">017</FONT> <a name="line.17"></a>
21 <FONT color="green">018</FONT> package org.apache.commons.math.ode.nonstiff;<a name="line.18"></a>
22 <FONT color="green">019</FONT> <a name="line.19"></a>
23 <FONT color="green">020</FONT> import org.apache.commons.math.ode.DerivativeException;<a name="line.20"></a>
24 <FONT color="green">021</FONT> import org.apache.commons.math.ode.FirstOrderDifferentialEquations;<a name="line.21"></a>
25 <FONT color="green">022</FONT> import org.apache.commons.math.ode.IntegratorException;<a name="line.22"></a>
26 <FONT color="green">023</FONT> import org.apache.commons.math.ode.events.EventHandler;<a name="line.23"></a>
27 <FONT color="green">024</FONT> import org.apache.commons.math.ode.sampling.AbstractStepInterpolator;<a name="line.24"></a>
28 <FONT color="green">025</FONT> import org.apache.commons.math.ode.sampling.DummyStepInterpolator;<a name="line.25"></a>
29 <FONT color="green">026</FONT> import org.apache.commons.math.ode.sampling.StepHandler;<a name="line.26"></a>
30 <FONT color="green">027</FONT> <a name="line.27"></a>
31 <FONT color="green">028</FONT> /**<a name="line.28"></a>
32 <FONT color="green">029</FONT> * This class implements a Gragg-Bulirsch-Stoer integrator for<a name="line.29"></a>
33 <FONT color="green">030</FONT> * Ordinary Differential Equations.<a name="line.30"></a>
34 <FONT color="green">031</FONT> *<a name="line.31"></a>
35 <FONT color="green">032</FONT> * &lt;p&gt;The Gragg-Bulirsch-Stoer algorithm is one of the most efficient<a name="line.32"></a>
36 <FONT color="green">033</FONT> * ones currently available for smooth problems. It uses Richardson<a name="line.33"></a>
37 <FONT color="green">034</FONT> * extrapolation to estimate what would be the solution if the step<a name="line.34"></a>
38 <FONT color="green">035</FONT> * size could be decreased down to zero.&lt;/p&gt;<a name="line.35"></a>
39 <FONT color="green">036</FONT> *<a name="line.36"></a>
40 <FONT color="green">037</FONT> * &lt;p&gt;<a name="line.37"></a>
41 <FONT color="green">038</FONT> * This method changes both the step size and the order during<a name="line.38"></a>
42 <FONT color="green">039</FONT> * integration, in order to minimize computation cost. It is<a name="line.39"></a>
43 <FONT color="green">040</FONT> * particularly well suited when a very high precision is needed. The<a name="line.40"></a>
44 <FONT color="green">041</FONT> * limit where this method becomes more efficient than high-order<a name="line.41"></a>
45 <FONT color="green">042</FONT> * embedded Runge-Kutta methods like {@link DormandPrince853Integrator<a name="line.42"></a>
46 <FONT color="green">043</FONT> * Dormand-Prince 8(5,3)} depends on the problem. Results given in the<a name="line.43"></a>
47 <FONT color="green">044</FONT> * Hairer, Norsett and Wanner book show for example that this limit<a name="line.44"></a>
48 <FONT color="green">045</FONT> * occurs for accuracy around 1e-6 when integrating Saltzam-Lorenz<a name="line.45"></a>
49 <FONT color="green">046</FONT> * equations (the authors note this problem is &lt;i&gt;extremely sensitive<a name="line.46"></a>
50 <FONT color="green">047</FONT> * to the errors in the first integration steps&lt;/i&gt;), and around 1e-11<a name="line.47"></a>
51 <FONT color="green">048</FONT> * for a two dimensional celestial mechanics problems with seven<a name="line.48"></a>
52 <FONT color="green">049</FONT> * bodies (pleiades problem, involving quasi-collisions for which<a name="line.49"></a>
53 <FONT color="green">050</FONT> * &lt;i&gt;automatic step size control is essential&lt;/i&gt;).<a name="line.50"></a>
54 <FONT color="green">051</FONT> * &lt;/p&gt;<a name="line.51"></a>
55 <FONT color="green">052</FONT> *<a name="line.52"></a>
56 <FONT color="green">053</FONT> * &lt;p&gt;<a name="line.53"></a>
57 <FONT color="green">054</FONT> * This implementation is basically a reimplementation in Java of the<a name="line.54"></a>
58 <FONT color="green">055</FONT> * &lt;a<a name="line.55"></a>
59 <FONT color="green">056</FONT> * href="http://www.unige.ch/math/folks/hairer/prog/nonstiff/odex.f"&gt;odex&lt;/a&gt;<a name="line.56"></a>
60 <FONT color="green">057</FONT> * fortran code by E. Hairer and G. Wanner. The redistribution policy<a name="line.57"></a>
61 <FONT color="green">058</FONT> * for this code is available &lt;a<a name="line.58"></a>
62 <FONT color="green">059</FONT> * href="http://www.unige.ch/~hairer/prog/licence.txt"&gt;here&lt;/a&gt;, for<a name="line.59"></a>
63 <FONT color="green">060</FONT> * convenience, it is reproduced below.&lt;/p&gt;<a name="line.60"></a>
64 <FONT color="green">061</FONT> * &lt;/p&gt;<a name="line.61"></a>
65 <FONT color="green">062</FONT> *<a name="line.62"></a>
66 <FONT color="green">063</FONT> * &lt;table border="0" width="80%" cellpadding="10" align="center" bgcolor="#E0E0E0"&gt;<a name="line.63"></a>
67 <FONT color="green">064</FONT> * &lt;tr&gt;&lt;td&gt;Copyright (c) 2004, Ernst Hairer&lt;/td&gt;&lt;/tr&gt;<a name="line.64"></a>
68 <FONT color="green">065</FONT> *<a name="line.65"></a>
69 <FONT color="green">066</FONT> * &lt;tr&gt;&lt;td&gt;Redistribution and use in source and binary forms, with or<a name="line.66"></a>
70 <FONT color="green">067</FONT> * without modification, are permitted provided that the following<a name="line.67"></a>
71 <FONT color="green">068</FONT> * conditions are met:<a name="line.68"></a>
72 <FONT color="green">069</FONT> * &lt;ul&gt;<a name="line.69"></a>
73 <FONT color="green">070</FONT> * &lt;li&gt;Redistributions of source code must retain the above copyright<a name="line.70"></a>
74 <FONT color="green">071</FONT> * notice, this list of conditions and the following disclaimer.&lt;/li&gt;<a name="line.71"></a>
75 <FONT color="green">072</FONT> * &lt;li&gt;Redistributions in binary form must reproduce the above copyright<a name="line.72"></a>
76 <FONT color="green">073</FONT> * notice, this list of conditions and the following disclaimer in the<a name="line.73"></a>
77 <FONT color="green">074</FONT> * documentation and/or other materials provided with the distribution.&lt;/li&gt;<a name="line.74"></a>
78 <FONT color="green">075</FONT> * &lt;/ul&gt;&lt;/td&gt;&lt;/tr&gt;<a name="line.75"></a>
79 <FONT color="green">076</FONT> *<a name="line.76"></a>
80 <FONT color="green">077</FONT> * &lt;tr&gt;&lt;td&gt;&lt;strong&gt;THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND<a name="line.77"></a>
81 <FONT color="green">078</FONT> * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,<a name="line.78"></a>
82 <FONT color="green">079</FONT> * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS<a name="line.79"></a>
83 <FONT color="green">080</FONT> * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR<a name="line.80"></a>
84 <FONT color="green">081</FONT> * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,<a name="line.81"></a>
85 <FONT color="green">082</FONT> * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,<a name="line.82"></a>
86 <FONT color="green">083</FONT> * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR<a name="line.83"></a>
87 <FONT color="green">084</FONT> * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF<a name="line.84"></a>
88 <FONT color="green">085</FONT> * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING<a name="line.85"></a>
89 <FONT color="green">086</FONT> * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS<a name="line.86"></a>
90 <FONT color="green">087</FONT> * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;<a name="line.87"></a>
91 <FONT color="green">088</FONT> * &lt;/table&gt;<a name="line.88"></a>
92 <FONT color="green">089</FONT> *<a name="line.89"></a>
93 <FONT color="green">090</FONT> * @version $Revision: 919479 $ $Date: 2010-03-05 11:35:56 -0500 (Fri, 05 Mar 2010) $<a name="line.90"></a>
94 <FONT color="green">091</FONT> * @since 1.2<a name="line.91"></a>
95 <FONT color="green">092</FONT> */<a name="line.92"></a>
96 <FONT color="green">093</FONT> <a name="line.93"></a>
97 <FONT color="green">094</FONT> public class GraggBulirschStoerIntegrator extends AdaptiveStepsizeIntegrator {<a name="line.94"></a>
98 <FONT color="green">095</FONT> <a name="line.95"></a>
99 <FONT color="green">096</FONT> /** Integrator method name. */<a name="line.96"></a>
100 <FONT color="green">097</FONT> private static final String METHOD_NAME = "Gragg-Bulirsch-Stoer";<a name="line.97"></a>
101 <FONT color="green">098</FONT> <a name="line.98"></a>
102 <FONT color="green">099</FONT> /** maximal order. */<a name="line.99"></a>
103 <FONT color="green">100</FONT> private int maxOrder;<a name="line.100"></a>
104 <FONT color="green">101</FONT> <a name="line.101"></a>
105 <FONT color="green">102</FONT> /** step size sequence. */<a name="line.102"></a>
106 <FONT color="green">103</FONT> private int[] sequence;<a name="line.103"></a>
107 <FONT color="green">104</FONT> <a name="line.104"></a>
108 <FONT color="green">105</FONT> /** overall cost of applying step reduction up to iteration k+1, in number of calls. */<a name="line.105"></a>
109 <FONT color="green">106</FONT> private int[] costPerStep;<a name="line.106"></a>
110 <FONT color="green">107</FONT> <a name="line.107"></a>
111 <FONT color="green">108</FONT> /** cost per unit step. */<a name="line.108"></a>
112 <FONT color="green">109</FONT> private double[] costPerTimeUnit;<a name="line.109"></a>
113 <FONT color="green">110</FONT> <a name="line.110"></a>
114 <FONT color="green">111</FONT> /** optimal steps for each order. */<a name="line.111"></a>
115 <FONT color="green">112</FONT> private double[] optimalStep;<a name="line.112"></a>
116 <FONT color="green">113</FONT> <a name="line.113"></a>
117 <FONT color="green">114</FONT> /** extrapolation coefficients. */<a name="line.114"></a>
118 <FONT color="green">115</FONT> private double[][] coeff;<a name="line.115"></a>
119 <FONT color="green">116</FONT> <a name="line.116"></a>
120 <FONT color="green">117</FONT> /** stability check enabling parameter. */<a name="line.117"></a>
121 <FONT color="green">118</FONT> private boolean performTest;<a name="line.118"></a>
122 <FONT color="green">119</FONT> <a name="line.119"></a>
123 <FONT color="green">120</FONT> /** maximal number of checks for each iteration. */<a name="line.120"></a>
124 <FONT color="green">121</FONT> private int maxChecks;<a name="line.121"></a>
125 <FONT color="green">122</FONT> <a name="line.122"></a>
126 <FONT color="green">123</FONT> /** maximal number of iterations for which checks are performed. */<a name="line.123"></a>
127 <FONT color="green">124</FONT> private int maxIter;<a name="line.124"></a>
128 <FONT color="green">125</FONT> <a name="line.125"></a>
129 <FONT color="green">126</FONT> /** stepsize reduction factor in case of stability check failure. */<a name="line.126"></a>
130 <FONT color="green">127</FONT> private double stabilityReduction;<a name="line.127"></a>
131 <FONT color="green">128</FONT> <a name="line.128"></a>
132 <FONT color="green">129</FONT> /** first stepsize control factor. */<a name="line.129"></a>
133 <FONT color="green">130</FONT> private double stepControl1;<a name="line.130"></a>
134 <FONT color="green">131</FONT> <a name="line.131"></a>
135 <FONT color="green">132</FONT> /** second stepsize control factor. */<a name="line.132"></a>
136 <FONT color="green">133</FONT> private double stepControl2;<a name="line.133"></a>
137 <FONT color="green">134</FONT> <a name="line.134"></a>
138 <FONT color="green">135</FONT> /** third stepsize control factor. */<a name="line.135"></a>
139 <FONT color="green">136</FONT> private double stepControl3;<a name="line.136"></a>
140 <FONT color="green">137</FONT> <a name="line.137"></a>
141 <FONT color="green">138</FONT> /** fourth stepsize control factor. */<a name="line.138"></a>
142 <FONT color="green">139</FONT> private double stepControl4;<a name="line.139"></a>
143 <FONT color="green">140</FONT> <a name="line.140"></a>
144 <FONT color="green">141</FONT> /** first order control factor. */<a name="line.141"></a>
145 <FONT color="green">142</FONT> private double orderControl1;<a name="line.142"></a>
146 <FONT color="green">143</FONT> <a name="line.143"></a>
147 <FONT color="green">144</FONT> /** second order control factor. */<a name="line.144"></a>
148 <FONT color="green">145</FONT> private double orderControl2;<a name="line.145"></a>
149 <FONT color="green">146</FONT> <a name="line.146"></a>
150 <FONT color="green">147</FONT> /** dense outpute required. */<a name="line.147"></a>
151 <FONT color="green">148</FONT> private boolean denseOutput;<a name="line.148"></a>
152 <FONT color="green">149</FONT> <a name="line.149"></a>
153 <FONT color="green">150</FONT> /** use interpolation error in stepsize control. */<a name="line.150"></a>
154 <FONT color="green">151</FONT> private boolean useInterpolationError;<a name="line.151"></a>
155 <FONT color="green">152</FONT> <a name="line.152"></a>
156 <FONT color="green">153</FONT> /** interpolation order control parameter. */<a name="line.153"></a>
157 <FONT color="green">154</FONT> private int mudif;<a name="line.154"></a>
158 <FONT color="green">155</FONT> <a name="line.155"></a>
159 <FONT color="green">156</FONT> /** Simple constructor.<a name="line.156"></a>
160 <FONT color="green">157</FONT> * Build a Gragg-Bulirsch-Stoer integrator with the given step<a name="line.157"></a>
161 <FONT color="green">158</FONT> * bounds. All tuning parameters are set to their default<a name="line.158"></a>
162 <FONT color="green">159</FONT> * values. The default step handler does nothing.<a name="line.159"></a>
163 <FONT color="green">160</FONT> * @param minStep minimal step (must be positive even for backward<a name="line.160"></a>
164 <FONT color="green">161</FONT> * integration), the last step can be smaller than this<a name="line.161"></a>
165 <FONT color="green">162</FONT> * @param maxStep maximal step (must be positive even for backward<a name="line.162"></a>
166 <FONT color="green">163</FONT> * integration)<a name="line.163"></a>
167 <FONT color="green">164</FONT> * @param scalAbsoluteTolerance allowed absolute error<a name="line.164"></a>
168 <FONT color="green">165</FONT> * @param scalRelativeTolerance allowed relative error<a name="line.165"></a>
169 <FONT color="green">166</FONT> */<a name="line.166"></a>
170 <FONT color="green">167</FONT> public GraggBulirschStoerIntegrator(final double minStep, final double maxStep,<a name="line.167"></a>
171 <FONT color="green">168</FONT> final double scalAbsoluteTolerance,<a name="line.168"></a>
172 <FONT color="green">169</FONT> final double scalRelativeTolerance) {<a name="line.169"></a>
173 <FONT color="green">170</FONT> super(METHOD_NAME, minStep, maxStep,<a name="line.170"></a>
174 <FONT color="green">171</FONT> scalAbsoluteTolerance, scalRelativeTolerance);<a name="line.171"></a>
175 <FONT color="green">172</FONT> denseOutput = requiresDenseOutput() || (! eventsHandlersManager.isEmpty());<a name="line.172"></a>
176 <FONT color="green">173</FONT> setStabilityCheck(true, -1, -1, -1);<a name="line.173"></a>
177 <FONT color="green">174</FONT> setStepsizeControl(-1, -1, -1, -1);<a name="line.174"></a>
178 <FONT color="green">175</FONT> setOrderControl(-1, -1, -1);<a name="line.175"></a>
179 <FONT color="green">176</FONT> setInterpolationControl(true, -1);<a name="line.176"></a>
180 <FONT color="green">177</FONT> }<a name="line.177"></a>
181 <FONT color="green">178</FONT> <a name="line.178"></a>
182 <FONT color="green">179</FONT> /** Simple constructor.<a name="line.179"></a>
183 <FONT color="green">180</FONT> * Build a Gragg-Bulirsch-Stoer integrator with the given step<a name="line.180"></a>
184 <FONT color="green">181</FONT> * bounds. All tuning parameters are set to their default<a name="line.181"></a>
185 <FONT color="green">182</FONT> * values. The default step handler does nothing.<a name="line.182"></a>
186 <FONT color="green">183</FONT> * @param minStep minimal step (must be positive even for backward<a name="line.183"></a>
187 <FONT color="green">184</FONT> * integration), the last step can be smaller than this<a name="line.184"></a>
188 <FONT color="green">185</FONT> * @param maxStep maximal step (must be positive even for backward<a name="line.185"></a>
189 <FONT color="green">186</FONT> * integration)<a name="line.186"></a>
190 <FONT color="green">187</FONT> * @param vecAbsoluteTolerance allowed absolute error<a name="line.187"></a>
191 <FONT color="green">188</FONT> * @param vecRelativeTolerance allowed relative error<a name="line.188"></a>
192 <FONT color="green">189</FONT> */<a name="line.189"></a>
193 <FONT color="green">190</FONT> public GraggBulirschStoerIntegrator(final double minStep, final double maxStep,<a name="line.190"></a>
194 <FONT color="green">191</FONT> final double[] vecAbsoluteTolerance,<a name="line.191"></a>
195 <FONT color="green">192</FONT> final double[] vecRelativeTolerance) {<a name="line.192"></a>
196 <FONT color="green">193</FONT> super(METHOD_NAME, minStep, maxStep,<a name="line.193"></a>
197 <FONT color="green">194</FONT> vecAbsoluteTolerance, vecRelativeTolerance);<a name="line.194"></a>
198 <FONT color="green">195</FONT> denseOutput = requiresDenseOutput() || (! eventsHandlersManager.isEmpty());<a name="line.195"></a>
199 <FONT color="green">196</FONT> setStabilityCheck(true, -1, -1, -1);<a name="line.196"></a>
200 <FONT color="green">197</FONT> setStepsizeControl(-1, -1, -1, -1);<a name="line.197"></a>
201 <FONT color="green">198</FONT> setOrderControl(-1, -1, -1);<a name="line.198"></a>
202 <FONT color="green">199</FONT> setInterpolationControl(true, -1);<a name="line.199"></a>
203 <FONT color="green">200</FONT> }<a name="line.200"></a>
204 <FONT color="green">201</FONT> <a name="line.201"></a>
205 <FONT color="green">202</FONT> /** Set the stability check controls.<a name="line.202"></a>
206 <FONT color="green">203</FONT> * &lt;p&gt;The stability check is performed on the first few iterations of<a name="line.203"></a>
207 <FONT color="green">204</FONT> * the extrapolation scheme. If this test fails, the step is rejected<a name="line.204"></a>
208 <FONT color="green">205</FONT> * and the stepsize is reduced.&lt;/p&gt;<a name="line.205"></a>
209 <FONT color="green">206</FONT> * &lt;p&gt;By default, the test is performed, at most during two<a name="line.206"></a>
210 <FONT color="green">207</FONT> * iterations at each step, and at most once for each of these<a name="line.207"></a>
211 <FONT color="green">208</FONT> * iterations. The default stepsize reduction factor is 0.5.&lt;/p&gt;<a name="line.208"></a>
212 <FONT color="green">209</FONT> * @param performStabilityCheck if true, stability check will be performed,<a name="line.209"></a>
213 <FONT color="green">210</FONT> if false, the check will be skipped<a name="line.210"></a>
214 <FONT color="green">211</FONT> * @param maxNumIter maximal number of iterations for which checks are<a name="line.211"></a>
215 <FONT color="green">212</FONT> * performed (the number of iterations is reset to default if negative<a name="line.212"></a>
216 <FONT color="green">213</FONT> * or null)<a name="line.213"></a>
217 <FONT color="green">214</FONT> * @param maxNumChecks maximal number of checks for each iteration<a name="line.214"></a>
218 <FONT color="green">215</FONT> * (the number of checks is reset to default if negative or null)<a name="line.215"></a>
219 <FONT color="green">216</FONT> * @param stepsizeReductionFactor stepsize reduction factor in case of<a name="line.216"></a>
220 <FONT color="green">217</FONT> * failure (the factor is reset to default if lower than 0.0001 or<a name="line.217"></a>
221 <FONT color="green">218</FONT> * greater than 0.9999)<a name="line.218"></a>
222 <FONT color="green">219</FONT> */<a name="line.219"></a>
223 <FONT color="green">220</FONT> public void setStabilityCheck(final boolean performStabilityCheck,<a name="line.220"></a>
224 <FONT color="green">221</FONT> final int maxNumIter, final int maxNumChecks,<a name="line.221"></a>
225 <FONT color="green">222</FONT> final double stepsizeReductionFactor) {<a name="line.222"></a>
226 <FONT color="green">223</FONT> <a name="line.223"></a>
227 <FONT color="green">224</FONT> this.performTest = performStabilityCheck;<a name="line.224"></a>
228 <FONT color="green">225</FONT> this.maxIter = (maxNumIter &lt;= 0) ? 2 : maxNumIter;<a name="line.225"></a>
229 <FONT color="green">226</FONT> this.maxChecks = (maxNumChecks &lt;= 0) ? 1 : maxNumChecks;<a name="line.226"></a>
230 <FONT color="green">227</FONT> <a name="line.227"></a>
231 <FONT color="green">228</FONT> if ((stepsizeReductionFactor &lt; 0.0001) || (stepsizeReductionFactor &gt; 0.9999)) {<a name="line.228"></a>
232 <FONT color="green">229</FONT> this.stabilityReduction = 0.5;<a name="line.229"></a>
233 <FONT color="green">230</FONT> } else {<a name="line.230"></a>
234 <FONT color="green">231</FONT> this.stabilityReduction = stepsizeReductionFactor;<a name="line.231"></a>
235 <FONT color="green">232</FONT> }<a name="line.232"></a>
236 <FONT color="green">233</FONT> <a name="line.233"></a>
237 <FONT color="green">234</FONT> }<a name="line.234"></a>
238 <FONT color="green">235</FONT> <a name="line.235"></a>
239 <FONT color="green">236</FONT> /** Set the step size control factors.<a name="line.236"></a>
240 <FONT color="green">237</FONT> <a name="line.237"></a>
241 <FONT color="green">238</FONT> * &lt;p&gt;The new step size hNew is computed from the old one h by:<a name="line.238"></a>
242 <FONT color="green">239</FONT> * &lt;pre&gt;<a name="line.239"></a>
243 <FONT color="green">240</FONT> * hNew = h * stepControl2 / (err/stepControl1)^(1/(2k+1))<a name="line.240"></a>
244 <FONT color="green">241</FONT> * &lt;/pre&gt;<a name="line.241"></a>
245 <FONT color="green">242</FONT> * where err is the scaled error and k the iteration number of the<a name="line.242"></a>
246 <FONT color="green">243</FONT> * extrapolation scheme (counting from 0). The default values are<a name="line.243"></a>
247 <FONT color="green">244</FONT> * 0.65 for stepControl1 and 0.94 for stepControl2.&lt;/p&gt;<a name="line.244"></a>
248 <FONT color="green">245</FONT> * &lt;p&gt;The step size is subject to the restriction:<a name="line.245"></a>
249 <FONT color="green">246</FONT> * &lt;pre&gt;<a name="line.246"></a>
250 <FONT color="green">247</FONT> * stepControl3^(1/(2k+1))/stepControl4 &lt;= hNew/h &lt;= 1/stepControl3^(1/(2k+1))<a name="line.247"></a>
251 <FONT color="green">248</FONT> * &lt;/pre&gt;<a name="line.248"></a>
252 <FONT color="green">249</FONT> * The default values are 0.02 for stepControl3 and 4.0 for<a name="line.249"></a>
253 <FONT color="green">250</FONT> * stepControl4.&lt;/p&gt;<a name="line.250"></a>
254 <FONT color="green">251</FONT> * @param control1 first stepsize control factor (the factor is<a name="line.251"></a>
255 <FONT color="green">252</FONT> * reset to default if lower than 0.0001 or greater than 0.9999)<a name="line.252"></a>
256 <FONT color="green">253</FONT> * @param control2 second stepsize control factor (the factor<a name="line.253"></a>
257 <FONT color="green">254</FONT> * is reset to default if lower than 0.0001 or greater than 0.9999)<a name="line.254"></a>
258 <FONT color="green">255</FONT> * @param control3 third stepsize control factor (the factor is<a name="line.255"></a>
259 <FONT color="green">256</FONT> * reset to default if lower than 0.0001 or greater than 0.9999)<a name="line.256"></a>
260 <FONT color="green">257</FONT> * @param control4 fourth stepsize control factor (the factor<a name="line.257"></a>
261 <FONT color="green">258</FONT> * is reset to default if lower than 1.0001 or greater than 999.9)<a name="line.258"></a>
262 <FONT color="green">259</FONT> */<a name="line.259"></a>
263 <FONT color="green">260</FONT> public void setStepsizeControl(final double control1, final double control2,<a name="line.260"></a>
264 <FONT color="green">261</FONT> final double control3, final double control4) {<a name="line.261"></a>
265 <FONT color="green">262</FONT> <a name="line.262"></a>
266 <FONT color="green">263</FONT> if ((control1 &lt; 0.0001) || (control1 &gt; 0.9999)) {<a name="line.263"></a>
267 <FONT color="green">264</FONT> this.stepControl1 = 0.65;<a name="line.264"></a>
268 <FONT color="green">265</FONT> } else {<a name="line.265"></a>
269 <FONT color="green">266</FONT> this.stepControl1 = control1;<a name="line.266"></a>
270 <FONT color="green">267</FONT> }<a name="line.267"></a>
271 <FONT color="green">268</FONT> <a name="line.268"></a>
272 <FONT color="green">269</FONT> if ((control2 &lt; 0.0001) || (control2 &gt; 0.9999)) {<a name="line.269"></a>
273 <FONT color="green">270</FONT> this.stepControl2 = 0.94;<a name="line.270"></a>
274 <FONT color="green">271</FONT> } else {<a name="line.271"></a>
275 <FONT color="green">272</FONT> this.stepControl2 = control2;<a name="line.272"></a>
276 <FONT color="green">273</FONT> }<a name="line.273"></a>
277 <FONT color="green">274</FONT> <a name="line.274"></a>
278 <FONT color="green">275</FONT> if ((control3 &lt; 0.0001) || (control3 &gt; 0.9999)) {<a name="line.275"></a>
279 <FONT color="green">276</FONT> this.stepControl3 = 0.02;<a name="line.276"></a>
280 <FONT color="green">277</FONT> } else {<a name="line.277"></a>
281 <FONT color="green">278</FONT> this.stepControl3 = control3;<a name="line.278"></a>
282 <FONT color="green">279</FONT> }<a name="line.279"></a>
283 <FONT color="green">280</FONT> <a name="line.280"></a>
284 <FONT color="green">281</FONT> if ((control4 &lt; 1.0001) || (control4 &gt; 999.9)) {<a name="line.281"></a>
285 <FONT color="green">282</FONT> this.stepControl4 = 4.0;<a name="line.282"></a>
286 <FONT color="green">283</FONT> } else {<a name="line.283"></a>
287 <FONT color="green">284</FONT> this.stepControl4 = control4;<a name="line.284"></a>
288 <FONT color="green">285</FONT> }<a name="line.285"></a>
289 <FONT color="green">286</FONT> <a name="line.286"></a>
290 <FONT color="green">287</FONT> }<a name="line.287"></a>
291 <FONT color="green">288</FONT> <a name="line.288"></a>
292 <FONT color="green">289</FONT> /** Set the order control parameters.<a name="line.289"></a>
293 <FONT color="green">290</FONT> * &lt;p&gt;The Gragg-Bulirsch-Stoer method changes both the step size and<a name="line.290"></a>
294 <FONT color="green">291</FONT> * the order during integration, in order to minimize computation<a name="line.291"></a>
295 <FONT color="green">292</FONT> * cost. Each extrapolation step increases the order by 2, so the<a name="line.292"></a>
296 <FONT color="green">293</FONT> * maximal order that will be used is always even, it is twice the<a name="line.293"></a>
297 <FONT color="green">294</FONT> * maximal number of columns in the extrapolation table.&lt;/p&gt;<a name="line.294"></a>
298 <FONT color="green">295</FONT> * &lt;pre&gt;<a name="line.295"></a>
299 <FONT color="green">296</FONT> * order is decreased if w(k-1) &lt;= w(k) * orderControl1<a name="line.296"></a>
300 <FONT color="green">297</FONT> * order is increased if w(k) &lt;= w(k-1) * orderControl2<a name="line.297"></a>
301 <FONT color="green">298</FONT> * &lt;/pre&gt;<a name="line.298"></a>
302 <FONT color="green">299</FONT> * &lt;p&gt;where w is the table of work per unit step for each order<a name="line.299"></a>
303 <FONT color="green">300</FONT> * (number of function calls divided by the step length), and k is<a name="line.300"></a>
304 <FONT color="green">301</FONT> * the current order.&lt;/p&gt;<a name="line.301"></a>
305 <FONT color="green">302</FONT> * &lt;p&gt;The default maximal order after construction is 18 (i.e. the<a name="line.302"></a>
306 <FONT color="green">303</FONT> * maximal number of columns is 9). The default values are 0.8 for<a name="line.303"></a>
307 <FONT color="green">304</FONT> * orderControl1 and 0.9 for orderControl2.&lt;/p&gt;<a name="line.304"></a>
308 <FONT color="green">305</FONT> * @param maximalOrder maximal order in the extrapolation table (the<a name="line.305"></a>
309 <FONT color="green">306</FONT> * maximal order is reset to default if order &lt;= 6 or odd)<a name="line.306"></a>
310 <FONT color="green">307</FONT> * @param control1 first order control factor (the factor is<a name="line.307"></a>
311 <FONT color="green">308</FONT> * reset to default if lower than 0.0001 or greater than 0.9999)<a name="line.308"></a>
312 <FONT color="green">309</FONT> * @param control2 second order control factor (the factor<a name="line.309"></a>
313 <FONT color="green">310</FONT> * is reset to default if lower than 0.0001 or greater than 0.9999)<a name="line.310"></a>
314 <FONT color="green">311</FONT> */<a name="line.311"></a>
315 <FONT color="green">312</FONT> public void setOrderControl(final int maximalOrder,<a name="line.312"></a>
316 <FONT color="green">313</FONT> final double control1, final double control2) {<a name="line.313"></a>
317 <FONT color="green">314</FONT> <a name="line.314"></a>
318 <FONT color="green">315</FONT> if ((maximalOrder &lt;= 6) || (maximalOrder % 2 != 0)) {<a name="line.315"></a>
319 <FONT color="green">316</FONT> this.maxOrder = 18;<a name="line.316"></a>
320 <FONT color="green">317</FONT> }<a name="line.317"></a>
321 <FONT color="green">318</FONT> <a name="line.318"></a>
322 <FONT color="green">319</FONT> if ((control1 &lt; 0.0001) || (control1 &gt; 0.9999)) {<a name="line.319"></a>
323 <FONT color="green">320</FONT> this.orderControl1 = 0.8;<a name="line.320"></a>
324 <FONT color="green">321</FONT> } else {<a name="line.321"></a>
325 <FONT color="green">322</FONT> this.orderControl1 = control1;<a name="line.322"></a>
326 <FONT color="green">323</FONT> }<a name="line.323"></a>
327 <FONT color="green">324</FONT> <a name="line.324"></a>
328 <FONT color="green">325</FONT> if ((control2 &lt; 0.0001) || (control2 &gt; 0.9999)) {<a name="line.325"></a>
329 <FONT color="green">326</FONT> this.orderControl2 = 0.9;<a name="line.326"></a>
330 <FONT color="green">327</FONT> } else {<a name="line.327"></a>
331 <FONT color="green">328</FONT> this.orderControl2 = control2;<a name="line.328"></a>
332 <FONT color="green">329</FONT> }<a name="line.329"></a>
333 <FONT color="green">330</FONT> <a name="line.330"></a>
334 <FONT color="green">331</FONT> // reinitialize the arrays<a name="line.331"></a>
335 <FONT color="green">332</FONT> initializeArrays();<a name="line.332"></a>
336 <FONT color="green">333</FONT> <a name="line.333"></a>
337 <FONT color="green">334</FONT> }<a name="line.334"></a>
338 <FONT color="green">335</FONT> <a name="line.335"></a>
339 <FONT color="green">336</FONT> /** {@inheritDoc} */<a name="line.336"></a>
340 <FONT color="green">337</FONT> @Override<a name="line.337"></a>
341 <FONT color="green">338</FONT> public void addStepHandler (final StepHandler handler) {<a name="line.338"></a>
342 <FONT color="green">339</FONT> <a name="line.339"></a>
343 <FONT color="green">340</FONT> super.addStepHandler(handler);<a name="line.340"></a>
344 <FONT color="green">341</FONT> denseOutput = requiresDenseOutput() || (! eventsHandlersManager.isEmpty());<a name="line.341"></a>
345 <FONT color="green">342</FONT> <a name="line.342"></a>
346 <FONT color="green">343</FONT> // reinitialize the arrays<a name="line.343"></a>
347 <FONT color="green">344</FONT> initializeArrays();<a name="line.344"></a>
348 <FONT color="green">345</FONT> <a name="line.345"></a>
349 <FONT color="green">346</FONT> }<a name="line.346"></a>
350 <FONT color="green">347</FONT> <a name="line.347"></a>
351 <FONT color="green">348</FONT> /** {@inheritDoc} */<a name="line.348"></a>
352 <FONT color="green">349</FONT> @Override<a name="line.349"></a>
353 <FONT color="green">350</FONT> public void addEventHandler(final EventHandler function,<a name="line.350"></a>
354 <FONT color="green">351</FONT> final double maxCheckInterval,<a name="line.351"></a>
355 <FONT color="green">352</FONT> final double convergence,<a name="line.352"></a>
356 <FONT color="green">353</FONT> final int maxIterationCount) {<a name="line.353"></a>
357 <FONT color="green">354</FONT> super.addEventHandler(function, maxCheckInterval, convergence, maxIterationCount);<a name="line.354"></a>
358 <FONT color="green">355</FONT> denseOutput = requiresDenseOutput() || (! eventsHandlersManager.isEmpty());<a name="line.355"></a>
359 <FONT color="green">356</FONT> <a name="line.356"></a>
360 <FONT color="green">357</FONT> // reinitialize the arrays<a name="line.357"></a>
361 <FONT color="green">358</FONT> initializeArrays();<a name="line.358"></a>
362 <FONT color="green">359</FONT> <a name="line.359"></a>
363 <FONT color="green">360</FONT> }<a name="line.360"></a>
364 <FONT color="green">361</FONT> <a name="line.361"></a>
365 <FONT color="green">362</FONT> /** Initialize the integrator internal arrays. */<a name="line.362"></a>
366 <FONT color="green">363</FONT> private void initializeArrays() {<a name="line.363"></a>
367 <FONT color="green">364</FONT> <a name="line.364"></a>
368 <FONT color="green">365</FONT> final int size = maxOrder / 2;<a name="line.365"></a>
369 <FONT color="green">366</FONT> <a name="line.366"></a>
370 <FONT color="green">367</FONT> if ((sequence == null) || (sequence.length != size)) {<a name="line.367"></a>
371 <FONT color="green">368</FONT> // all arrays should be reallocated with the right size<a name="line.368"></a>
372 <FONT color="green">369</FONT> sequence = new int[size];<a name="line.369"></a>
373 <FONT color="green">370</FONT> costPerStep = new int[size];<a name="line.370"></a>
374 <FONT color="green">371</FONT> coeff = new double[size][];<a name="line.371"></a>
375 <FONT color="green">372</FONT> costPerTimeUnit = new double[size];<a name="line.372"></a>
376 <FONT color="green">373</FONT> optimalStep = new double[size];<a name="line.373"></a>
377 <FONT color="green">374</FONT> }<a name="line.374"></a>
378 <FONT color="green">375</FONT> <a name="line.375"></a>
379 <FONT color="green">376</FONT> if (denseOutput) {<a name="line.376"></a>
380 <FONT color="green">377</FONT> // step size sequence: 2, 6, 10, 14, ...<a name="line.377"></a>
381 <FONT color="green">378</FONT> for (int k = 0; k &lt; size; ++k) {<a name="line.378"></a>
382 <FONT color="green">379</FONT> sequence[k] = 4 * k + 2;<a name="line.379"></a>
383 <FONT color="green">380</FONT> }<a name="line.380"></a>
384 <FONT color="green">381</FONT> } else {<a name="line.381"></a>
385 <FONT color="green">382</FONT> // step size sequence: 2, 4, 6, 8, ...<a name="line.382"></a>
386 <FONT color="green">383</FONT> for (int k = 0; k &lt; size; ++k) {<a name="line.383"></a>
387 <FONT color="green">384</FONT> sequence[k] = 2 * (k + 1);<a name="line.384"></a>
388 <FONT color="green">385</FONT> }<a name="line.385"></a>
389 <FONT color="green">386</FONT> }<a name="line.386"></a>
390 <FONT color="green">387</FONT> <a name="line.387"></a>
391 <FONT color="green">388</FONT> // initialize the order selection cost array<a name="line.388"></a>
392 <FONT color="green">389</FONT> // (number of function calls for each column of the extrapolation table)<a name="line.389"></a>
393 <FONT color="green">390</FONT> costPerStep[0] = sequence[0] + 1;<a name="line.390"></a>
394 <FONT color="green">391</FONT> for (int k = 1; k &lt; size; ++k) {<a name="line.391"></a>
395 <FONT color="green">392</FONT> costPerStep[k] = costPerStep[k-1] + sequence[k];<a name="line.392"></a>
396 <FONT color="green">393</FONT> }<a name="line.393"></a>
397 <FONT color="green">394</FONT> <a name="line.394"></a>
398 <FONT color="green">395</FONT> // initialize the extrapolation tables<a name="line.395"></a>
399 <FONT color="green">396</FONT> for (int k = 0; k &lt; size; ++k) {<a name="line.396"></a>
400 <FONT color="green">397</FONT> coeff[k] = (k &gt; 0) ? new double[k] : null;<a name="line.397"></a>
401 <FONT color="green">398</FONT> for (int l = 0; l &lt; k; ++l) {<a name="line.398"></a>
402 <FONT color="green">399</FONT> final double ratio = ((double) sequence[k]) / sequence[k-l-1];<a name="line.399"></a>
403 <FONT color="green">400</FONT> coeff[k][l] = 1.0 / (ratio * ratio - 1.0);<a name="line.400"></a>
404 <FONT color="green">401</FONT> }<a name="line.401"></a>
405 <FONT color="green">402</FONT> }<a name="line.402"></a>
406 <FONT color="green">403</FONT> <a name="line.403"></a>
407 <FONT color="green">404</FONT> }<a name="line.404"></a>
408 <FONT color="green">405</FONT> <a name="line.405"></a>
409 <FONT color="green">406</FONT> /** Set the interpolation order control parameter.<a name="line.406"></a>
410 <FONT color="green">407</FONT> * The interpolation order for dense output is 2k - mudif + 1. The<a name="line.407"></a>
411 <FONT color="green">408</FONT> * default value for mudif is 4 and the interpolation error is used<a name="line.408"></a>
412 <FONT color="green">409</FONT> * in stepsize control by default.<a name="line.409"></a>
413 <FONT color="green">410</FONT> <a name="line.410"></a>
414 <FONT color="green">411</FONT> * @param useInterpolationErrorForControl if true, interpolation error is used<a name="line.411"></a>
415 <FONT color="green">412</FONT> * for stepsize control<a name="line.412"></a>
416 <FONT color="green">413</FONT> * @param mudifControlParameter interpolation order control parameter (the parameter<a name="line.413"></a>
417 <FONT color="green">414</FONT> * is reset to default if &lt;= 0 or &gt;= 7)<a name="line.414"></a>
418 <FONT color="green">415</FONT> */<a name="line.415"></a>
419 <FONT color="green">416</FONT> public void setInterpolationControl(final boolean useInterpolationErrorForControl,<a name="line.416"></a>
420 <FONT color="green">417</FONT> final int mudifControlParameter) {<a name="line.417"></a>
421 <FONT color="green">418</FONT> <a name="line.418"></a>
422 <FONT color="green">419</FONT> this.useInterpolationError = useInterpolationErrorForControl;<a name="line.419"></a>
423 <FONT color="green">420</FONT> <a name="line.420"></a>
424 <FONT color="green">421</FONT> if ((mudifControlParameter &lt;= 0) || (mudifControlParameter &gt;= 7)) {<a name="line.421"></a>
425 <FONT color="green">422</FONT> this.mudif = 4;<a name="line.422"></a>
426 <FONT color="green">423</FONT> } else {<a name="line.423"></a>
427 <FONT color="green">424</FONT> this.mudif = mudifControlParameter;<a name="line.424"></a>
428 <FONT color="green">425</FONT> }<a name="line.425"></a>
429 <FONT color="green">426</FONT> <a name="line.426"></a>
430 <FONT color="green">427</FONT> }<a name="line.427"></a>
431 <FONT color="green">428</FONT> <a name="line.428"></a>
432 <FONT color="green">429</FONT> /** Update scaling array.<a name="line.429"></a>
433 <FONT color="green">430</FONT> * @param y1 first state vector to use for scaling<a name="line.430"></a>
434 <FONT color="green">431</FONT> * @param y2 second state vector to use for scaling<a name="line.431"></a>
435 <FONT color="green">432</FONT> * @param scale scaling array to update<a name="line.432"></a>
436 <FONT color="green">433</FONT> */<a name="line.433"></a>
437 <FONT color="green">434</FONT> private void rescale(final double[] y1, final double[] y2, final double[] scale) {<a name="line.434"></a>
438 <FONT color="green">435</FONT> if (vecAbsoluteTolerance == null) {<a name="line.435"></a>
439 <FONT color="green">436</FONT> for (int i = 0; i &lt; scale.length; ++i) {<a name="line.436"></a>
440 <FONT color="green">437</FONT> final double yi = Math.max(Math.abs(y1[i]), Math.abs(y2[i]));<a name="line.437"></a>
441 <FONT color="green">438</FONT> scale[i] = scalAbsoluteTolerance + scalRelativeTolerance * yi;<a name="line.438"></a>
442 <FONT color="green">439</FONT> }<a name="line.439"></a>
443 <FONT color="green">440</FONT> } else {<a name="line.440"></a>
444 <FONT color="green">441</FONT> for (int i = 0; i &lt; scale.length; ++i) {<a name="line.441"></a>
445 <FONT color="green">442</FONT> final double yi = Math.max(Math.abs(y1[i]), Math.abs(y2[i]));<a name="line.442"></a>
446 <FONT color="green">443</FONT> scale[i] = vecAbsoluteTolerance[i] + vecRelativeTolerance[i] * yi;<a name="line.443"></a>
447 <FONT color="green">444</FONT> }<a name="line.444"></a>
448 <FONT color="green">445</FONT> }<a name="line.445"></a>
449 <FONT color="green">446</FONT> }<a name="line.446"></a>
450 <FONT color="green">447</FONT> <a name="line.447"></a>
451 <FONT color="green">448</FONT> /** Perform integration over one step using substeps of a modified<a name="line.448"></a>
452 <FONT color="green">449</FONT> * midpoint method.<a name="line.449"></a>
453 <FONT color="green">450</FONT> * @param t0 initial time<a name="line.450"></a>
454 <FONT color="green">451</FONT> * @param y0 initial value of the state vector at t0<a name="line.451"></a>
455 <FONT color="green">452</FONT> * @param step global step<a name="line.452"></a>
456 <FONT color="green">453</FONT> * @param k iteration number (from 0 to sequence.length - 1)<a name="line.453"></a>
457 <FONT color="green">454</FONT> * @param scale scaling array<a name="line.454"></a>
458 <FONT color="green">455</FONT> * @param f placeholder where to put the state vector derivatives at each substep<a name="line.455"></a>
459 <FONT color="green">456</FONT> * (element 0 already contains initial derivative)<a name="line.456"></a>
460 <FONT color="green">457</FONT> * @param yMiddle placeholder where to put the state vector at the middle of the step<a name="line.457"></a>
461 <FONT color="green">458</FONT> * @param yEnd placeholder where to put the state vector at the end<a name="line.458"></a>
462 <FONT color="green">459</FONT> * @param yTmp placeholder for one state vector<a name="line.459"></a>
463 <FONT color="green">460</FONT> * @return true if computation was done properly,<a name="line.460"></a>
464 <FONT color="green">461</FONT> * false if stability check failed before end of computation<a name="line.461"></a>
465 <FONT color="green">462</FONT> * @throws DerivativeException this exception is propagated to the caller if the<a name="line.462"></a>
466 <FONT color="green">463</FONT> * underlying user function triggers one<a name="line.463"></a>
467 <FONT color="green">464</FONT> */<a name="line.464"></a>
468 <FONT color="green">465</FONT> private boolean tryStep(final double t0, final double[] y0, final double step, final int k,<a name="line.465"></a>
469 <FONT color="green">466</FONT> final double[] scale, final double[][] f,<a name="line.466"></a>
470 <FONT color="green">467</FONT> final double[] yMiddle, final double[] yEnd,<a name="line.467"></a>
471 <FONT color="green">468</FONT> final double[] yTmp)<a name="line.468"></a>
472 <FONT color="green">469</FONT> throws DerivativeException {<a name="line.469"></a>
473 <FONT color="green">470</FONT> <a name="line.470"></a>
474 <FONT color="green">471</FONT> final int n = sequence[k];<a name="line.471"></a>
475 <FONT color="green">472</FONT> final double subStep = step / n;<a name="line.472"></a>
476 <FONT color="green">473</FONT> final double subStep2 = 2 * subStep;<a name="line.473"></a>
477 <FONT color="green">474</FONT> <a name="line.474"></a>
478 <FONT color="green">475</FONT> // first substep<a name="line.475"></a>
479 <FONT color="green">476</FONT> double t = t0 + subStep;<a name="line.476"></a>
480 <FONT color="green">477</FONT> for (int i = 0; i &lt; y0.length; ++i) {<a name="line.477"></a>
481 <FONT color="green">478</FONT> yTmp[i] = y0[i];<a name="line.478"></a>
482 <FONT color="green">479</FONT> yEnd[i] = y0[i] + subStep * f[0][i];<a name="line.479"></a>
483 <FONT color="green">480</FONT> }<a name="line.480"></a>
484 <FONT color="green">481</FONT> computeDerivatives(t, yEnd, f[1]);<a name="line.481"></a>
485 <FONT color="green">482</FONT> <a name="line.482"></a>
486 <FONT color="green">483</FONT> // other substeps<a name="line.483"></a>
487 <FONT color="green">484</FONT> for (int j = 1; j &lt; n; ++j) {<a name="line.484"></a>
488 <FONT color="green">485</FONT> <a name="line.485"></a>
489 <FONT color="green">486</FONT> if (2 * j == n) {<a name="line.486"></a>
490 <FONT color="green">487</FONT> // save the point at the middle of the step<a name="line.487"></a>
491 <FONT color="green">488</FONT> System.arraycopy(yEnd, 0, yMiddle, 0, y0.length);<a name="line.488"></a>
492 <FONT color="green">489</FONT> }<a name="line.489"></a>
493 <FONT color="green">490</FONT> <a name="line.490"></a>
494 <FONT color="green">491</FONT> t += subStep;<a name="line.491"></a>
495 <FONT color="green">492</FONT> for (int i = 0; i &lt; y0.length; ++i) {<a name="line.492"></a>
496 <FONT color="green">493</FONT> final double middle = yEnd[i];<a name="line.493"></a>
497 <FONT color="green">494</FONT> yEnd[i] = yTmp[i] + subStep2 * f[j][i];<a name="line.494"></a>
498 <FONT color="green">495</FONT> yTmp[i] = middle;<a name="line.495"></a>
499 <FONT color="green">496</FONT> }<a name="line.496"></a>
500 <FONT color="green">497</FONT> <a name="line.497"></a>
501 <FONT color="green">498</FONT> computeDerivatives(t, yEnd, f[j+1]);<a name="line.498"></a>
502 <FONT color="green">499</FONT> <a name="line.499"></a>
503 <FONT color="green">500</FONT> // stability check<a name="line.500"></a>
504 <FONT color="green">501</FONT> if (performTest &amp;&amp; (j &lt;= maxChecks) &amp;&amp; (k &lt; maxIter)) {<a name="line.501"></a>
505 <FONT color="green">502</FONT> double initialNorm = 0.0;<a name="line.502"></a>
506 <FONT color="green">503</FONT> for (int l = 0; l &lt; y0.length; ++l) {<a name="line.503"></a>
507 <FONT color="green">504</FONT> final double ratio = f[0][l] / scale[l];<a name="line.504"></a>
508 <FONT color="green">505</FONT> initialNorm += ratio * ratio;<a name="line.505"></a>
509 <FONT color="green">506</FONT> }<a name="line.506"></a>
510 <FONT color="green">507</FONT> double deltaNorm = 0.0;<a name="line.507"></a>
511 <FONT color="green">508</FONT> for (int l = 0; l &lt; y0.length; ++l) {<a name="line.508"></a>
512 <FONT color="green">509</FONT> final double ratio = (f[j+1][l] - f[0][l]) / scale[l];<a name="line.509"></a>
513 <FONT color="green">510</FONT> deltaNorm += ratio * ratio;<a name="line.510"></a>
514 <FONT color="green">511</FONT> }<a name="line.511"></a>
515 <FONT color="green">512</FONT> if (deltaNorm &gt; 4 * Math.max(1.0e-15, initialNorm)) {<a name="line.512"></a>
516 <FONT color="green">513</FONT> return false;<a name="line.513"></a>
517 <FONT color="green">514</FONT> }<a name="line.514"></a>
518 <FONT color="green">515</FONT> }<a name="line.515"></a>
519 <FONT color="green">516</FONT> <a name="line.516"></a>
520 <FONT color="green">517</FONT> }<a name="line.517"></a>
521 <FONT color="green">518</FONT> <a name="line.518"></a>
522 <FONT color="green">519</FONT> // correction of the last substep (at t0 + step)<a name="line.519"></a>
523 <FONT color="green">520</FONT> for (int i = 0; i &lt; y0.length; ++i) {<a name="line.520"></a>
524 <FONT color="green">521</FONT> yEnd[i] = 0.5 * (yTmp[i] + yEnd[i] + subStep * f[n][i]);<a name="line.521"></a>
525 <FONT color="green">522</FONT> }<a name="line.522"></a>
526 <FONT color="green">523</FONT> <a name="line.523"></a>
527 <FONT color="green">524</FONT> return true;<a name="line.524"></a>
528 <FONT color="green">525</FONT> <a name="line.525"></a>
529 <FONT color="green">526</FONT> }<a name="line.526"></a>
530 <FONT color="green">527</FONT> <a name="line.527"></a>
531 <FONT color="green">528</FONT> /** Extrapolate a vector.<a name="line.528"></a>
532 <FONT color="green">529</FONT> * @param offset offset to use in the coefficients table<a name="line.529"></a>
533 <FONT color="green">530</FONT> * @param k index of the last updated point<a name="line.530"></a>
534 <FONT color="green">531</FONT> * @param diag working diagonal of the Aitken-Neville's<a name="line.531"></a>
535 <FONT color="green">532</FONT> * triangle, without the last element<a name="line.532"></a>
536 <FONT color="green">533</FONT> * @param last last element<a name="line.533"></a>
537 <FONT color="green">534</FONT> */<a name="line.534"></a>
538 <FONT color="green">535</FONT> private void extrapolate(final int offset, final int k,<a name="line.535"></a>
539 <FONT color="green">536</FONT> final double[][] diag, final double[] last) {<a name="line.536"></a>
540 <FONT color="green">537</FONT> <a name="line.537"></a>
541 <FONT color="green">538</FONT> // update the diagonal<a name="line.538"></a>
542 <FONT color="green">539</FONT> for (int j = 1; j &lt; k; ++j) {<a name="line.539"></a>
543 <FONT color="green">540</FONT> for (int i = 0; i &lt; last.length; ++i) {<a name="line.540"></a>
544 <FONT color="green">541</FONT> // Aitken-Neville's recursive formula<a name="line.541"></a>
545 <FONT color="green">542</FONT> diag[k-j-1][i] = diag[k-j][i] +<a name="line.542"></a>
546 <FONT color="green">543</FONT> coeff[k+offset][j-1] * (diag[k-j][i] - diag[k-j-1][i]);<a name="line.543"></a>
547 <FONT color="green">544</FONT> }<a name="line.544"></a>
548 <FONT color="green">545</FONT> }<a name="line.545"></a>
549 <FONT color="green">546</FONT> <a name="line.546"></a>
550 <FONT color="green">547</FONT> // update the last element<a name="line.547"></a>
551 <FONT color="green">548</FONT> for (int i = 0; i &lt; last.length; ++i) {<a name="line.548"></a>
552 <FONT color="green">549</FONT> // Aitken-Neville's recursive formula<a name="line.549"></a>
553 <FONT color="green">550</FONT> last[i] = diag[0][i] + coeff[k+offset][k-1] * (diag[0][i] - last[i]);<a name="line.550"></a>
554 <FONT color="green">551</FONT> }<a name="line.551"></a>
555 <FONT color="green">552</FONT> }<a name="line.552"></a>
556 <FONT color="green">553</FONT> <a name="line.553"></a>
557 <FONT color="green">554</FONT> /** {@inheritDoc} */<a name="line.554"></a>
558 <FONT color="green">555</FONT> @Override<a name="line.555"></a>
559 <FONT color="green">556</FONT> public double integrate(final FirstOrderDifferentialEquations equations,<a name="line.556"></a>
560 <FONT color="green">557</FONT> final double t0, final double[] y0, final double t, final double[] y)<a name="line.557"></a>
561 <FONT color="green">558</FONT> throws DerivativeException, IntegratorException {<a name="line.558"></a>
562 <FONT color="green">559</FONT> <a name="line.559"></a>
563 <FONT color="green">560</FONT> sanityChecks(equations, t0, y0, t, y);<a name="line.560"></a>
564 <FONT color="green">561</FONT> setEquations(equations);<a name="line.561"></a>
565 <FONT color="green">562</FONT> resetEvaluations();<a name="line.562"></a>
566 <FONT color="green">563</FONT> final boolean forward = t &gt; t0;<a name="line.563"></a>
567 <FONT color="green">564</FONT> <a name="line.564"></a>
568 <FONT color="green">565</FONT> // create some internal working arrays<a name="line.565"></a>
569 <FONT color="green">566</FONT> final double[] yDot0 = new double[y0.length];<a name="line.566"></a>
570 <FONT color="green">567</FONT> final double[] y1 = new double[y0.length];<a name="line.567"></a>
571 <FONT color="green">568</FONT> final double[] yTmp = new double[y0.length];<a name="line.568"></a>
572 <FONT color="green">569</FONT> final double[] yTmpDot = new double[y0.length];<a name="line.569"></a>
573 <FONT color="green">570</FONT> <a name="line.570"></a>
574 <FONT color="green">571</FONT> final double[][] diagonal = new double[sequence.length-1][];<a name="line.571"></a>
575 <FONT color="green">572</FONT> final double[][] y1Diag = new double[sequence.length-1][];<a name="line.572"></a>
576 <FONT color="green">573</FONT> for (int k = 0; k &lt; sequence.length-1; ++k) {<a name="line.573"></a>
577 <FONT color="green">574</FONT> diagonal[k] = new double[y0.length];<a name="line.574"></a>
578 <FONT color="green">575</FONT> y1Diag[k] = new double[y0.length];<a name="line.575"></a>
579 <FONT color="green">576</FONT> }<a name="line.576"></a>
580 <FONT color="green">577</FONT> <a name="line.577"></a>
581 <FONT color="green">578</FONT> final double[][][] fk = new double[sequence.length][][];<a name="line.578"></a>
582 <FONT color="green">579</FONT> for (int k = 0; k &lt; sequence.length; ++k) {<a name="line.579"></a>
583 <FONT color="green">580</FONT> <a name="line.580"></a>
584 <FONT color="green">581</FONT> fk[k] = new double[sequence[k] + 1][];<a name="line.581"></a>
585 <FONT color="green">582</FONT> <a name="line.582"></a>
586 <FONT color="green">583</FONT> // all substeps start at the same point, so share the first array<a name="line.583"></a>
587 <FONT color="green">584</FONT> fk[k][0] = yDot0;<a name="line.584"></a>
588 <FONT color="green">585</FONT> <a name="line.585"></a>
589 <FONT color="green">586</FONT> for (int l = 0; l &lt; sequence[k]; ++l) {<a name="line.586"></a>
590 <FONT color="green">587</FONT> fk[k][l+1] = new double[y0.length];<a name="line.587"></a>
591 <FONT color="green">588</FONT> }<a name="line.588"></a>
592 <FONT color="green">589</FONT> <a name="line.589"></a>
593 <FONT color="green">590</FONT> }<a name="line.590"></a>
594 <FONT color="green">591</FONT> <a name="line.591"></a>
595 <FONT color="green">592</FONT> if (y != y0) {<a name="line.592"></a>
596 <FONT color="green">593</FONT> System.arraycopy(y0, 0, y, 0, y0.length);<a name="line.593"></a>
597 <FONT color="green">594</FONT> }<a name="line.594"></a>
598 <FONT color="green">595</FONT> <a name="line.595"></a>
599 <FONT color="green">596</FONT> double[] yDot1 = null;<a name="line.596"></a>
600 <FONT color="green">597</FONT> double[][] yMidDots = null;<a name="line.597"></a>
601 <FONT color="green">598</FONT> if (denseOutput) {<a name="line.598"></a>
602 <FONT color="green">599</FONT> yDot1 = new double[y0.length];<a name="line.599"></a>
603 <FONT color="green">600</FONT> yMidDots = new double[1 + 2 * sequence.length][];<a name="line.600"></a>
604 <FONT color="green">601</FONT> for (int j = 0; j &lt; yMidDots.length; ++j) {<a name="line.601"></a>
605 <FONT color="green">602</FONT> yMidDots[j] = new double[y0.length];<a name="line.602"></a>
606 <FONT color="green">603</FONT> }<a name="line.603"></a>
607 <FONT color="green">604</FONT> } else {<a name="line.604"></a>
608 <FONT color="green">605</FONT> yMidDots = new double[1][];<a name="line.605"></a>
609 <FONT color="green">606</FONT> yMidDots[0] = new double[y0.length];<a name="line.606"></a>
610 <FONT color="green">607</FONT> }<a name="line.607"></a>
611 <FONT color="green">608</FONT> <a name="line.608"></a>
612 <FONT color="green">609</FONT> // initial scaling<a name="line.609"></a>
613 <FONT color="green">610</FONT> final double[] scale = new double[y0.length];<a name="line.610"></a>
614 <FONT color="green">611</FONT> rescale(y, y, scale);<a name="line.611"></a>
615 <FONT color="green">612</FONT> <a name="line.612"></a>
616 <FONT color="green">613</FONT> // initial order selection<a name="line.613"></a>
617 <FONT color="green">614</FONT> final double tol =<a name="line.614"></a>
618 <FONT color="green">615</FONT> (vecRelativeTolerance == null) ? scalRelativeTolerance : vecRelativeTolerance[0];<a name="line.615"></a>
619 <FONT color="green">616</FONT> final double log10R = Math.log(Math.max(1.0e-10, tol)) / Math.log(10.0);<a name="line.616"></a>
620 <FONT color="green">617</FONT> int targetIter = Math.max(1,<a name="line.617"></a>
621 <FONT color="green">618</FONT> Math.min(sequence.length - 2,<a name="line.618"></a>
622 <FONT color="green">619</FONT> (int) Math.floor(0.5 - 0.6 * log10R)));<a name="line.619"></a>
623 <FONT color="green">620</FONT> // set up an interpolator sharing the integrator arrays<a name="line.620"></a>
624 <FONT color="green">621</FONT> AbstractStepInterpolator interpolator = null;<a name="line.621"></a>
625 <FONT color="green">622</FONT> if (denseOutput || (! eventsHandlersManager.isEmpty())) {<a name="line.622"></a>
626 <FONT color="green">623</FONT> interpolator = new GraggBulirschStoerStepInterpolator(y, yDot0,<a name="line.623"></a>
627 <FONT color="green">624</FONT> y1, yDot1,<a name="line.624"></a>
628 <FONT color="green">625</FONT> yMidDots, forward);<a name="line.625"></a>
629 <FONT color="green">626</FONT> } else {<a name="line.626"></a>
630 <FONT color="green">627</FONT> interpolator = new DummyStepInterpolator(y, yDot1, forward);<a name="line.627"></a>
631 <FONT color="green">628</FONT> }<a name="line.628"></a>
632 <FONT color="green">629</FONT> interpolator.storeTime(t0);<a name="line.629"></a>
633 <FONT color="green">630</FONT> <a name="line.630"></a>
634 <FONT color="green">631</FONT> stepStart = t0;<a name="line.631"></a>
635 <FONT color="green">632</FONT> double hNew = 0;<a name="line.632"></a>
636 <FONT color="green">633</FONT> double maxError = Double.MAX_VALUE;<a name="line.633"></a>
637 <FONT color="green">634</FONT> boolean previousRejected = false;<a name="line.634"></a>
638 <FONT color="green">635</FONT> boolean firstTime = true;<a name="line.635"></a>
639 <FONT color="green">636</FONT> boolean newStep = true;<a name="line.636"></a>
640 <FONT color="green">637</FONT> boolean lastStep = false;<a name="line.637"></a>
641 <FONT color="green">638</FONT> boolean firstStepAlreadyComputed = false;<a name="line.638"></a>
642 <FONT color="green">639</FONT> for (StepHandler handler : stepHandlers) {<a name="line.639"></a>
643 <FONT color="green">640</FONT> handler.reset();<a name="line.640"></a>
644 <FONT color="green">641</FONT> }<a name="line.641"></a>
645 <FONT color="green">642</FONT> costPerTimeUnit[0] = 0;<a name="line.642"></a>
646 <FONT color="green">643</FONT> while (! lastStep) {<a name="line.643"></a>
647 <FONT color="green">644</FONT> <a name="line.644"></a>
648 <FONT color="green">645</FONT> double error;<a name="line.645"></a>
649 <FONT color="green">646</FONT> boolean reject = false;<a name="line.646"></a>
650 <FONT color="green">647</FONT> <a name="line.647"></a>
651 <FONT color="green">648</FONT> if (newStep) {<a name="line.648"></a>
652 <FONT color="green">649</FONT> <a name="line.649"></a>
653 <FONT color="green">650</FONT> interpolator.shift();<a name="line.650"></a>
654 <FONT color="green">651</FONT> <a name="line.651"></a>
655 <FONT color="green">652</FONT> // first evaluation, at the beginning of the step<a name="line.652"></a>
656 <FONT color="green">653</FONT> if (! firstStepAlreadyComputed) {<a name="line.653"></a>
657 <FONT color="green">654</FONT> computeDerivatives(stepStart, y, yDot0);<a name="line.654"></a>
658 <FONT color="green">655</FONT> }<a name="line.655"></a>
659 <FONT color="green">656</FONT> <a name="line.656"></a>
660 <FONT color="green">657</FONT> if (firstTime) {<a name="line.657"></a>
661 <FONT color="green">658</FONT> <a name="line.658"></a>
662 <FONT color="green">659</FONT> hNew = initializeStep(equations, forward,<a name="line.659"></a>
663 <FONT color="green">660</FONT> 2 * targetIter + 1, scale,<a name="line.660"></a>
664 <FONT color="green">661</FONT> stepStart, y, yDot0, yTmp, yTmpDot);<a name="line.661"></a>
665 <FONT color="green">662</FONT> <a name="line.662"></a>
666 <FONT color="green">663</FONT> if (! forward) {<a name="line.663"></a>
667 <FONT color="green">664</FONT> hNew = -hNew;<a name="line.664"></a>
668 <FONT color="green">665</FONT> }<a name="line.665"></a>
669 <FONT color="green">666</FONT> <a name="line.666"></a>
670 <FONT color="green">667</FONT> }<a name="line.667"></a>
671 <FONT color="green">668</FONT> <a name="line.668"></a>
672 <FONT color="green">669</FONT> newStep = false;<a name="line.669"></a>
673 <FONT color="green">670</FONT> <a name="line.670"></a>
674 <FONT color="green">671</FONT> }<a name="line.671"></a>
675 <FONT color="green">672</FONT> <a name="line.672"></a>
676 <FONT color="green">673</FONT> stepSize = hNew;<a name="line.673"></a>
677 <FONT color="green">674</FONT> <a name="line.674"></a>
678 <FONT color="green">675</FONT> // step adjustment near bounds<a name="line.675"></a>
679 <FONT color="green">676</FONT> if ((forward &amp;&amp; (stepStart + stepSize &gt; t)) ||<a name="line.676"></a>
680 <FONT color="green">677</FONT> ((! forward) &amp;&amp; (stepStart + stepSize &lt; t))) {<a name="line.677"></a>
681 <FONT color="green">678</FONT> stepSize = t - stepStart;<a name="line.678"></a>
682 <FONT color="green">679</FONT> }<a name="line.679"></a>
683 <FONT color="green">680</FONT> final double nextT = stepStart + stepSize;<a name="line.680"></a>
684 <FONT color="green">681</FONT> lastStep = forward ? (nextT &gt;= t) : (nextT &lt;= t);<a name="line.681"></a>
685 <FONT color="green">682</FONT> <a name="line.682"></a>
686 <FONT color="green">683</FONT> // iterate over several substep sizes<a name="line.683"></a>
687 <FONT color="green">684</FONT> int k = -1;<a name="line.684"></a>
688 <FONT color="green">685</FONT> for (boolean loop = true; loop; ) {<a name="line.685"></a>
689 <FONT color="green">686</FONT> <a name="line.686"></a>
690 <FONT color="green">687</FONT> ++k;<a name="line.687"></a>
691 <FONT color="green">688</FONT> <a name="line.688"></a>
692 <FONT color="green">689</FONT> // modified midpoint integration with the current substep<a name="line.689"></a>
693 <FONT color="green">690</FONT> if ( ! tryStep(stepStart, y, stepSize, k, scale, fk[k],<a name="line.690"></a>
694 <FONT color="green">691</FONT> (k == 0) ? yMidDots[0] : diagonal[k-1],<a name="line.691"></a>
695 <FONT color="green">692</FONT> (k == 0) ? y1 : y1Diag[k-1],<a name="line.692"></a>
696 <FONT color="green">693</FONT> yTmp)) {<a name="line.693"></a>
697 <FONT color="green">694</FONT> <a name="line.694"></a>
698 <FONT color="green">695</FONT> // the stability check failed, we reduce the global step<a name="line.695"></a>
699 <FONT color="green">696</FONT> hNew = Math.abs(filterStep(stepSize * stabilityReduction, forward, false));<a name="line.696"></a>
700 <FONT color="green">697</FONT> reject = true;<a name="line.697"></a>
701 <FONT color="green">698</FONT> loop = false;<a name="line.698"></a>
702 <FONT color="green">699</FONT> <a name="line.699"></a>
703 <FONT color="green">700</FONT> } else {<a name="line.700"></a>
704 <FONT color="green">701</FONT> <a name="line.701"></a>
705 <FONT color="green">702</FONT> // the substep was computed successfully<a name="line.702"></a>
706 <FONT color="green">703</FONT> if (k &gt; 0) {<a name="line.703"></a>
707 <FONT color="green">704</FONT> <a name="line.704"></a>
708 <FONT color="green">705</FONT> // extrapolate the state at the end of the step<a name="line.705"></a>
709 <FONT color="green">706</FONT> // using last iteration data<a name="line.706"></a>
710 <FONT color="green">707</FONT> extrapolate(0, k, y1Diag, y1);<a name="line.707"></a>
711 <FONT color="green">708</FONT> rescale(y, y1, scale);<a name="line.708"></a>
712 <FONT color="green">709</FONT> <a name="line.709"></a>
713 <FONT color="green">710</FONT> // estimate the error at the end of the step.<a name="line.710"></a>
714 <FONT color="green">711</FONT> error = 0;<a name="line.711"></a>
715 <FONT color="green">712</FONT> for (int j = 0; j &lt; y0.length; ++j) {<a name="line.712"></a>
716 <FONT color="green">713</FONT> final double e = Math.abs(y1[j] - y1Diag[0][j]) / scale[j];<a name="line.713"></a>
717 <FONT color="green">714</FONT> error += e * e;<a name="line.714"></a>
718 <FONT color="green">715</FONT> }<a name="line.715"></a>
719 <FONT color="green">716</FONT> error = Math.sqrt(error / y0.length);<a name="line.716"></a>
720 <FONT color="green">717</FONT> <a name="line.717"></a>
721 <FONT color="green">718</FONT> if ((error &gt; 1.0e15) || ((k &gt; 1) &amp;&amp; (error &gt; maxError))) {<a name="line.718"></a>
722 <FONT color="green">719</FONT> // error is too big, we reduce the global step<a name="line.719"></a>
723 <FONT color="green">720</FONT> hNew = Math.abs(filterStep(stepSize * stabilityReduction, forward, false));<a name="line.720"></a>
724 <FONT color="green">721</FONT> reject = true;<a name="line.721"></a>
725 <FONT color="green">722</FONT> loop = false;<a name="line.722"></a>
726 <FONT color="green">723</FONT> } else {<a name="line.723"></a>
727 <FONT color="green">724</FONT> <a name="line.724"></a>
728 <FONT color="green">725</FONT> maxError = Math.max(4 * error, 1.0);<a name="line.725"></a>
729 <FONT color="green">726</FONT> <a name="line.726"></a>
730 <FONT color="green">727</FONT> // compute optimal stepsize for this order<a name="line.727"></a>
731 <FONT color="green">728</FONT> final double exp = 1.0 / (2 * k + 1);<a name="line.728"></a>
732 <FONT color="green">729</FONT> double fac = stepControl2 / Math.pow(error / stepControl1, exp);<a name="line.729"></a>
733 <FONT color="green">730</FONT> final double pow = Math.pow(stepControl3, exp);<a name="line.730"></a>
734 <FONT color="green">731</FONT> fac = Math.max(pow / stepControl4, Math.min(1 / pow, fac));<a name="line.731"></a>
735 <FONT color="green">732</FONT> optimalStep[k] = Math.abs(filterStep(stepSize * fac, forward, true));<a name="line.732"></a>
736 <FONT color="green">733</FONT> costPerTimeUnit[k] = costPerStep[k] / optimalStep[k];<a name="line.733"></a>
737 <FONT color="green">734</FONT> <a name="line.734"></a>
738 <FONT color="green">735</FONT> // check convergence<a name="line.735"></a>
739 <FONT color="green">736</FONT> switch (k - targetIter) {<a name="line.736"></a>
740 <FONT color="green">737</FONT> <a name="line.737"></a>
741 <FONT color="green">738</FONT> case -1 :<a name="line.738"></a>
742 <FONT color="green">739</FONT> if ((targetIter &gt; 1) &amp;&amp; ! previousRejected) {<a name="line.739"></a>
743 <FONT color="green">740</FONT> <a name="line.740"></a>
744 <FONT color="green">741</FONT> // check if we can stop iterations now<a name="line.741"></a>
745 <FONT color="green">742</FONT> if (error &lt;= 1.0) {<a name="line.742"></a>
746 <FONT color="green">743</FONT> // convergence have been reached just before targetIter<a name="line.743"></a>
747 <FONT color="green">744</FONT> loop = false;<a name="line.744"></a>
748 <FONT color="green">745</FONT> } else {<a name="line.745"></a>
749 <FONT color="green">746</FONT> // estimate if there is a chance convergence will<a name="line.746"></a>
750 <FONT color="green">747</FONT> // be reached on next iteration, using the<a name="line.747"></a>
751 <FONT color="green">748</FONT> // asymptotic evolution of error<a name="line.748"></a>
752 <FONT color="green">749</FONT> final double ratio = ((double) sequence [targetIter] * sequence[targetIter + 1]) /<a name="line.749"></a>
753 <FONT color="green">750</FONT> (sequence[0] * sequence[0]);<a name="line.750"></a>
754 <FONT color="green">751</FONT> if (error &gt; ratio * ratio) {<a name="line.751"></a>
755 <FONT color="green">752</FONT> // we don't expect to converge on next iteration<a name="line.752"></a>
756 <FONT color="green">753</FONT> // we reject the step immediately and reduce order<a name="line.753"></a>
757 <FONT color="green">754</FONT> reject = true;<a name="line.754"></a>
758 <FONT color="green">755</FONT> loop = false;<a name="line.755"></a>
759 <FONT color="green">756</FONT> targetIter = k;<a name="line.756"></a>
760 <FONT color="green">757</FONT> if ((targetIter &gt; 1) &amp;&amp;<a name="line.757"></a>
761 <FONT color="green">758</FONT> (costPerTimeUnit[targetIter-1] &lt;<a name="line.758"></a>
762 <FONT color="green">759</FONT> orderControl1 * costPerTimeUnit[targetIter])) {<a name="line.759"></a>
763 <FONT color="green">760</FONT> --targetIter;<a name="line.760"></a>
764 <FONT color="green">761</FONT> }<a name="line.761"></a>
765 <FONT color="green">762</FONT> hNew = optimalStep[targetIter];<a name="line.762"></a>
766 <FONT color="green">763</FONT> }<a name="line.763"></a>
767 <FONT color="green">764</FONT> }<a name="line.764"></a>
768 <FONT color="green">765</FONT> }<a name="line.765"></a>
769 <FONT color="green">766</FONT> break;<a name="line.766"></a>
770 <FONT color="green">767</FONT> <a name="line.767"></a>
771 <FONT color="green">768</FONT> case 0:<a name="line.768"></a>
772 <FONT color="green">769</FONT> if (error &lt;= 1.0) {<a name="line.769"></a>
773 <FONT color="green">770</FONT> // convergence has been reached exactly at targetIter<a name="line.770"></a>
774 <FONT color="green">771</FONT> loop = false;<a name="line.771"></a>
775 <FONT color="green">772</FONT> } else {<a name="line.772"></a>
776 <FONT color="green">773</FONT> // estimate if there is a chance convergence will<a name="line.773"></a>
777 <FONT color="green">774</FONT> // be reached on next iteration, using the<a name="line.774"></a>
778 <FONT color="green">775</FONT> // asymptotic evolution of error<a name="line.775"></a>
779 <FONT color="green">776</FONT> final double ratio = ((double) sequence[k+1]) / sequence[0];<a name="line.776"></a>
780 <FONT color="green">777</FONT> if (error &gt; ratio * ratio) {<a name="line.777"></a>
781 <FONT color="green">778</FONT> // we don't expect to converge on next iteration<a name="line.778"></a>
782 <FONT color="green">779</FONT> // we reject the step immediately<a name="line.779"></a>
783 <FONT color="green">780</FONT> reject = true;<a name="line.780"></a>
784 <FONT color="green">781</FONT> loop = false;<a name="line.781"></a>
785 <FONT color="green">782</FONT> if ((targetIter &gt; 1) &amp;&amp;<a name="line.782"></a>
786 <FONT color="green">783</FONT> (costPerTimeUnit[targetIter-1] &lt;<a name="line.783"></a>
787 <FONT color="green">784</FONT> orderControl1 * costPerTimeUnit[targetIter])) {<a name="line.784"></a>
788 <FONT color="green">785</FONT> --targetIter;<a name="line.785"></a>
789 <FONT color="green">786</FONT> }<a name="line.786"></a>
790 <FONT color="green">787</FONT> hNew = optimalStep[targetIter];<a name="line.787"></a>
791 <FONT color="green">788</FONT> }<a name="line.788"></a>
792 <FONT color="green">789</FONT> }<a name="line.789"></a>
793 <FONT color="green">790</FONT> break;<a name="line.790"></a>
794 <FONT color="green">791</FONT> <a name="line.791"></a>
795 <FONT color="green">792</FONT> case 1 :<a name="line.792"></a>
796 <FONT color="green">793</FONT> if (error &gt; 1.0) {<a name="line.793"></a>
797 <FONT color="green">794</FONT> reject = true;<a name="line.794"></a>
798 <FONT color="green">795</FONT> if ((targetIter &gt; 1) &amp;&amp;<a name="line.795"></a>
799 <FONT color="green">796</FONT> (costPerTimeUnit[targetIter-1] &lt;<a name="line.796"></a>
800 <FONT color="green">797</FONT> orderControl1 * costPerTimeUnit[targetIter])) {<a name="line.797"></a>
801 <FONT color="green">798</FONT> --targetIter;<a name="line.798"></a>
802 <FONT color="green">799</FONT> }<a name="line.799"></a>
803 <FONT color="green">800</FONT> hNew = optimalStep[targetIter];<a name="line.800"></a>
804 <FONT color="green">801</FONT> }<a name="line.801"></a>
805 <FONT color="green">802</FONT> loop = false;<a name="line.802"></a>
806 <FONT color="green">803</FONT> break;<a name="line.803"></a>
807 <FONT color="green">804</FONT> <a name="line.804"></a>
808 <FONT color="green">805</FONT> default :<a name="line.805"></a>
809 <FONT color="green">806</FONT> if ((firstTime || lastStep) &amp;&amp; (error &lt;= 1.0)) {<a name="line.806"></a>
810 <FONT color="green">807</FONT> loop = false;<a name="line.807"></a>
811 <FONT color="green">808</FONT> }<a name="line.808"></a>
812 <FONT color="green">809</FONT> break;<a name="line.809"></a>
813 <FONT color="green">810</FONT> <a name="line.810"></a>
814 <FONT color="green">811</FONT> }<a name="line.811"></a>
815 <FONT color="green">812</FONT> <a name="line.812"></a>
816 <FONT color="green">813</FONT> }<a name="line.813"></a>
817 <FONT color="green">814</FONT> }<a name="line.814"></a>
818 <FONT color="green">815</FONT> }<a name="line.815"></a>
819 <FONT color="green">816</FONT> }<a name="line.816"></a>
820 <FONT color="green">817</FONT> <a name="line.817"></a>
821 <FONT color="green">818</FONT> // dense output handling<a name="line.818"></a>
822 <FONT color="green">819</FONT> double hInt = getMaxStep();<a name="line.819"></a>
823 <FONT color="green">820</FONT> if (denseOutput &amp;&amp; ! reject) {<a name="line.820"></a>
824 <FONT color="green">821</FONT> <a name="line.821"></a>
825 <FONT color="green">822</FONT> // extrapolate state at middle point of the step<a name="line.822"></a>
826 <FONT color="green">823</FONT> for (int j = 1; j &lt;= k; ++j) {<a name="line.823"></a>
827 <FONT color="green">824</FONT> extrapolate(0, j, diagonal, yMidDots[0]);<a name="line.824"></a>
828 <FONT color="green">825</FONT> }<a name="line.825"></a>
829 <FONT color="green">826</FONT> <a name="line.826"></a>
830 <FONT color="green">827</FONT> // derivative at end of step<a name="line.827"></a>
831 <FONT color="green">828</FONT> computeDerivatives(stepStart + stepSize, y1, yDot1);<a name="line.828"></a>
832 <FONT color="green">829</FONT> <a name="line.829"></a>
833 <FONT color="green">830</FONT> final int mu = 2 * k - mudif + 3;<a name="line.830"></a>
834 <FONT color="green">831</FONT> <a name="line.831"></a>
835 <FONT color="green">832</FONT> for (int l = 0; l &lt; mu; ++l) {<a name="line.832"></a>
836 <FONT color="green">833</FONT> <a name="line.833"></a>
837 <FONT color="green">834</FONT> // derivative at middle point of the step<a name="line.834"></a>
838 <FONT color="green">835</FONT> final int l2 = l / 2;<a name="line.835"></a>
839 <FONT color="green">836</FONT> double factor = Math.pow(0.5 * sequence[l2], l);<a name="line.836"></a>
840 <FONT color="green">837</FONT> int middleIndex = fk[l2].length / 2;<a name="line.837"></a>
841 <FONT color="green">838</FONT> for (int i = 0; i &lt; y0.length; ++i) {<a name="line.838"></a>
842 <FONT color="green">839</FONT> yMidDots[l+1][i] = factor * fk[l2][middleIndex + l][i];<a name="line.839"></a>
843 <FONT color="green">840</FONT> }<a name="line.840"></a>
844 <FONT color="green">841</FONT> for (int j = 1; j &lt;= k - l2; ++j) {<a name="line.841"></a>
845 <FONT color="green">842</FONT> factor = Math.pow(0.5 * sequence[j + l2], l);<a name="line.842"></a>
846 <FONT color="green">843</FONT> middleIndex = fk[l2+j].length / 2;<a name="line.843"></a>
847 <FONT color="green">844</FONT> for (int i = 0; i &lt; y0.length; ++i) {<a name="line.844"></a>
848 <FONT color="green">845</FONT> diagonal[j-1][i] = factor * fk[l2+j][middleIndex+l][i];<a name="line.845"></a>
849 <FONT color="green">846</FONT> }<a name="line.846"></a>
850 <FONT color="green">847</FONT> extrapolate(l2, j, diagonal, yMidDots[l+1]);<a name="line.847"></a>
851 <FONT color="green">848</FONT> }<a name="line.848"></a>
852 <FONT color="green">849</FONT> for (int i = 0; i &lt; y0.length; ++i) {<a name="line.849"></a>
853 <FONT color="green">850</FONT> yMidDots[l+1][i] *= stepSize;<a name="line.850"></a>
854 <FONT color="green">851</FONT> }<a name="line.851"></a>
855 <FONT color="green">852</FONT> <a name="line.852"></a>
856 <FONT color="green">853</FONT> // compute centered differences to evaluate next derivatives<a name="line.853"></a>
857 <FONT color="green">854</FONT> for (int j = (l + 1) / 2; j &lt;= k; ++j) {<a name="line.854"></a>
858 <FONT color="green">855</FONT> for (int m = fk[j].length - 1; m &gt;= 2 * (l + 1); --m) {<a name="line.855"></a>
859 <FONT color="green">856</FONT> for (int i = 0; i &lt; y0.length; ++i) {<a name="line.856"></a>
860 <FONT color="green">857</FONT> fk[j][m][i] -= fk[j][m-2][i];<a name="line.857"></a>
861 <FONT color="green">858</FONT> }<a name="line.858"></a>
862 <FONT color="green">859</FONT> }<a name="line.859"></a>
863 <FONT color="green">860</FONT> }<a name="line.860"></a>
864 <FONT color="green">861</FONT> <a name="line.861"></a>
865 <FONT color="green">862</FONT> }<a name="line.862"></a>
866 <FONT color="green">863</FONT> <a name="line.863"></a>
867 <FONT color="green">864</FONT> if (mu &gt;= 0) {<a name="line.864"></a>
868 <FONT color="green">865</FONT> <a name="line.865"></a>
869 <FONT color="green">866</FONT> // estimate the dense output coefficients<a name="line.866"></a>
870 <FONT color="green">867</FONT> final GraggBulirschStoerStepInterpolator gbsInterpolator<a name="line.867"></a>
871 <FONT color="green">868</FONT> = (GraggBulirschStoerStepInterpolator) interpolator;<a name="line.868"></a>
872 <FONT color="green">869</FONT> gbsInterpolator.computeCoefficients(mu, stepSize);<a name="line.869"></a>
873 <FONT color="green">870</FONT> <a name="line.870"></a>
874 <FONT color="green">871</FONT> if (useInterpolationError) {<a name="line.871"></a>
875 <FONT color="green">872</FONT> // use the interpolation error to limit stepsize<a name="line.872"></a>
876 <FONT color="green">873</FONT> final double interpError = gbsInterpolator.estimateError(scale);<a name="line.873"></a>
877 <FONT color="green">874</FONT> hInt = Math.abs(stepSize / Math.max(Math.pow(interpError, 1.0 / (mu+4)),<a name="line.874"></a>
878 <FONT color="green">875</FONT> 0.01));<a name="line.875"></a>
879 <FONT color="green">876</FONT> if (interpError &gt; 10.0) {<a name="line.876"></a>
880 <FONT color="green">877</FONT> hNew = hInt;<a name="line.877"></a>
881 <FONT color="green">878</FONT> reject = true;<a name="line.878"></a>
882 <FONT color="green">879</FONT> }<a name="line.879"></a>
883 <FONT color="green">880</FONT> }<a name="line.880"></a>
884 <FONT color="green">881</FONT> <a name="line.881"></a>
885 <FONT color="green">882</FONT> // Discrete events handling<a name="line.882"></a>
886 <FONT color="green">883</FONT> if (!reject) {<a name="line.883"></a>
887 <FONT color="green">884</FONT> interpolator.storeTime(stepStart + stepSize);<a name="line.884"></a>
888 <FONT color="green">885</FONT> if (eventsHandlersManager.evaluateStep(interpolator)) {<a name="line.885"></a>
889 <FONT color="green">886</FONT> final double dt = eventsHandlersManager.getEventTime() - stepStart;<a name="line.886"></a>
890 <FONT color="green">887</FONT> if (Math.abs(dt) &gt; Math.ulp(stepStart)) {<a name="line.887"></a>
891 <FONT color="green">888</FONT> // reject the step to match exactly the next switch time<a name="line.888"></a>
892 <FONT color="green">889</FONT> hNew = Math.abs(dt);<a name="line.889"></a>
893 <FONT color="green">890</FONT> reject = true;<a name="line.890"></a>
894 <FONT color="green">891</FONT> }<a name="line.891"></a>
895 <FONT color="green">892</FONT> }<a name="line.892"></a>
896 <FONT color="green">893</FONT> }<a name="line.893"></a>
897 <FONT color="green">894</FONT> <a name="line.894"></a>
898 <FONT color="green">895</FONT> }<a name="line.895"></a>
899 <FONT color="green">896</FONT> <a name="line.896"></a>
900 <FONT color="green">897</FONT> if (!reject) {<a name="line.897"></a>
901 <FONT color="green">898</FONT> // we will reuse the slope for the beginning of next step<a name="line.898"></a>
902 <FONT color="green">899</FONT> firstStepAlreadyComputed = true;<a name="line.899"></a>
903 <FONT color="green">900</FONT> System.arraycopy(yDot1, 0, yDot0, 0, y0.length);<a name="line.900"></a>
904 <FONT color="green">901</FONT> }<a name="line.901"></a>
905 <FONT color="green">902</FONT> <a name="line.902"></a>
906 <FONT color="green">903</FONT> }<a name="line.903"></a>
907 <FONT color="green">904</FONT> <a name="line.904"></a>
908 <FONT color="green">905</FONT> if (! reject) {<a name="line.905"></a>
909 <FONT color="green">906</FONT> <a name="line.906"></a>
910 <FONT color="green">907</FONT> // store end of step state<a name="line.907"></a>
911 <FONT color="green">908</FONT> final double nextStep = stepStart + stepSize;<a name="line.908"></a>
912 <FONT color="green">909</FONT> System.arraycopy(y1, 0, y, 0, y0.length);<a name="line.909"></a>
913 <FONT color="green">910</FONT> <a name="line.910"></a>
914 <FONT color="green">911</FONT> eventsHandlersManager.stepAccepted(nextStep, y);<a name="line.911"></a>
915 <FONT color="green">912</FONT> if (eventsHandlersManager.stop()) {<a name="line.912"></a>
916 <FONT color="green">913</FONT> lastStep = true;<a name="line.913"></a>
917 <FONT color="green">914</FONT> }<a name="line.914"></a>
918 <FONT color="green">915</FONT> <a name="line.915"></a>
919 <FONT color="green">916</FONT> // provide the step data to the step handler<a name="line.916"></a>
920 <FONT color="green">917</FONT> interpolator.storeTime(nextStep);<a name="line.917"></a>
921 <FONT color="green">918</FONT> for (StepHandler handler : stepHandlers) {<a name="line.918"></a>
922 <FONT color="green">919</FONT> handler.handleStep(interpolator, lastStep);<a name="line.919"></a>
923 <FONT color="green">920</FONT> }<a name="line.920"></a>
924 <FONT color="green">921</FONT> stepStart = nextStep;<a name="line.921"></a>
925 <FONT color="green">922</FONT> <a name="line.922"></a>
926 <FONT color="green">923</FONT> if (eventsHandlersManager.reset(stepStart, y) &amp;&amp; ! lastStep) {<a name="line.923"></a>
927 <FONT color="green">924</FONT> // some switching function has triggered changes that<a name="line.924"></a>
928 <FONT color="green">925</FONT> // invalidate the derivatives, we need to recompute them<a name="line.925"></a>
929 <FONT color="green">926</FONT> firstStepAlreadyComputed = false;<a name="line.926"></a>
930 <FONT color="green">927</FONT> }<a name="line.927"></a>
931 <FONT color="green">928</FONT> <a name="line.928"></a>
932 <FONT color="green">929</FONT> int optimalIter;<a name="line.929"></a>
933 <FONT color="green">930</FONT> if (k == 1) {<a name="line.930"></a>
934 <FONT color="green">931</FONT> optimalIter = 2;<a name="line.931"></a>
935 <FONT color="green">932</FONT> if (previousRejected) {<a name="line.932"></a>
936 <FONT color="green">933</FONT> optimalIter = 1;<a name="line.933"></a>
937 <FONT color="green">934</FONT> }<a name="line.934"></a>
938 <FONT color="green">935</FONT> } else if (k &lt;= targetIter) {<a name="line.935"></a>
939 <FONT color="green">936</FONT> optimalIter = k;<a name="line.936"></a>
940 <FONT color="green">937</FONT> if (costPerTimeUnit[k-1] &lt; orderControl1 * costPerTimeUnit[k]) {<a name="line.937"></a>
941 <FONT color="green">938</FONT> optimalIter = k-1;<a name="line.938"></a>
942 <FONT color="green">939</FONT> } else if (costPerTimeUnit[k] &lt; orderControl2 * costPerTimeUnit[k-1]) {<a name="line.939"></a>
943 <FONT color="green">940</FONT> optimalIter = Math.min(k+1, sequence.length - 2);<a name="line.940"></a>
944 <FONT color="green">941</FONT> }<a name="line.941"></a>
945 <FONT color="green">942</FONT> } else {<a name="line.942"></a>
946 <FONT color="green">943</FONT> optimalIter = k - 1;<a name="line.943"></a>
947 <FONT color="green">944</FONT> if ((k &gt; 2) &amp;&amp;<a name="line.944"></a>
948 <FONT color="green">945</FONT> (costPerTimeUnit[k-2] &lt; orderControl1 * costPerTimeUnit[k-1])) {<a name="line.945"></a>
949 <FONT color="green">946</FONT> optimalIter = k - 2;<a name="line.946"></a>
950 <FONT color="green">947</FONT> }<a name="line.947"></a>
951 <FONT color="green">948</FONT> if (costPerTimeUnit[k] &lt; orderControl2 * costPerTimeUnit[optimalIter]) {<a name="line.948"></a>
952 <FONT color="green">949</FONT> optimalIter = Math.min(k, sequence.length - 2);<a name="line.949"></a>
953 <FONT color="green">950</FONT> }<a name="line.950"></a>
954 <FONT color="green">951</FONT> }<a name="line.951"></a>
955 <FONT color="green">952</FONT> <a name="line.952"></a>
956 <FONT color="green">953</FONT> if (previousRejected) {<a name="line.953"></a>
957 <FONT color="green">954</FONT> // after a rejected step neither order nor stepsize<a name="line.954"></a>
958 <FONT color="green">955</FONT> // should increase<a name="line.955"></a>
959 <FONT color="green">956</FONT> targetIter = Math.min(optimalIter, k);<a name="line.956"></a>
960 <FONT color="green">957</FONT> hNew = Math.min(Math.abs(stepSize), optimalStep[targetIter]);<a name="line.957"></a>
961 <FONT color="green">958</FONT> } else {<a name="line.958"></a>
962 <FONT color="green">959</FONT> // stepsize control<a name="line.959"></a>
963 <FONT color="green">960</FONT> if (optimalIter &lt;= k) {<a name="line.960"></a>
964 <FONT color="green">961</FONT> hNew = optimalStep[optimalIter];<a name="line.961"></a>
965 <FONT color="green">962</FONT> } else {<a name="line.962"></a>
966 <FONT color="green">963</FONT> if ((k &lt; targetIter) &amp;&amp;<a name="line.963"></a>
967 <FONT color="green">964</FONT> (costPerTimeUnit[k] &lt; orderControl2 * costPerTimeUnit[k-1])) {<a name="line.964"></a>
968 <FONT color="green">965</FONT> hNew = filterStep(optimalStep[k] * costPerStep[optimalIter+1] / costPerStep[k],<a name="line.965"></a>
969 <FONT color="green">966</FONT> forward, false);<a name="line.966"></a>
970 <FONT color="green">967</FONT> } else {<a name="line.967"></a>
971 <FONT color="green">968</FONT> hNew = filterStep(optimalStep[k] * costPerStep[optimalIter] / costPerStep[k],<a name="line.968"></a>
972 <FONT color="green">969</FONT> forward, false);<a name="line.969"></a>
973 <FONT color="green">970</FONT> }<a name="line.970"></a>
974 <FONT color="green">971</FONT> }<a name="line.971"></a>
975 <FONT color="green">972</FONT> <a name="line.972"></a>
976 <FONT color="green">973</FONT> targetIter = optimalIter;<a name="line.973"></a>
977 <FONT color="green">974</FONT> <a name="line.974"></a>
978 <FONT color="green">975</FONT> }<a name="line.975"></a>
979 <FONT color="green">976</FONT> <a name="line.976"></a>
980 <FONT color="green">977</FONT> newStep = true;<a name="line.977"></a>
981 <FONT color="green">978</FONT> <a name="line.978"></a>
982 <FONT color="green">979</FONT> }<a name="line.979"></a>
983 <FONT color="green">980</FONT> <a name="line.980"></a>
984 <FONT color="green">981</FONT> hNew = Math.min(hNew, hInt);<a name="line.981"></a>
985 <FONT color="green">982</FONT> if (! forward) {<a name="line.982"></a>
986 <FONT color="green">983</FONT> hNew = -hNew;<a name="line.983"></a>
987 <FONT color="green">984</FONT> }<a name="line.984"></a>
988 <FONT color="green">985</FONT> <a name="line.985"></a>
989 <FONT color="green">986</FONT> firstTime = false;<a name="line.986"></a>
990 <FONT color="green">987</FONT> <a name="line.987"></a>
991 <FONT color="green">988</FONT> if (reject) {<a name="line.988"></a>
992 <FONT color="green">989</FONT> lastStep = false;<a name="line.989"></a>
993 <FONT color="green">990</FONT> previousRejected = true;<a name="line.990"></a>
994 <FONT color="green">991</FONT> } else {<a name="line.991"></a>
995 <FONT color="green">992</FONT> previousRejected = false;<a name="line.992"></a>
996 <FONT color="green">993</FONT> }<a name="line.993"></a>
997 <FONT color="green">994</FONT> <a name="line.994"></a>
998 <FONT color="green">995</FONT> }<a name="line.995"></a>
999 <FONT color="green">996</FONT> <a name="line.996"></a>
1000 <FONT color="green">997</FONT> return stepStart;<a name="line.997"></a>
1001 <FONT color="green">998</FONT> <a name="line.998"></a>
1002 <FONT color="green">999</FONT> }<a name="line.999"></a>
1003 <FONT color="green">1000</FONT> <a name="line.1000"></a>
1004 <FONT color="green">1001</FONT> }<a name="line.1001"></a>
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065 </PRE>
1066 </BODY>
1067 </HTML>