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