1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package org.apache.commons.math.ode;
19
20 import java.io.ObjectInput;
21 import java.io.ObjectOutput;
22 import java.io.IOException;
23
24 /** This class represents an interpolator over the last step during an
25 * ODE integration for Runge-Kutta and embedded Runge-Kutta integrators.
26 *
27 * @see RungeKuttaIntegrator
28 * @see EmbeddedRungeKuttaIntegrator
29 *
30 * @version $Revision: 620312 $ $Date: 2008-02-10 12:28:59 -0700 (Sun, 10 Feb 2008) $
31 * @since 1.2
32 */
33
34 abstract class RungeKuttaStepInterpolator
35 extends AbstractStepInterpolator {
36
37 /** Simple constructor.
38 * This constructor builds an instance that is not usable yet, the
39 * {@link #reinitialize} method should be called before using the
40 * instance in order to initialize the internal arrays. This
41 * constructor is used only in order to delay the initialization in
42 * some cases. The {@link RungeKuttaIntegrator} and {@link
43 * EmbeddedRungeKuttaIntegrator} classes uses the prototyping design
44 * pattern to create the step interpolators by cloning an
45 * uninitialized model and latter initializing the copy.
46 */
47 protected RungeKuttaStepInterpolator() {
48 super();
49 yDotK = null;
50 equations = null;
51 }
52
53 /** Copy constructor.
54
55 * <p>The copied interpolator should have been finalized before the
56 * copy, otherwise the copy will not be able to perform correctly any
57 * interpolation and will throw a {@link NullPointerException}
58 * later. Since we don't want this constructor to throw the
59 * exceptions finalization may involve and since we don't want this
60 * method to modify the state of the copied interpolator,
61 * finalization is <strong>not</strong> done automatically, it
62 * remains under user control.</p>
63
64 * <p>The copy is a deep copy: its arrays are separated from the
65 * original arrays of the instance.</p>
66
67 * @param interpolator interpolator to copy from.
68
69 */
70 public RungeKuttaStepInterpolator(RungeKuttaStepInterpolator interpolator) {
71
72 super(interpolator);
73
74 if (interpolator.currentState != null) {
75 int dimension = currentState.length;
76
77 yDotK = new double[interpolator.yDotK.length][];
78 for (int k = 0; k < interpolator.yDotK.length; ++k) {
79 yDotK[k] = new double[dimension];
80 System.arraycopy(interpolator.yDotK[k], 0,
81 yDotK[k], 0, dimension);
82 }
83
84 } else {
85 yDotK = null;
86 }
87
88 // we cannot keep any reference to the equations in the copy
89 // the interpolator should have been finalized before
90 equations = null;
91
92 }
93
94 /** Reinitialize the instance
95 * <p>Some Runge-Kutta integrators need fewer functions evaluations
96 * than their counterpart step interpolators. So the interpolator
97 * should perform the last evaluations they need by themselves. The
98 * {@link RungeKuttaIntegrator RungeKuttaIntegrator} and {@link
99 * EmbeddedRungeKuttaIntegrator EmbeddedRungeKuttaIntegrator}
100 * abstract classes call this method in order to let the step
101 * interpolator perform the evaluations it needs. These evaluations
102 * will be performed during the call to <code>doFinalize</code> if
103 * any, i.e. only if the step handler either calls the {@link
104 * AbstractStepInterpolator#finalizeStep finalizeStep} method or the
105 * {@link AbstractStepInterpolator#getInterpolatedState
106 * getInterpolatedState} method (for an interpolator which needs a
107 * finalization) or if it clones the step interpolator.</p>
108 * @param equations set of differential equations being integrated
109 * @param y reference to the integrator array holding the state at
110 * the end of the step
111 * @param yDotK reference to the integrator array holding all the
112 * intermediate slopes
113 * @param forward integration direction indicator
114 */
115 public void reinitialize(FirstOrderDifferentialEquations equations,
116 double[] y, double[][] yDotK, boolean forward) {
117 reinitialize(y, forward);
118 this.yDotK = yDotK;
119 this.equations = equations;
120 }
121
122 /** Save the state of the instance.
123 * @param out stream where to save the state
124 * @exception IOException in case of write error
125 */
126 public void writeExternal(ObjectOutput out)
127 throws IOException {
128
129 // save the state of the base class
130 writeBaseExternal(out);
131
132 // save the local attributes
133 out.writeInt(yDotK.length);
134 for (int k = 0; k < yDotK.length; ++k) {
135 for (int i = 0; i < currentState.length; ++i) {
136 out.writeDouble(yDotK[k][i]);
137 }
138 }
139
140 // we do not save any reference to the equations
141
142 }
143
144 /** Read the state of the instance.
145 * @param in stream where to read the state from
146 * @exception IOException in case of read error
147 */
148 public void readExternal(ObjectInput in)
149 throws IOException {
150
151 // read the base class
152 double t = readBaseExternal(in);
153
154 // read the local attributes
155 int kMax = in.readInt();
156 yDotK = new double[kMax][];
157 for (int k = 0; k < kMax; ++k) {
158 yDotK[k] = new double[currentState.length];
159 for (int i = 0; i < currentState.length; ++i) {
160 yDotK[k][i] = in.readDouble();
161 }
162 }
163
164 equations = null;
165
166 try {
167 // we can now set the interpolated time and state
168 setInterpolatedTime(t);
169 } catch (DerivativeException e) {
170 throw new IOException(e.getMessage());
171 }
172
173 }
174
175 /** Slopes at the intermediate points */
176 protected double[][] yDotK;
177
178 /** Reference to the differential equations beeing integrated. */
179 protected FirstOrderDifferentialEquations equations;
180
181 }