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  /** 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 }