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 (double[] doubles : secondaryState) {
185 System.arraycopy(doubles, 0,
186 completeState, offset,
187 doubles.length);
188 offset += doubles.length;
189 }
190 }
191 return completeState;
192 }
193
194 }