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 /** This class converts second order differential equations to first 26 * order ones. 27 * 28 * <p>This class is a wrapper around a {@link SecondOrderODE} which 29 * allow to use a {@link ODEIntegrator} to integrate it.</p> 30 * 31 * <p>The transformation is done by changing the n dimension state 32 * vector to a 2n dimension vector, where the first n components are 33 * the initial state variables and the n last components are their 34 * first time derivative. The first time derivative of this state 35 * vector then really contains both the first and second time 36 * derivative of the initial state vector, which can be handled by the 37 * underlying second order equations set.</p> 38 * 39 * <p>One should be aware that the data is duplicated during the 40 * transformation process and that for each call to {@link 41 * #computeDerivatives computeDerivatives}, this wrapper does copy 4n 42 * scalars : 2n before the call to {@link 43 * SecondOrderODE#computeSecondDerivatives 44 * computeSecondDerivatives} in order to dispatch the y state vector 45 * into z and zDot, and 2n after the call to gather zDot and zDDot 46 * into yDot. Since the underlying problem by itself perhaps also 47 * needs to copy data and dispatch the arrays into domain objects, 48 * this has an impact on both memory and CPU usage. The only way to 49 * avoid this duplication is to perform the transformation at the 50 * problem level, i.e. to implement the problem as a first order one 51 * and then avoid using this class.</p> 52 * 53 * @see ODEIntegrator 54 * @see OrdinaryDifferentialEquation 55 * @see SecondOrderODE 56 */ 57 58 public class FirstOrderConverter implements OrdinaryDifferentialEquation { 59 60 /** Underlying second order equations set. */ 61 private final SecondOrderODE equations; 62 63 /** second order problem dimension. */ 64 private final int dimension; 65 66 /** Simple constructor. 67 * Build a converter around a second order equations set. 68 * @param equations second order equations set to convert 69 */ 70 public FirstOrderConverter (final SecondOrderODE equations) { 71 this.equations = equations; 72 dimension = equations.getDimension(); 73 } 74 75 /** {@inheritDoc} 76 * <p>The dimension of the first order problem is twice the 77 * dimension of the underlying second order problem.</p> 78 * @return dimension of the problem 79 */ 80 @Override 81 public int getDimension() { 82 return 2 * dimension; 83 } 84 85 /** {@inheritDoc} */ 86 @Override 87 public double[] computeDerivatives(final double t, final double[] y) { 88 89 final double[] yDot = new double[y.length]; 90 91 // split the state vector in two 92 final double[] z = new double[dimension]; 93 final double[] zDot = new double[dimension]; 94 System.arraycopy(y, 0, z, 0, dimension); 95 System.arraycopy(y, dimension, zDot, 0, dimension); 96 97 // apply the underlying equations set 98 final double[] zDDot = equations.computeSecondDerivatives(t, z, zDot); 99 100 // build the result state derivative 101 System.arraycopy(zDot, 0, yDot, 0, dimension); 102 System.arraycopy(zDDot, 0, yDot, dimension, dimension); 103 104 return yDot; 105 106 } 107 108 }