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