1dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond/*
2dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Licensed to the Apache Software Foundation (ASF) under one or more
3dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * contributor license agreements.  See the NOTICE file distributed with
4dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * this work for additional information regarding copyright ownership.
5dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The ASF licenses this file to You under the Apache License, Version 2.0
6dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * (the "License"); you may not use this file except in compliance with
7dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * the License.  You may obtain a copy of the License at
8dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond *
9dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond *      http://www.apache.org/licenses/LICENSE-2.0
10dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond *
11dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Unless required by applicable law or agreed to in writing, software
12dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * distributed under the License is distributed on an "AS IS" BASIS,
13dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * See the License for the specific language governing permissions and
15dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * limitations under the License.
16dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */
17dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
18dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondpackage org.apache.commons.math.ode.nonstiff;
19dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
20dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport java.io.IOException;
21dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport java.io.ObjectInput;
22dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport java.io.ObjectOutput;
23dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
24dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.ode.AbstractIntegrator;
25dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.ode.DerivativeException;
26dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.ode.sampling.StepInterpolator;
27dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
28dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond/**
29dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * This class represents an interpolator over the last step during an
30dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * ODE integration for the 8(5,3) Dormand-Prince integrator.
31dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond *
32dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @see DormandPrince853Integrator
33dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond *
34dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
35dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @since 1.2
36dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */
37dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
38dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondclass DormandPrince853StepInterpolator
39dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond  extends RungeKuttaStepInterpolator {
40dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
41dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Serializable version identifier */
42dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final long serialVersionUID = 7152276390558450974L;
43dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
44dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Propagation weights, element 1. */
45dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double B_01 =         104257.0 / 1920240.0;
46dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
47dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    // elements 2 to 5 are zero, so they are neither stored nor used
48dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
49dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Propagation weights, element 6. */
50dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double B_06 =        3399327.0 / 763840.0;
51dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
52dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Propagation weights, element 7. */
53dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double B_07 =       66578432.0 / 35198415.0;
54dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
55dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Propagation weights, element 8. */
56dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double B_08 =    -1674902723.0 / 288716400.0;
57dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
58dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Propagation weights, element 9. */
59dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double B_09 = 54980371265625.0 / 176692375811392.0;
60dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
61dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Propagation weights, element 10. */
62dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double B_10 =        -734375.0 / 4826304.0;
63dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
64dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Propagation weights, element 11. */
65dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double B_11 =      171414593.0 / 851261400.0;
66dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
67dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Propagation weights, element 12. */
68dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double B_12 =         137909.0 / 3084480.0;
69dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
70dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Time step for stage 14 (interpolation only). */
71dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double C14    = 1.0 / 10.0;
72dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
73dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Internal weights for stage 14, element 1. */
74dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double K14_01 =       13481885573.0 / 240030000000.0      - B_01;
75dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
76dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    // elements 2 to 5 are zero, so they are neither stored nor used
77dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
78dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Internal weights for stage 14, element 6. */
79dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double K14_06 =                 0.0                       - B_06;
80dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
81dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Internal weights for stage 14, element 7. */
82dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double K14_07 =      139418837528.0 / 549975234375.0      - B_07;
83dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
84dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Internal weights for stage 14, element 8. */
85dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double K14_08 =   -11108320068443.0 / 45111937500000.0    - B_08;
86dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
87dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Internal weights for stage 14, element 9. */
88dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double K14_09 = -1769651421925959.0 / 14249385146080000.0 - B_09;
89dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
90dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Internal weights for stage 14, element 10. */
91dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double K14_10 =          57799439.0 / 377055000.0         - B_10;
92dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
93dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Internal weights for stage 14, element 11. */
94dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double K14_11 =      793322643029.0 / 96734250000000.0    - B_11;
95dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
96dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Internal weights for stage 14, element 12. */
97dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double K14_12 =        1458939311.0 / 192780000000.0      - B_12;
98dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
99dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Internal weights for stage 14, element 13. */
100dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double K14_13 =             -4149.0 / 500000.0;
101dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
102dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Time step for stage 15 (interpolation only). */
103dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double C15    = 1.0 / 5.0;
104dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
105dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
106dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Internal weights for stage 15, element 1. */
107dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double K15_01 =     1595561272731.0 / 50120273500000.0    - B_01;
108dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
109dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    // elements 2 to 5 are zero, so they are neither stored nor used
110dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
111dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Internal weights for stage 15, element 6. */
112dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double K15_06 =      975183916491.0 / 34457688031250.0    - B_06;
113dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
114dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Internal weights for stage 15, element 7. */
115dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double K15_07 =    38492013932672.0 / 718912673015625.0   - B_07;
116dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
117dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Internal weights for stage 15, element 8. */
118dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double K15_08 = -1114881286517557.0 / 20298710767500000.0 - B_08;
119dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
120dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Internal weights for stage 15, element 9. */
121dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double K15_09 =                 0.0                       - B_09;
122dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
123dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Internal weights for stage 15, element 10. */
124dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double K15_10 =                 0.0                       - B_10;
125dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
126dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Internal weights for stage 15, element 11. */
127dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double K15_11 =    -2538710946863.0 / 23431227861250000.0 - B_11;
128dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
129dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Internal weights for stage 15, element 12. */
130dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double K15_12 =        8824659001.0 / 23066716781250.0    - B_12;
131dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
132dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Internal weights for stage 15, element 13. */
133dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double K15_13 =      -11518334563.0 / 33831184612500.0;
134dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
135dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Internal weights for stage 15, element 14. */
136dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double K15_14 =        1912306948.0 / 13532473845.0;
137dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
138dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Time step for stage 16 (interpolation only). */
139dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double C16    = 7.0 / 9.0;
140dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
141dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
142dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Internal weights for stage 16, element 1. */
143dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double K16_01 =      -13613986967.0 / 31741908048.0       - B_01;
144dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
145dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    // elements 2 to 5 are zero, so they are neither stored nor used
146dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
147dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Internal weights for stage 16, element 6. */
148dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double K16_06 =       -4755612631.0 / 1012344804.0        - B_06;
149dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
150dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Internal weights for stage 16, element 7. */
151dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double K16_07 =    42939257944576.0 / 5588559685701.0     - B_07;
152dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
153dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Internal weights for stage 16, element 8. */
154dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double K16_08 =    77881972900277.0 / 19140370552944.0    - B_08;
155dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
156dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Internal weights for stage 16, element 9. */
157dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double K16_09 =    22719829234375.0 / 63689648654052.0    - B_09;
158dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
159dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Internal weights for stage 16, element 10. */
160dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double K16_10 =                 0.0                       - B_10;
161dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
162dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Internal weights for stage 16, element 11. */
163dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double K16_11 =                 0.0                       - B_11;
164dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
165dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Internal weights for stage 16, element 12. */
166dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double K16_12 =                 0.0                       - B_12;
167dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
168dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Internal weights for stage 16, element 13. */
169dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double K16_13 =       -1199007803.0 / 857031517296.0;
170dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
171dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Internal weights for stage 16, element 14. */
172dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double K16_14 =      157882067000.0 / 53564469831.0;
173dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
174dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Internal weights for stage 16, element 15. */
175dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double K16_15 =     -290468882375.0 / 31741908048.0;
176dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
177dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Interpolation weights.
178dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * (beware that only the non-null values are in the table)
179dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
180dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final double[][] D = {
181dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
182dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      {        -17751989329.0 / 2106076560.0,               4272954039.0 / 7539864640.0,
183dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond              -118476319744.0 / 38604839385.0,            755123450731.0 / 316657731600.0,
184dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        3692384461234828125.0 / 1744130441634250432.0,     -4612609375.0 / 5293382976.0,
185dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond              2091772278379.0 / 933644586600.0,             2136624137.0 / 3382989120.0,
186dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                    -126493.0 / 1421424.0,                    98350000.0 / 5419179.0,
187dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                  -18878125.0 / 2053168.0,                 -1944542619.0 / 438351368.0},
188dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
189dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      {         32941697297.0 / 3159114840.0,             456696183123.0 / 1884966160.0,
190dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond             19132610714624.0 / 115814518155.0,       -177904688592943.0 / 474986597400.0,
191dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond       -4821139941836765625.0 / 218016305204281304.0,      30702015625.0 / 3970037232.0,
192dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            -85916079474274.0 / 2800933759800.0,           -5919468007.0 / 634310460.0,
193dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                    2479159.0 / 157936.0,                    -18750000.0 / 602131.0,
194dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                  -19203125.0 / 2053168.0,                 15700361463.0 / 438351368.0},
195dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
196dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      {         12627015655.0 / 631822968.0,              -72955222965.0 / 188496616.0,
197dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            -13145744952320.0 / 69488710893.0,          30084216194513.0 / 56998391688.0,
198dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        -296858761006640625.0 / 25648977082856624.0,         569140625.0 / 82709109.0,
199dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond               -18684190637.0 / 18672891732.0,                69644045.0 / 89549712.0,
200dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                  -11847025.0 / 4264272.0,                  -978650000.0 / 16257537.0,
201dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                  519371875.0 / 6159504.0,                  5256837225.0 / 438351368.0},
202dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
203dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      {          -450944925.0 / 17550638.0,               -14532122925.0 / 94248308.0,
204dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond              -595876966400.0 / 2573655959.0,             188748653015.0 / 527762886.0,
205dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        2545485458115234375.0 / 27252038150535163.0,       -1376953125.0 / 36759604.0,
206dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                53995596795.0 / 518691437.0,                 210311225.0 / 7047894.0,
207dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                   -1718875.0 / 39484.0,                      58000000.0 / 602131.0,
208dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                   -1546875.0 / 39484.0,                   -1262172375.0 / 8429834.0}
209dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
210dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    };
211dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
212dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Last evaluations. */
213dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private double[][] yDotKLast;
214dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
215dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Vectors for interpolation. */
216dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private double[][] v;
217dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
218dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Initialization indicator for the interpolation vectors. */
219dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private boolean vectorsInitialized;
220dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
221dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond  /** Simple constructor.
222dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond   * This constructor builds an instance that is not usable yet, the
223dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond   * {@link #reinitialize} method should be called before using the
224dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond   * instance in order to initialize the internal arrays. This
225dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond   * constructor is used only in order to delay the initialization in
226dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond   * some cases. The {@link EmbeddedRungeKuttaIntegrator} uses the
227dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond   * prototyping design pattern to create the step interpolators by
228dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond   * cloning an uninitialized model and latter initializing the copy.
229dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond   */
230dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond  public DormandPrince853StepInterpolator() {
231dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    super();
232dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    yDotKLast = null;
233dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    v         = null;
234dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    vectorsInitialized = false;
235dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond  }
236dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
237dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond  /** Copy constructor.
238dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond   * @param interpolator interpolator to copy from. The copy is a deep
239dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond   * copy: its arrays are separated from the original arrays of the
240dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond   * instance
241dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond   */
242dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond  public DormandPrince853StepInterpolator(final DormandPrince853StepInterpolator interpolator) {
243dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
244dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    super(interpolator);
245dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
246dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    if (interpolator.currentState == null) {
247dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
248dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      yDotKLast = null;
249dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      v         = null;
250dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      vectorsInitialized = false;
251dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
252dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    } else {
253dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
254dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      final int dimension = interpolator.currentState.length;
255dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
256dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      yDotKLast    = new double[3][];
257dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      for (int k = 0; k < yDotKLast.length; ++k) {
258dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        yDotKLast[k] = new double[dimension];
259dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        System.arraycopy(interpolator.yDotKLast[k], 0, yDotKLast[k], 0,
260dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                         dimension);
261dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      }
262dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
263dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      v = new double[7][];
264dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      for (int k = 0; k < v.length; ++k) {
265dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        v[k] = new double[dimension];
266dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        System.arraycopy(interpolator.v[k], 0, v[k], 0, dimension);
267dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      }
268dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
269dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      vectorsInitialized = interpolator.vectorsInitialized;
270dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
271dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
272dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
273dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond  }
274dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
275dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond  /** {@inheritDoc} */
276dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond  @Override
277dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond  protected StepInterpolator doCopy() {
278dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    return new DormandPrince853StepInterpolator(this);
279dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond  }
280dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
281dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond  /** {@inheritDoc} */
282dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond  @Override
283dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond  public void reinitialize(final AbstractIntegrator integrator,
284dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                           final double[] y, final double[][] yDotK, final boolean forward) {
285dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
286dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    super.reinitialize(integrator, y, yDotK, forward);
287dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
288dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    final int dimension = currentState.length;
289dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
290dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    yDotKLast = new double[3][];
291dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    for (int k = 0; k < yDotKLast.length; ++k) {
292dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      yDotKLast[k] = new double[dimension];
293dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
294dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
295dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    v = new double[7][];
296dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    for (int k = 0; k < v.length; ++k) {
297dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      v[k]  = new double[dimension];
298dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
299dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
300dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    vectorsInitialized = false;
301dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
302dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond  }
303dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
304dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond  /** {@inheritDoc} */
305dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond  @Override
306dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond  public void storeTime(final double t) {
307dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    super.storeTime(t);
308dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    vectorsInitialized = false;
309dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond  }
310dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
311dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond  /** {@inheritDoc} */
312dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond  @Override
313dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond  protected void computeInterpolatedStateAndDerivatives(final double theta,
314dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                                          final double oneMinusThetaH)
315dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    throws DerivativeException {
316dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
317dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    if (! vectorsInitialized) {
318dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
319dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      if (v == null) {
320dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        v = new double[7][];
321dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        for (int k = 0; k < 7; ++k) {
322dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond          v[k] = new double[interpolatedState.length];
323dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
324dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      }
325dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
326dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      // perform the last evaluations if they have not been done yet
327dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      finalizeStep();
328dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
329dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      // compute the interpolation vectors for this time step
330dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      for (int i = 0; i < interpolatedState.length; ++i) {
331dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond          final double yDot1  = yDotK[0][i];
332dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond          final double yDot6  = yDotK[5][i];
333dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond          final double yDot7  = yDotK[6][i];
334dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond          final double yDot8  = yDotK[7][i];
335dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond          final double yDot9  = yDotK[8][i];
336dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond          final double yDot10 = yDotK[9][i];
337dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond          final double yDot11 = yDotK[10][i];
338dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond          final double yDot12 = yDotK[11][i];
339dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond          final double yDot13 = yDotK[12][i];
340dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond          final double yDot14 = yDotKLast[0][i];
341dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond          final double yDot15 = yDotKLast[1][i];
342dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond          final double yDot16 = yDotKLast[2][i];
343dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond          v[0][i] = B_01 * yDot1  + B_06 * yDot6 + B_07 * yDot7 +
344dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                    B_08 * yDot8  + B_09 * yDot9 + B_10 * yDot10 +
345dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                    B_11 * yDot11 + B_12 * yDot12;
346dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond          v[1][i] = yDot1 - v[0][i];
347dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond          v[2][i] = v[0][i] - v[1][i] - yDotK[12][i];
348dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond          for (int k = 0; k < D.length; ++k) {
349dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond              v[k+3][i] = D[k][0] * yDot1  + D[k][1]  * yDot6  + D[k][2]  * yDot7  +
350dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                          D[k][3] * yDot8  + D[k][4]  * yDot9  + D[k][5]  * yDot10 +
351dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                          D[k][6] * yDot11 + D[k][7]  * yDot12 + D[k][8]  * yDot13 +
352dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                          D[k][9] * yDot14 + D[k][10] * yDot15 + D[k][11] * yDot16;
353dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond          }
354dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      }
355dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
356dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      vectorsInitialized = true;
357dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
358dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
359dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
360dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    final double eta      = 1 - theta;
361dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    final double twoTheta = 2 * theta;
362dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    final double theta2   = theta * theta;
363dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    final double dot1 = 1 - twoTheta;
364dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    final double dot2 = theta * (2 - 3 * theta);
365dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    final double dot3 = twoTheta * (1 + theta * (twoTheta -3));
366dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    final double dot4 = theta2 * (3 + theta * (5 * theta - 8));
367dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    final double dot5 = theta2 * (3 + theta * (-12 + theta * (15 - 6 * theta)));
368dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    final double dot6 = theta2 * theta * (4 + theta * (-15 + theta * (18 - 7 * theta)));
369dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
370dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    for (int i = 0; i < interpolatedState.length; ++i) {
371dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      interpolatedState[i] = currentState[i] -
372dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                             oneMinusThetaH * (v[0][i] -
373dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                                               theta * (v[1][i] +
374dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                                                        theta * (v[2][i] +
375dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                                                                 eta * (v[3][i] +
376dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                                                                        theta * (v[4][i] +
377dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                                                                                 eta * (v[5][i] +
378dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                                                                                        theta * (v[6][i])))))));
379dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      interpolatedDerivatives[i] =  v[0][i] + dot1 * v[1][i] + dot2 * v[2][i] +
380dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                                    dot3 * v[3][i] + dot4 * v[4][i] +
381dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                                    dot5 * v[5][i] + dot6 * v[6][i];
382dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
383dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
384dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond  }
385dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
386dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond  /** {@inheritDoc} */
387dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond  @Override
388dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond  protected void doFinalize()
389dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    throws DerivativeException {
390dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
391dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    if (currentState == null) {
392dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      // we are finalizing an uninitialized instance
393dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      return;
394dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
395dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
396dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    double s;
397dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    final double[] yTmp = new double[currentState.length];
398dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    final double pT = getGlobalPreviousTime();
399dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
400dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    // k14
401dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    for (int j = 0; j < currentState.length; ++j) {
402dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      s = K14_01 * yDotK[0][j]  + K14_06 * yDotK[5][j]  + K14_07 * yDotK[6][j] +
403dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond          K14_08 * yDotK[7][j]  + K14_09 * yDotK[8][j]  + K14_10 * yDotK[9][j] +
404dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond          K14_11 * yDotK[10][j] + K14_12 * yDotK[11][j] + K14_13 * yDotK[12][j];
405dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      yTmp[j] = currentState[j] + h * s;
406dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
407dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    integrator.computeDerivatives(pT + C14 * h, yTmp, yDotKLast[0]);
408dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
409dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    // k15
410dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    for (int j = 0; j < currentState.length; ++j) {
411dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     s = K15_01 * yDotK[0][j]  + K15_06 * yDotK[5][j]  + K15_07 * yDotK[6][j] +
412dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond         K15_08 * yDotK[7][j]  + K15_09 * yDotK[8][j]  + K15_10 * yDotK[9][j] +
413dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond         K15_11 * yDotK[10][j] + K15_12 * yDotK[11][j] + K15_13 * yDotK[12][j] +
414dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond         K15_14 * yDotKLast[0][j];
415dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     yTmp[j] = currentState[j] + h * s;
416dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
417dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    integrator.computeDerivatives(pT + C15 * h, yTmp, yDotKLast[1]);
418dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
419dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    // k16
420dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    for (int j = 0; j < currentState.length; ++j) {
421dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      s = K16_01 * yDotK[0][j]  + K16_06 * yDotK[5][j]  + K16_07 * yDotK[6][j] +
422dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond          K16_08 * yDotK[7][j]  + K16_09 * yDotK[8][j]  + K16_10 * yDotK[9][j] +
423dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond          K16_11 * yDotK[10][j] + K16_12 * yDotK[11][j] + K16_13 * yDotK[12][j] +
424dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond          K16_14 * yDotKLast[0][j] +  K16_15 * yDotKLast[1][j];
425dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      yTmp[j] = currentState[j] + h * s;
426dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
427dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    integrator.computeDerivatives(pT + C16 * h, yTmp, yDotKLast[2]);
428dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
429dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond  }
430dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
431dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond  /** {@inheritDoc} */
432dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond  @Override
433dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond  public void writeExternal(final ObjectOutput out)
434dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    throws IOException {
435dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
436dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    try {
437dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      // save the local attributes
438dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      finalizeStep();
439dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    } catch (DerivativeException e) {
440dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        IOException ioe = new IOException(e.getLocalizedMessage());
441dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        ioe.initCause(e);
442dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        throw ioe;
443dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
444dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    final int dimension = (currentState == null) ? -1 : currentState.length;
445dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    out.writeInt(dimension);
446dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    for (int i = 0; i < dimension; ++i) {
447dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      out.writeDouble(yDotKLast[0][i]);
448dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      out.writeDouble(yDotKLast[1][i]);
449dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      out.writeDouble(yDotKLast[2][i]);
450dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
451dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
452dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    // save the state of the base class
453dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    super.writeExternal(out);
454dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
455dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond  }
456dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
457dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond  /** {@inheritDoc} */
458dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond  @Override
459dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond  public void readExternal(final ObjectInput in)
460dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    throws IOException {
461dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
462dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    // read the local attributes
463dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    yDotKLast = new double[3][];
464dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    final int dimension = in.readInt();
465dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    yDotKLast[0] = (dimension < 0) ? null : new double[dimension];
466dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    yDotKLast[1] = (dimension < 0) ? null : new double[dimension];
467dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    yDotKLast[2] = (dimension < 0) ? null : new double[dimension];
468dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
469dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    for (int i = 0; i < dimension; ++i) {
470dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      yDotKLast[0][i] = in.readDouble();
471dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      yDotKLast[1][i] = in.readDouble();
472dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      yDotKLast[2][i] = in.readDouble();
473dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
474dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
475dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    // read the base state
476dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    super.readExternal(in);
477dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
478dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond  }
479dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
480dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond}
481