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    import org.apache.commons.math.ode.DerivativeException;
025    
026    /** This class is a step interpolator that does nothing.
027     *
028     * <p>This class is used when the {@link StepHandler "step handler"}
029     * set up by the user does not need step interpolation. It does not
030     * recompute the state when {@link AbstractStepInterpolator#setInterpolatedTime
031     * setInterpolatedTime} is called. This implies the interpolated state
032     * is always the state at the end of the current step.</p>
033     *
034     * @see StepHandler
035     *
036     * @version $Revision: 919479 $ $Date: 2010-03-05 11:35:56 -0500 (Fri, 05 Mar 2010) $
037     * @since 1.2
038     */
039    
040    public class DummyStepInterpolator
041      extends AbstractStepInterpolator {
042    
043      /** Serializable version identifier. */
044      private static final long serialVersionUID = 1708010296707839488L;
045    
046      /** Current derivative. */
047      private double[] currentDerivative;
048    
049      /** Simple constructor.
050       * This constructor builds an instance that is not usable yet, the
051       * <code>AbstractStepInterpolator.reinitialize</code> protected method
052       * should be called before using the instance in order to initialize
053       * the internal arrays. This constructor is used only in order to delay
054       * the initialization in some cases. As an example, the {@link
055       * org.apache.commons.math.ode.nonstiff.EmbeddedRungeKuttaIntegrator} uses
056       * the prototyping design pattern to create the step interpolators by
057       * cloning an uninitialized model and latter initializing the copy.
058       */
059      public DummyStepInterpolator() {
060        super();
061        currentDerivative = null;
062      }
063    
064      /** Simple constructor.
065       * @param y reference to the integrator array holding the state at
066       * the end of the step
067       * @param yDot reference to the integrator array holding the state
068       * derivative at some arbitrary point within the step
069       * @param forward integration direction indicator
070       */
071      public DummyStepInterpolator(final double[] y, final double[] yDot, final boolean forward) {
072        super(y, forward);
073        currentDerivative = yDot;
074      }
075    
076      /** Copy constructor.
077       * @param interpolator interpolator to copy from. The copy is a deep
078       * copy: its arrays are separated from the original arrays of the
079       * instance
080       */
081      public DummyStepInterpolator(final DummyStepInterpolator interpolator) {
082        super(interpolator);
083        currentDerivative = interpolator.currentDerivative.clone();
084      }
085    
086      /** Really copy the finalized instance.
087       * @return a copy of the finalized instance
088       */
089      @Override
090      protected StepInterpolator doCopy() {
091        return new DummyStepInterpolator(this);
092      }
093    
094      /** Compute the state at the interpolated time.
095       * In this class, this method does nothing: the interpolated state
096       * is always the state at the end of the current step.
097       * @param theta normalized interpolation abscissa within the step
098       * (theta is zero at the previous time step and one at the current time step)
099       * @param oneMinusThetaH time gap between the interpolated time and
100       * the current time
101       * @throws DerivativeException this exception is propagated to the caller if the
102       * underlying user function triggers one
103       */
104      @Override
105      protected void computeInterpolatedStateAndDerivatives(final double theta, final double oneMinusThetaH)
106        throws DerivativeException {
107          System.arraycopy(currentState,      0, interpolatedState,       0, currentState.length);
108          System.arraycopy(currentDerivative, 0, interpolatedDerivatives, 0, currentDerivative.length);
109      }
110    
111      /** Write the instance to an output channel.
112       * @param out output channel
113       * @exception IOException if the instance cannot be written
114       */
115      @Override
116      public void writeExternal(final ObjectOutput out)
117        throws IOException {
118    
119          // save the state of the base class
120        writeBaseExternal(out);
121    
122        if (currentDerivative != null) {
123            for (int i = 0; i < currentDerivative.length; ++i) {
124                out.writeDouble(currentDerivative[i]);
125            }
126        }
127    
128      }
129    
130      /** Read the instance from an input channel.
131       * @param in input channel
132       * @exception IOException if the instance cannot be read
133       */
134      @Override
135      public void readExternal(final ObjectInput in)
136        throws IOException {
137    
138        // read the base class
139        final double t = readBaseExternal(in);
140    
141        if (currentState == null) {
142            currentDerivative = null;
143        } else {
144            currentDerivative  = new double[currentState.length];
145            for (int i = 0; i < currentDerivative.length; ++i) {
146                currentDerivative[i] = in.readDouble();
147            }
148        }
149    
150        // we can now set the interpolated time and state
151        setInterpolatedTime(t);
152    
153      }
154    
155    }