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 }