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: 620312 $ $Date: 2008-02-10 12:28:59 -0700 (Sun, 10 Feb 2008) $
53   * @since 1.2
54   */
55  
56  public class FirstOrderConverter
57    implements FirstOrderDifferentialEquations {
58  
59    /** Simple constructor.
60     * Build a converter around a second order equations set.
61     * @param equations second order equations set to convert
62     */
63    public FirstOrderConverter (SecondOrderDifferentialEquations equations) {
64        this.equations = equations;
65        dimension      = equations.getDimension();
66        z              = new double[dimension];
67        zDot           = new double[dimension];
68        zDDot          = new double[dimension];
69    }
70  
71    /** Get the dimension of the problem.
72     * <p>The dimension of the first order problem is twice the
73     * dimension of the underlying second order problem.</p>
74     * @return dimension of the problem
75     */
76    public int getDimension() {
77      return 2 * dimension;
78    }
79  
80    /** Get the current time derivative of the state vector.
81     * @param t current value of the independent <I>time</I> variable
82     * @param y array containing the current value of the state vector
83     * @param yDot placeholder array where to put the time derivative of the state vector
84     * @throws DerivativeException this exception is propagated to the caller if the
85     * underlying user function triggers one
86     */
87    public void computeDerivatives(double t, double[] y, double[] yDot)
88    throws DerivativeException {
89  
90      // split the state vector in two
91      System.arraycopy(y, 0,         z,    0, dimension);
92      System.arraycopy(y, dimension, zDot, 0, dimension);
93  
94      // apply the underlying equations set
95      equations.computeSecondDerivatives(t, z, zDot, zDDot);
96  
97      // build the result state derivative
98      System.arraycopy(zDot,  0, yDot, 0,         dimension);
99      System.arraycopy(zDDot, 0, yDot, dimension, dimension);
100     
101   }
102 
103   /** Underlying second order equations set. */
104   private SecondOrderDifferentialEquations equations;
105 
106   /** second order problem dimension. */
107   private int dimension;
108 
109   /** state vector. */
110   private double[] z;
111 
112   /** first time derivative of the state vector. */
113   private double[] zDot;
114 
115   /** second time derivative of the state vector. */
116   private double[] zDDot;
117 
118 }