ODEState.java

  1. /*
  2.  * Licensed to the Hipparchus project 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 Hipparchus project 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.  *      https://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. package org.hipparchus.ode;

  18. import java.io.Serializable;

  19. /** Container for time, main and secondary state vectors.

  20.  * @see OrdinaryDifferentialEquation
  21.  * @see SecondaryODE
  22.  * @see ODEIntegrator
  23.  * @see ODEStateAndDerivative
  24.  */

  25. public class ODEState implements Serializable {

  26.     /** Serializable UID. */
  27.     private static final long serialVersionUID = 20160408L;

  28.     /** Time. */
  29.     private final double time;

  30.     /** Primary state at time. */
  31.     private final double[] primaryState;

  32.     /** Secondary state at time. */
  33.     private final double[][] secondaryState;

  34.     /** Complete dimension. */
  35.     private final int completeDimension;

  36.     /** Simple constructor.
  37.      * <p>Calling this constructor is equivalent to call {@link
  38.      * #ODEState(double, double[], double[][])
  39.      * ODEState(time, state, null)}.</p>
  40.      * @param time time
  41.      * @param primaryState primary state at time
  42.      */
  43.     public ODEState(double time, double[] primaryState) {
  44.         this(time, primaryState, null);
  45.     }

  46.     /** Simple constructor.
  47.      * @param time time
  48.      * @param primaryState state at time
  49.      * @param secondaryState primary state at time (may be null)
  50.      */
  51.     public ODEState(double time, double[] primaryState, double[][] secondaryState) {

  52.         this.time           = time;
  53.         this.primaryState   = primaryState.clone();
  54.         this.secondaryState = copy(secondaryState);

  55.         // compute once and for all the complete dimension
  56.         int dimension = primaryState.length;
  57.         if (secondaryState != null) {
  58.             for (final double[] secondary : secondaryState) {
  59.                 dimension += secondary.length;
  60.             }
  61.         }
  62.         this.completeDimension = dimension;

  63.     }

  64.     /** Copy a two-dimensions array.
  65.      * @param original original array (may be null)
  66.      * @return copied array or null if original array was null
  67.      */
  68.     protected double[][] copy(final double[][] original) {

  69.         // special handling of null arrays
  70.         if (original == null) {
  71.             return null; // NOPMD
  72.         }

  73.         // allocate the array
  74.         final double[][] copied = new double[original.length][];

  75.         // copy content
  76.         for (int i = 0; i < original.length; ++i) {
  77.             copied[i] = original[i].clone();
  78.         }

  79.         return copied;

  80.     }

  81.     /** Get time.
  82.      * @return time
  83.      */
  84.     public double getTime() {
  85.         return time;
  86.     }

  87.     /** Get primary state dimension.
  88.      * @return primary state dimension
  89.      * @see #getSecondaryStateDimension(int)
  90.      * @see #getCompleteStateDimension()
  91.      */
  92.     public int getPrimaryStateDimension() {
  93.         return primaryState.length;
  94.     }

  95.     /** Get primary state at time.
  96.      * @return primary state at time
  97.      * @see #getSecondaryState(int)
  98.      * @see #getCompleteState()
  99.      */
  100.     public double[] getPrimaryState() {
  101.         return primaryState.clone();
  102.     }

  103.     /** Get the number of secondary states.
  104.      * @return number of secondary states.
  105.      */
  106.     public int getNumberOfSecondaryStates() {
  107.         return secondaryState == null ? 0 : secondaryState.length;
  108.     }

  109.     /** Get secondary state dimension.
  110.      * @param index index of the secondary set as returned
  111.      * by {@link ExpandableODE#addSecondaryEquations(SecondaryODE)}
  112.      * (beware index 0 corresponds to primary state, secondary states start at 1)
  113.      * @return secondary state dimension
  114.      * @see #getPrimaryStateDimension()
  115.      * @see #getCompleteStateDimension()
  116.      */
  117.     public int getSecondaryStateDimension(final int index) {
  118.         return index == 0 ? primaryState.length : secondaryState[index - 1].length;
  119.     }

  120.     /** Get secondary state at time.
  121.      * @param index index of the secondary set as returned
  122.      * by {@link ExpandableODE#addSecondaryEquations(SecondaryODE)}
  123.      * (beware index 0 corresponds to primary state, secondary states start at 1)
  124.      * @return secondary state at time
  125.      * @see #getPrimaryState()
  126.      * @see #getCompleteState()
  127.      */
  128.     public double[] getSecondaryState(final int index) {
  129.         return index == 0 ? primaryState.clone() : secondaryState[index - 1].clone();
  130.     }

  131.     /** Return the dimension of the complete set of equations.
  132.      * <p>
  133.      * The complete set of equations correspond to the primary set plus all secondary sets.
  134.      * </p>
  135.      * @return dimension of the complete set of equations
  136.      * @see #getPrimaryStateDimension()
  137.      * @see #getSecondaryStateDimension(int)
  138.      */
  139.     public int getCompleteStateDimension() {
  140.         return completeDimension;
  141.     }

  142.     /** Get complete state at time.
  143.      * @return complete state at time, starting with
  144.      * {@link #getPrimaryState() primary state}, followed
  145.      * by all {@link #getSecondaryState(int) secondary states} in
  146.      * increasing index order
  147.      * @see #getPrimaryState()
  148.      * @see #getSecondaryState(int)
  149.      */
  150.     public double[] getCompleteState() {
  151.         final double[] completeState = new double[getCompleteStateDimension()];
  152.         System.arraycopy(primaryState, 0, completeState, 0, primaryState.length);
  153.         int offset = primaryState.length;
  154.         if (secondaryState != null) {
  155.             for (int index = 0; index < secondaryState.length; ++index) {
  156.                 System.arraycopy(secondaryState[index], 0,
  157.                                  completeState, offset,
  158.                                  secondaryState[index].length);
  159.                 offset += secondaryState[index].length;
  160.             }
  161.         }
  162.         return completeState;
  163.     }

  164. }