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.sampling; 19dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 20dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport java.io.IOException; 21dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport java.io.ObjectInput; 22dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport java.io.ObjectOutput; 23dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 24dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.ode.DerivativeException; 25dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 26dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond/** This abstract class represents an interpolator over the last step 27dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * during an ODE integration. 28dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 29dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p>The various ODE integrators provide objects extending this class 30dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * to the step handlers. The handlers can use these objects to 31dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * retrieve the state vector at intermediate times between the 32dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * previous and the current grid points (dense output).</p> 33dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 34dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @see org.apache.commons.math.ode.FirstOrderIntegrator 35dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @see org.apache.commons.math.ode.SecondOrderIntegrator 36dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @see StepHandler 37dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 38dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ 39dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @since 1.2 40dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 41dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 42dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 43dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondpublic abstract class AbstractStepInterpolator 44dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond implements StepInterpolator { 45dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 46dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** current time step */ 47dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond protected double h; 48dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 49dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** current state */ 50dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond protected double[] currentState; 51dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 52dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** interpolated time */ 53dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond protected double interpolatedTime; 54dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 55dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** interpolated state */ 56dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond protected double[] interpolatedState; 57dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 58dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** interpolated derivatives */ 59dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond protected double[] interpolatedDerivatives; 60dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 61dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** global previous time */ 62dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private double globalPreviousTime; 63dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 64dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** global current time */ 65dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private double globalCurrentTime; 66dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 67dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** soft previous time */ 68dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private double softPreviousTime; 69dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 70dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** soft current time */ 71dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private double softCurrentTime; 72dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 73dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** indicate if the step has been finalized or not. */ 74dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private boolean finalized; 75dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 76dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** integration direction. */ 77dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private boolean forward; 78dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 79dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** indicator for dirty state. */ 80dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private boolean dirtyState; 81dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 82dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 83dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Simple constructor. 84dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * This constructor builds an instance that is not usable yet, the 85dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * {@link #reinitialize} method should be called before using the 86dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * instance in order to initialize the internal arrays. This 87dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * constructor is used only in order to delay the initialization in 88dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * some cases. As an example, the {@link 89dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * org.apache.commons.math.ode.nonstiff.EmbeddedRungeKuttaIntegrator} 90dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * class uses the prototyping design pattern to create the step 91dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * interpolators by cloning an uninitialized model and latter 92dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * initializing the copy. 93dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 94dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond protected AbstractStepInterpolator() { 95dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond globalPreviousTime = Double.NaN; 96dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond globalCurrentTime = Double.NaN; 97dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond softPreviousTime = Double.NaN; 98dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond softCurrentTime = Double.NaN; 99dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond h = Double.NaN; 100dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond interpolatedTime = Double.NaN; 101dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond currentState = null; 102dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond interpolatedState = null; 103dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond interpolatedDerivatives = null; 104dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond finalized = false; 105dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond this.forward = true; 106dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond this.dirtyState = true; 107dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 108dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 109dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Simple constructor. 110dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param y reference to the integrator array holding the state at 111dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * the end of the step 112dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param forward integration direction indicator 113dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 114dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond protected AbstractStepInterpolator(final double[] y, final boolean forward) { 115dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 116dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond globalPreviousTime = Double.NaN; 117dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond globalCurrentTime = Double.NaN; 118dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond softPreviousTime = Double.NaN; 119dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond softCurrentTime = Double.NaN; 120dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond h = Double.NaN; 121dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond interpolatedTime = Double.NaN; 122dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 123dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond currentState = y; 124dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond interpolatedState = new double[y.length]; 125dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond interpolatedDerivatives = new double[y.length]; 126dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 127dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond finalized = false; 128dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond this.forward = forward; 129dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond this.dirtyState = true; 130dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 131dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 132dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 133dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Copy constructor. 134dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 135dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p>The copied interpolator should have been finalized before the 136dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * copy, otherwise the copy will not be able to perform correctly 137dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * any derivative computation and will throw a {@link 138dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * NullPointerException} later. Since we don't want this constructor 139dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * to throw the exceptions finalization may involve and since we 140dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * don't want this method to modify the state of the copied 141dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * interpolator, finalization is <strong>not</strong> done 142dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * automatically, it remains under user control.</p> 143dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 144dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p>The copy is a deep copy: its arrays are separated from the 145dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * original arrays of the instance.</p> 146dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 147dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param interpolator interpolator to copy from. 148dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 149dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 150dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond protected AbstractStepInterpolator(final AbstractStepInterpolator interpolator) { 151dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 152dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond globalPreviousTime = interpolator.globalPreviousTime; 153dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond globalCurrentTime = interpolator.globalCurrentTime; 154dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond softPreviousTime = interpolator.softPreviousTime; 155dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond softCurrentTime = interpolator.softCurrentTime; 156dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond h = interpolator.h; 157dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond interpolatedTime = interpolator.interpolatedTime; 158dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 159dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (interpolator.currentState != null) { 160dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond currentState = interpolator.currentState.clone(); 161dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond interpolatedState = interpolator.interpolatedState.clone(); 162dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond interpolatedDerivatives = interpolator.interpolatedDerivatives.clone(); 163dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 164dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond currentState = null; 165dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond interpolatedState = null; 166dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond interpolatedDerivatives = null; 167dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 168dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 169dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond finalized = interpolator.finalized; 170dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond forward = interpolator.forward; 171dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond dirtyState = interpolator.dirtyState; 172dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 173dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 174dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 175dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Reinitialize the instance 176dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param y reference to the integrator array holding the state at 177dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * the end of the step 178dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param isForward integration direction indicator 179dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 180dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond protected void reinitialize(final double[] y, final boolean isForward) { 181dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 182dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond globalPreviousTime = Double.NaN; 183dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond globalCurrentTime = Double.NaN; 184dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond softPreviousTime = Double.NaN; 185dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond softCurrentTime = Double.NaN; 186dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond h = Double.NaN; 187dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond interpolatedTime = Double.NaN; 188dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 189dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond currentState = y; 190dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond interpolatedState = new double[y.length]; 191dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond interpolatedDerivatives = new double[y.length]; 192dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 193dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond finalized = false; 194dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond this.forward = isForward; 195dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond this.dirtyState = true; 196dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 197dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 198dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 199dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** {@inheritDoc} */ 200dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public StepInterpolator copy() throws DerivativeException { 201dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 202dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // finalize the step before performing copy 203dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond finalizeStep(); 204dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 205dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // create the new independent instance 206dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return doCopy(); 207dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 208dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 209dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 210dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Really copy the finalized instance. 211dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p>This method is called by {@link #copy()} after the 212dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * step has been finalized. It must perform a deep copy 213dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * to have an new instance completely independent for the 214dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * original instance. 215dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return a copy of the finalized instance 216dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 217dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond protected abstract StepInterpolator doCopy(); 218dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 219dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Shift one step forward. 220dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Copy the current time into the previous time, hence preparing the 221dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * interpolator for future calls to {@link #storeTime storeTime} 222dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 223dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public void shift() { 224dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond globalPreviousTime = globalCurrentTime; 225dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond softPreviousTime = globalPreviousTime; 226dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond softCurrentTime = globalCurrentTime; 227dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 228dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 229dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Store the current step time. 230dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param t current time 231dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 232dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public void storeTime(final double t) { 233dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 234dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond globalCurrentTime = t; 235dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond softCurrentTime = globalCurrentTime; 236dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond h = globalCurrentTime - globalPreviousTime; 237dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond setInterpolatedTime(t); 238dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 239dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // the step is not finalized anymore 240dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond finalized = false; 241dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 242dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 243dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 244dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Restrict step range to a limited part of the global step. 245dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p> 246dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * This method can be used to restrict a step and make it appear 247dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * as if the original step was smaller. Calling this method 248dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <em>only</em> changes the value returned by {@link #getPreviousTime()}, 249dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * it does not change any other property 250dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * </p> 251dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param softPreviousTime start of the restricted step 252dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @since 2.2 253dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 254dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public void setSoftPreviousTime(final double softPreviousTime) { 255dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond this.softPreviousTime = softPreviousTime; 256dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 257dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 258dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Restrict step range to a limited part of the global step. 259dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p> 260dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * This method can be used to restrict a step and make it appear 261dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * as if the original step was smaller. Calling this method 262dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <em>only</em> changes the value returned by {@link #getCurrentTime()}, 263dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * it does not change any other property 264dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * </p> 265dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param softCurrentTime end of the restricted step 266dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @since 2.2 267dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 268dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public void setSoftCurrentTime(final double softCurrentTime) { 269dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond this.softCurrentTime = softCurrentTime; 270dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 271dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 272dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 273dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Get the previous global grid point time. 274dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return previous global grid point time 275dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @since 2.2 276dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 277dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public double getGlobalPreviousTime() { 278dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return globalPreviousTime; 279dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 280dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 281dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 282dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Get the current global grid point time. 283dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return current global grid point time 284dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @since 2.2 285dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 286dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public double getGlobalCurrentTime() { 287dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return globalCurrentTime; 288dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 289dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 290dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 291dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Get the previous soft grid point time. 292dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return previous soft grid point time 293dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @see #setSoftPreviousTime(double) 294dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 295dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public double getPreviousTime() { 296dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return softPreviousTime; 297dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 298dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 299dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 300dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Get the current soft grid point time. 301dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return current soft grid point time 302dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @see #setSoftCurrentTime(double) 303dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 304dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public double getCurrentTime() { 305dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return softCurrentTime; 306dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 307dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 308dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** {@inheritDoc} */ 309dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public double getInterpolatedTime() { 310dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return interpolatedTime; 311dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 312dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 313dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** {@inheritDoc} */ 314dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public void setInterpolatedTime(final double time) { 315dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond interpolatedTime = time; 316dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond dirtyState = true; 317dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 318dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 319dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** {@inheritDoc} */ 320dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public boolean isForward() { 321dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return forward; 322dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 323dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 324dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Compute the state and derivatives at the interpolated time. 325dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * This is the main processing method that should be implemented by 326dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * the derived classes to perform the interpolation. 327dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param theta normalized interpolation abscissa within the step 328dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * (theta is zero at the previous time step and one at the current time step) 329dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param oneMinusThetaH time gap between the interpolated time and 330dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * the current time 331dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws DerivativeException this exception is propagated to the caller if the 332dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * underlying user function triggers one 333dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 334dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond protected abstract void computeInterpolatedStateAndDerivatives(double theta, 335dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double oneMinusThetaH) 336dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throws DerivativeException; 337dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 338dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** {@inheritDoc} */ 339dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public double[] getInterpolatedState() throws DerivativeException { 340dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 341dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // lazy evaluation of the state 342dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (dirtyState) { 343dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double oneMinusThetaH = globalCurrentTime - interpolatedTime; 344dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double theta = (h == 0) ? 0 : (h - oneMinusThetaH) / h; 345dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond computeInterpolatedStateAndDerivatives(theta, oneMinusThetaH); 346dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond dirtyState = false; 347dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 348dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 349dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return interpolatedState; 350dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 351dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 352dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 353dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** {@inheritDoc} */ 354dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public double[] getInterpolatedDerivatives() throws DerivativeException { 355dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 356dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // lazy evaluation of the state 357dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (dirtyState) { 358dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double oneMinusThetaH = globalCurrentTime - interpolatedTime; 359dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double theta = (h == 0) ? 0 : (h - oneMinusThetaH) / h; 360dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond computeInterpolatedStateAndDerivatives(theta, oneMinusThetaH); 361dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond dirtyState = false; 362dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 363dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 364dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return interpolatedDerivatives; 365dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 366dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 367dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 368dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 369dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Finalize the step. 370dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 371dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p>Some embedded Runge-Kutta integrators need fewer functions 372dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * evaluations than their counterpart step interpolators. These 373dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * interpolators should perform the last evaluations they need by 374dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * themselves only if they need them. This method triggers these 375dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * extra evaluations. It can be called directly by the user step 376dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * handler and it is called automatically if {@link 377dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * #setInterpolatedTime} is called.</p> 378dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 379dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p>Once this method has been called, <strong>no</strong> other 380dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * evaluation will be performed on this step. If there is a need to 381dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * have some side effects between the step handler and the 382dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * differential equations (for example update some data in the 383dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * equations once the step has been done), it is advised to call 384dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * this method explicitly from the step handler before these side 385dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * effects are set up. If the step handler induces no side effect, 386dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * then this method can safely be ignored, it will be called 387dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * transparently as needed.</p> 388dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 389dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p><strong>Warning</strong>: since the step interpolator provided 390dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * to the step handler as a parameter of the {@link 391dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * StepHandler#handleStep handleStep} is valid only for the duration 392dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * of the {@link StepHandler#handleStep handleStep} call, one cannot 393dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * simply store a reference and reuse it later. One should first 394dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * finalize the instance, then copy this finalized instance into a 395dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * new object that can be kept.</p> 396dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 397dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p>This method calls the protected <code>doFinalize</code> method 398dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * if it has never been called during this step and set a flag 399dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * indicating that it has been called once. It is the <code> 400dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * doFinalize</code> method which should perform the evaluations. 401dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * This wrapping prevents from calling <code>doFinalize</code> several 402dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * times and hence evaluating the differential equations too often. 403dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Therefore, subclasses are not allowed not reimplement it, they 404dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * should rather reimplement <code>doFinalize</code>.</p> 405dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 406dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws DerivativeException this exception is propagated to the 407dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * caller if the underlying user function triggers one 408dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 409dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public final void finalizeStep() 410dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throws DerivativeException { 411dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (! finalized) { 412dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond doFinalize(); 413dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond finalized = true; 414dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 415dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 416dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 417dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 418dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Really finalize the step. 419dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The default implementation of this method does nothing. 420dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws DerivativeException this exception is propagated to the 421dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * caller if the underlying user function triggers one 422dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 423dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond protected void doFinalize() 424dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throws DerivativeException { 425dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 426dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 427dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** {@inheritDoc} */ 428dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public abstract void writeExternal(ObjectOutput out) 429dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throws IOException; 430dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 431dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** {@inheritDoc} */ 432dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public abstract void readExternal(ObjectInput in) 433dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throws IOException, ClassNotFoundException; 434dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 435dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Save the base state of the instance. 436dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * This method performs step finalization if it has not been done 437dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * before. 438dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param out stream where to save the state 439dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @exception IOException in case of write error 440dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 441dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond protected void writeBaseExternal(final ObjectOutput out) 442dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throws IOException { 443dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 444dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (currentState == null) { 445dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond out.writeInt(-1); 446dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 447dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond out.writeInt(currentState.length); 448dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 449dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond out.writeDouble(globalPreviousTime); 450dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond out.writeDouble(globalCurrentTime); 451dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond out.writeDouble(softPreviousTime); 452dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond out.writeDouble(softCurrentTime); 453dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond out.writeDouble(h); 454dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond out.writeBoolean(forward); 455dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 456dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (currentState != null) { 457dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond for (int i = 0; i < currentState.length; ++i) { 458dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond out.writeDouble(currentState[i]); 459dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 460dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 461dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 462dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond out.writeDouble(interpolatedTime); 463dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 464dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // we do not store the interpolated state, 465dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // it will be recomputed as needed after reading 466dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 467dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // finalize the step (and don't bother saving the now true flag) 468dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond try { 469dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond finalizeStep(); 470dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } catch (DerivativeException e) { 471dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond IOException ioe = new IOException(e.getLocalizedMessage()); 472dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ioe.initCause(e); 473dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throw ioe; 474dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 475dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 476dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 477dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 478dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Read the base state of the instance. 479dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * This method does <strong>neither</strong> set the interpolated 480dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * time nor state. It is up to the derived class to reset it 481dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * properly calling the {@link #setInterpolatedTime} method later, 482dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * once all rest of the object state has been set up properly. 483dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param in stream where to read the state from 484dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return interpolated time be set later by the caller 485dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @exception IOException in case of read error 486dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 487dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond protected double readBaseExternal(final ObjectInput in) 488dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throws IOException { 489dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 490dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final int dimension = in.readInt(); 491dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond globalPreviousTime = in.readDouble(); 492dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond globalCurrentTime = in.readDouble(); 493dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond softPreviousTime = in.readDouble(); 494dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond softCurrentTime = in.readDouble(); 495dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond h = in.readDouble(); 496dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond forward = in.readBoolean(); 497dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond dirtyState = true; 498dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 499dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (dimension < 0) { 500dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond currentState = null; 501dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 502dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond currentState = new double[dimension]; 503dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond for (int i = 0; i < currentState.length; ++i) { 504dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond currentState[i] = in.readDouble(); 505dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 506dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 507dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 508dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // we do NOT handle the interpolated time and state here 509dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond interpolatedTime = Double.NaN; 510dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond interpolatedState = (dimension < 0) ? null : new double[dimension]; 511dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond interpolatedDerivatives = (dimension < 0) ? null : new double[dimension]; 512dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 513dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond finalized = true; 514dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 515dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return in.readDouble(); 516dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 517dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 518dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 519dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond} 520