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 }