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    *      http://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.apache.commons.math.ode;
19  
20  /** This class converts second order differential equations to first
21   * order ones.
22   *
23   * <p>This class is a wrapper around a {@link
24   * SecondOrderDifferentialEquations} which allow to use a {@link
25   * FirstOrderIntegrator} to integrate it.</p>
26   *
27   * <p>The transformation is done by changing the n dimension state
28   * vector to a 2n dimension vector, where the first n components are
29   * the initial state variables and the n last components are their
30   * first time derivative. The first time derivative of this state
31   * vector then really contains both the first and second time
32   * derivative of the initial state vector, which can be handled by the
33   * underlying second order equations set.</p>
34   *
35   * <p>One should be aware that the data is duplicated during the
36   * transformation process and that for each call to {@link
37   * #computeDerivatives computeDerivatives}, this wrapper does copy 4n
38   * scalars : 2n before the call to {@link
39   * SecondOrderDifferentialEquations#computeSecondDerivatives
40   * computeSecondDerivatives} in order to dispatch the y state vector
41   * into z and zDot, and 2n after the call to gather zDot and zDDot
42   * into yDot. Since the underlying problem by itself perhaps also
43   * needs to copy data and dispatch the arrays into domain objects,
44   * this has an impact on both memory and CPU usage. The only way to
45   * avoid this duplication is to perform the transformation at the
46   * problem level, i.e. to implement the problem as a first order one
47   * and then avoid using this class.</p>
48   *
49   * @see FirstOrderIntegrator
50   * @see FirstOrderDifferentialEquations
51   * @see SecondOrderDifferentialEquations
52   * @version $Revision: 786881 $ $Date: 2009-06-20 14:53:08 -0400 (Sat, 20 Jun 2009) $
53   * @since 1.2
54   */
55  
56  public class FirstOrderConverter implements FirstOrderDifferentialEquations {
57  
58    /** Simple constructor.
59     * Build a converter around a second order equations set.
60     * @param equations second order equations set to convert
61     */
62    public FirstOrderConverter (final SecondOrderDifferentialEquations equations) {
63        this.equations = equations;
64        dimension      = equations.getDimension();
65        z              = new double[dimension];
66        zDot           = new double[dimension];
67        zDDot          = new double[dimension];
68    }
69  
70    /** Get the dimension of the problem.
71     * <p>The dimension of the first order problem is twice the
72     * dimension of the underlying second order problem.</p>
73     * @return dimension of the problem
74     */
75    public int getDimension() {
76      return 2 * dimension;
77    }
78  
79    /** Get the current time derivative of the state vector.
80     * @param t current value of the independent <I>time</I> variable
81     * @param y array containing the current value of the state vector
82     * @param yDot placeholder array where to put the time derivative of the state vector
83     * @throws DerivativeException this exception is propagated to the caller if the
84     * underlying user function triggers one
85     */
86    public void computeDerivatives(final double t, final double[] y, final double[] yDot)
87        throws DerivativeException {
88  
89      // split the state vector in two
90      System.arraycopy(y, 0,         z,    0, dimension);
91      System.arraycopy(y, dimension, zDot, 0, dimension);
92  
93      // apply the underlying equations set
94      equations.computeSecondDerivatives(t, z, zDot, zDDot);
95  
96      // build the result state derivative
97      System.arraycopy(zDot,  0, yDot, 0,         dimension);
98      System.arraycopy(zDDot, 0, yDot, dimension, dimension);
99      
100   }
101 
102   /** Underlying second order equations set. */
103   private SecondOrderDifferentialEquations equations;
104 
105   /** second order problem dimension. */
106   private int dimension;
107 
108   /** state vector. */
109   private double[] z;
110 
111   /** first time derivative of the state vector. */
112   private double[] zDot;
113 
114   /** second time derivative of the state vector. */
115   private double[] zDDot;
116 
117 }