All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.commons.math3.ode.nonstiff.RungeKuttaStepInterpolator Maven / Gradle / Ivy

Go to download

The Apache Commons Math project is a library of lightweight, self-contained mathematics and statistics components addressing the most common practical problems not immediately available in the Java programming language or commons-lang.

There is a newer version: 62
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.commons.math3.ode.nonstiff;

import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;

import org.apache.commons.math3.ode.AbstractIntegrator;
import org.apache.commons.math3.ode.EquationsMapper;
import org.apache.commons.math3.ode.sampling.AbstractStepInterpolator;

/** This class represents an interpolator over the last step during an
 * ODE integration for Runge-Kutta and embedded Runge-Kutta integrators.
 *
 * @see RungeKuttaIntegrator
 * @see EmbeddedRungeKuttaIntegrator
 *
 * @since 1.2
 */

abstract class RungeKuttaStepInterpolator
  extends AbstractStepInterpolator {

    /** Previous state. */
    protected double[] previousState;

    /** Slopes at the intermediate points */
    protected double[][] yDotK;

    /** Reference to the integrator. */
    protected AbstractIntegrator integrator;

  /** Simple constructor.
   * This constructor builds an instance that is not usable yet, the
   * {@link #reinitialize} method should be called before using the
   * instance in order to initialize the internal arrays. This
   * constructor is used only in order to delay the initialization in
   * some cases. The {@link RungeKuttaIntegrator} and {@link
   * EmbeddedRungeKuttaIntegrator} classes use the prototyping design
   * pattern to create the step interpolators by cloning an
   * uninitialized model and latter initializing the copy.
   */
  protected RungeKuttaStepInterpolator() {
    previousState = null;
    yDotK         = null;
    integrator    = null;
  }

  /** Copy constructor.

  * 

The copied interpolator should have been finalized before the * copy, otherwise the copy will not be able to perform correctly any * interpolation and will throw a {@link NullPointerException} * later. Since we don't want this constructor to throw the * exceptions finalization may involve and since we don't want this * method to modify the state of the copied interpolator, * finalization is not done automatically, it * remains under user control.

*

The copy is a deep copy: its arrays are separated from the * original arrays of the instance.

* @param interpolator interpolator to copy from. */ RungeKuttaStepInterpolator(final RungeKuttaStepInterpolator interpolator) { super(interpolator); if (interpolator.currentState != null) { previousState = interpolator.previousState.clone(); yDotK = new double[interpolator.yDotK.length][]; for (int k = 0; k < interpolator.yDotK.length; ++k) { yDotK[k] = interpolator.yDotK[k].clone(); } } else { previousState = null; yDotK = null; } // we cannot keep any reference to the equations in the copy // the interpolator should have been finalized before integrator = null; } /** Reinitialize the instance *

Some Runge-Kutta integrators need fewer functions evaluations * than their counterpart step interpolators. So the interpolator * should perform the last evaluations they need by themselves. The * {@link RungeKuttaIntegrator RungeKuttaIntegrator} and {@link * EmbeddedRungeKuttaIntegrator EmbeddedRungeKuttaIntegrator} * abstract classes call this method in order to let the step * interpolator perform the evaluations it needs. These evaluations * will be performed during the call to doFinalize if * any, i.e. only if the step handler either calls the {@link * AbstractStepInterpolator#finalizeStep finalizeStep} method or the * {@link AbstractStepInterpolator#getInterpolatedState * getInterpolatedState} method (for an interpolator which needs a * finalization) or if it clones the step interpolator.

* @param rkIntegrator integrator being used * @param y reference to the integrator array holding the state at * the end of the step * @param yDotArray reference to the integrator array holding all the * intermediate slopes * @param forward integration direction indicator * @param primaryMapper equations mapper for the primary equations set * @param secondaryMappers equations mappers for the secondary equations sets */ public void reinitialize(final AbstractIntegrator rkIntegrator, final double[] y, final double[][] yDotArray, final boolean forward, final EquationsMapper primaryMapper, final EquationsMapper[] secondaryMappers) { reinitialize(y, forward, primaryMapper, secondaryMappers); this.previousState = null; this.yDotK = yDotArray; this.integrator = rkIntegrator; } /** {@inheritDoc} */ @Override public void shift() { previousState = currentState.clone(); super.shift(); } /** {@inheritDoc} */ @Override public void writeExternal(final ObjectOutput out) throws IOException { // save the state of the base class writeBaseExternal(out); // save the local attributes final int n = (currentState == null) ? -1 : currentState.length; for (int i = 0; i < n; ++i) { out.writeDouble(previousState[i]); } final int kMax = (yDotK == null) ? -1 : yDotK.length; out.writeInt(kMax); for (int k = 0; k < kMax; ++k) { for (int i = 0; i < n; ++i) { out.writeDouble(yDotK[k][i]); } } // we do not save any reference to the equations } /** {@inheritDoc} */ @Override public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException { // read the base class final double t = readBaseExternal(in); // read the local attributes final int n = (currentState == null) ? -1 : currentState.length; if (n < 0) { previousState = null; } else { previousState = new double[n]; for (int i = 0; i < n; ++i) { previousState[i] = in.readDouble(); } } final int kMax = in.readInt(); yDotK = (kMax < 0) ? null : new double[kMax][]; for (int k = 0; k < kMax; ++k) { yDotK[k] = (n < 0) ? null : new double[n]; for (int i = 0; i < n; ++i) { yDotK[k][i] = in.readDouble(); } } integrator = null; if (currentState != null) { // we can now set the interpolated time and state setInterpolatedTime(t); } else { interpolatedTime = t; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy