001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    
018    package org.apache.commons.math.ode.sampling;
019    
020    import java.io.IOException;
021    import java.io.ObjectInput;
022    import java.io.ObjectOutput;
023    
024    /** This class is a step interpolator that does nothing.
025     *
026     * <p>This class is used when the {@link StepHandler "step handler"}
027     * set up by the user does not need step interpolation. It does not
028     * recompute the state when {@link AbstractStepInterpolator#setInterpolatedTime
029     * setInterpolatedTime} is called. This implies the interpolated state
030     * is always the state at the end of the current step.</p>
031     *
032     * @see StepHandler
033     *
034     * @version $Revision: 1037327 $ $Date: 2010-11-20 21:57:37 +0100 (sam. 20 nov. 2010) $
035     * @since 1.2
036     */
037    
038    public class DummyStepInterpolator
039      extends AbstractStepInterpolator {
040    
041      /** Serializable version identifier. */
042      private static final long serialVersionUID = 1708010296707839488L;
043    
044      /** Current derivative. */
045      private double[] currentDerivative;
046    
047      /** Simple constructor.
048       * This constructor builds an instance that is not usable yet, the
049       * <code>AbstractStepInterpolator.reinitialize</code> protected method
050       * should be called before using the instance in order to initialize
051       * the internal arrays. This constructor is used only in order to delay
052       * the initialization in some cases. As an example, the {@link
053       * org.apache.commons.math.ode.nonstiff.EmbeddedRungeKuttaIntegrator} uses
054       * the prototyping design pattern to create the step interpolators by
055       * cloning an uninitialized model and latter initializing the copy.
056       */
057      public DummyStepInterpolator() {
058        super();
059        currentDerivative = null;
060      }
061    
062      /** Simple constructor.
063       * @param y reference to the integrator array holding the state at
064       * the end of the step
065       * @param yDot reference to the integrator array holding the state
066       * derivative at some arbitrary point within the step
067       * @param forward integration direction indicator
068       */
069      public DummyStepInterpolator(final double[] y, final double[] yDot, final boolean forward) {
070        super(y, forward);
071        currentDerivative = yDot;
072      }
073    
074      /** Copy constructor.
075       * @param interpolator interpolator to copy from. The copy is a deep
076       * copy: its arrays are separated from the original arrays of the
077       * instance
078       */
079      public DummyStepInterpolator(final DummyStepInterpolator interpolator) {
080        super(interpolator);
081        currentDerivative = interpolator.currentDerivative.clone();
082      }
083    
084      /** Really copy the finalized instance.
085       * @return a copy of the finalized instance
086       */
087      @Override
088      protected StepInterpolator doCopy() {
089        return new DummyStepInterpolator(this);
090      }
091    
092      /** Compute the state at the interpolated time.
093       * In this class, this method does nothing: the interpolated state
094       * is always the state at the end of the current step.
095       * @param theta normalized interpolation abscissa within the step
096       * (theta is zero at the previous time step and one at the current time step)
097       * @param oneMinusThetaH time gap between the interpolated time and
098       * the current time
099       */
100      @Override
101      protected void computeInterpolatedStateAndDerivatives(final double theta, final double oneMinusThetaH) {
102          System.arraycopy(currentState,      0, interpolatedState,       0, currentState.length);
103          System.arraycopy(currentDerivative, 0, interpolatedDerivatives, 0, currentDerivative.length);
104      }
105    
106      /** Write the instance to an output channel.
107       * @param out output channel
108       * @exception IOException if the instance cannot be written
109       */
110      @Override
111      public void writeExternal(final ObjectOutput out)
112        throws IOException {
113    
114          // save the state of the base class
115        writeBaseExternal(out);
116    
117        if (currentDerivative != null) {
118            for (int i = 0; i < currentDerivative.length; ++i) {
119                out.writeDouble(currentDerivative[i]);
120            }
121        }
122    
123      }
124    
125      /** Read the instance from an input channel.
126       * @param in input channel
127       * @exception IOException if the instance cannot be read
128       */
129      @Override
130      public void readExternal(final ObjectInput in)
131        throws IOException {
132    
133        // read the base class
134        final double t = readBaseExternal(in);
135    
136        if (currentState == null) {
137            currentDerivative = null;
138        } else {
139            currentDerivative  = new double[currentState.length];
140            for (int i = 0; i < currentDerivative.length; ++i) {
141                currentDerivative[i] = in.readDouble();
142            }
143        }
144    
145        // we can now set the interpolated time and state
146        setInterpolatedTime(t);
147    
148      }
149    
150    }