View Javadoc
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  
18  package org.hipparchus.ode;
19  
20  import java.io.Serializable;
21  
22  /** Container for time, main and secondary state vectors.
23  
24   * @see OrdinaryDifferentialEquation
25   * @see SecondaryODE
26   * @see ODEIntegrator
27   * @see ODEStateAndDerivative
28   */
29  
30  public class ODEState implements Serializable {
31  
32      /** Serializable UID. */
33      private static final long serialVersionUID = 20160408L;
34  
35      /** Time. */
36      private final double time;
37  
38      /** Primary state at time. */
39      private final double[] primaryState;
40  
41      /** Secondary state at time. */
42      private final double[][] secondaryState;
43  
44      /** Complete dimension. */
45      private final int completeDimension;
46  
47      /** Simple constructor.
48       * <p>Calling this constructor is equivalent to call {@link
49       * #ODEState(double, double[], double[][])
50       * ODEState(time, state, null)}.</p>
51       * @param time time
52       * @param primaryState primary state at time
53       */
54      public ODEState(double time, double[] primaryState) {
55          this(time, primaryState, null);
56      }
57  
58      /** Simple constructor.
59       * @param time time
60       * @param primaryState state at time
61       * @param secondaryState primary state at time (may be null)
62       */
63      public ODEState(double time, double[] primaryState, double[][] secondaryState) {
64  
65          this.time           = time;
66          this.primaryState   = primaryState.clone();
67          this.secondaryState = copy(secondaryState);
68  
69          // compute once and for all the complete dimension
70          int dimension = primaryState.length;
71          if (secondaryState != null) {
72              for (final double[] secondary : secondaryState) {
73                  dimension += secondary.length;
74              }
75          }
76          this.completeDimension = dimension;
77  
78      }
79  
80      /** Copy a two-dimensions array.
81       * @param original original array (may be null)
82       * @return copied array or null if original array was null
83       */
84      protected double[][] copy(final double[][] original) {
85  
86          // special handling of null arrays
87          if (original == null) {
88              return null; // NOPMD
89          }
90  
91          // allocate the array
92          final double[][] copied = new double[original.length][];
93  
94          // copy content
95          for (int i = 0; i < original.length; ++i) {
96              copied[i] = original[i].clone();
97          }
98  
99          return copied;
100 
101     }
102 
103     /** Get time.
104      * @return time
105      */
106     public double getTime() {
107         return time;
108     }
109 
110     /** Get primary state dimension.
111      * @return primary state dimension
112      * @see #getSecondaryStateDimension(int)
113      * @see #getCompleteStateDimension()
114      */
115     public int getPrimaryStateDimension() {
116         return primaryState.length;
117     }
118 
119     /** Get primary state at time.
120      * @return primary state at time
121      * @see #getSecondaryState(int)
122      * @see #getCompleteState()
123      */
124     public double[] getPrimaryState() {
125         return primaryState.clone();
126     }
127 
128     /** Get the number of secondary states.
129      * @return number of secondary states.
130      */
131     public int getNumberOfSecondaryStates() {
132         return secondaryState == null ? 0 : secondaryState.length;
133     }
134 
135     /** Get secondary state dimension.
136      * @param index index of the secondary set as returned
137      * by {@link ExpandableODE#addSecondaryEquations(SecondaryODE)}
138      * (beware index 0 corresponds to primary state, secondary states start at 1)
139      * @return secondary state dimension
140      * @see #getPrimaryStateDimension()
141      * @see #getCompleteStateDimension()
142      */
143     public int getSecondaryStateDimension(final int index) {
144         return index == 0 ? primaryState.length : secondaryState[index - 1].length;
145     }
146 
147     /** Get secondary state at time.
148      * @param index index of the secondary set as returned
149      * by {@link ExpandableODE#addSecondaryEquations(SecondaryODE)}
150      * (beware index 0 corresponds to primary state, secondary states start at 1)
151      * @return secondary state at time
152      * @see #getPrimaryState()
153      * @see #getCompleteState()
154      */
155     public double[] getSecondaryState(final int index) {
156         return index == 0 ? primaryState.clone() : secondaryState[index - 1].clone();
157     }
158 
159     /** Return the dimension of the complete set of equations.
160      * <p>
161      * The complete set of equations correspond to the primary set plus all secondary sets.
162      * </p>
163      * @return dimension of the complete set of equations
164      * @see #getPrimaryStateDimension()
165      * @see #getSecondaryStateDimension(int)
166      */
167     public int getCompleteStateDimension() {
168         return completeDimension;
169     }
170 
171     /** Get complete state at time.
172      * @return complete state at time, starting with
173      * {@link #getPrimaryState() primary state}, followed
174      * by all {@link #getSecondaryState(int) secondary states} in
175      * increasing index order
176      * @see #getPrimaryState()
177      * @see #getSecondaryState(int)
178      */
179     public double[] getCompleteState() {
180         final double[] completeState = new double[getCompleteStateDimension()];
181         System.arraycopy(primaryState, 0, completeState, 0, primaryState.length);
182         int offset = primaryState.length;
183         if (secondaryState != null) {
184             for (int index = 0; index < secondaryState.length; ++index) {
185                 System.arraycopy(secondaryState[index], 0,
186                                  completeState, offset,
187                                  secondaryState[index].length);
188                 offset += secondaryState[index].length;
189             }
190         }
191         return completeState;
192     }
193 
194 }