001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    
018    package org.apache.commons.math.ode;
019    
020    import org.apache.commons.math.ode.FirstOrderDifferentialEquations;
021    import org.apache.commons.math.ode.events.EventHandler;
022    
023    /**
024     * This class is used as the base class of the problems that are
025     * integrated during the junit tests for the ODE integrators.
026     */
027    public abstract class TestProblemAbstract
028      implements FirstOrderDifferentialEquations {
029    
030      /** Serializable version identifier. */
031      private static final long serialVersionUID = -8521928974502839379L;
032    
033      /** Dimension of the problem. */
034      protected int n;
035    
036      /** Number of functions calls. */
037      protected int calls;
038    
039      /** Initial time */
040      protected double t0;
041    
042      /** Initial state */
043      protected double[] y0;
044    
045      /** Final time */
046      protected double t1;
047    
048      /** Error scale */
049      protected double[] errorScale;
050    
051      /**
052       * Simple constructor.
053       */
054      protected TestProblemAbstract() {
055        n          = 0;
056        calls      = 0;
057        t0         = 0;
058        y0         = null;
059        t1         = 0;
060        errorScale = null;
061      }
062    
063      /**
064       * Copy constructor.
065       * @param problem problem to copy
066       */
067      protected TestProblemAbstract(TestProblemAbstract problem) {
068        n     = problem.n;
069        calls = problem.calls;
070        t0    = problem.t0;
071        if (problem.y0 == null) {
072          y0 = null;
073        } else {
074          y0 = problem.y0.clone();
075        }
076        if (problem.errorScale == null) {
077          errorScale = null;
078        } else {
079          errorScale = problem.errorScale.clone();
080        }
081        t1 = problem.t1;
082      }
083    
084      /**
085       * Copy operation.
086       * @return a copy of the instance
087       */
088      public abstract TestProblemAbstract copy();
089    
090      /**
091       * Set the initial conditions
092       * @param t0 initial time
093       * @param y0 initial state vector
094       */
095      protected void setInitialConditions(double t0, double[] y0) {
096        calls     = 0;
097        n         = y0.length;
098        this.t0   = t0;
099        this.y0   = y0.clone(); 
100       }
101    
102      /**
103       * Set the final conditions.
104       * @param t1 final time
105       */
106      protected void setFinalConditions(double t1) {
107        this.t1 = t1;
108      }
109    
110      /**
111       * Set the error scale
112       * @param errorScale error scale
113       */
114      protected void setErrorScale(double[] errorScale) {
115        this.errorScale = errorScale.clone(); 
116      }
117    
118      public int getDimension() {
119        return n;
120      }
121    
122      /**
123       * Get the initial time.
124       * @return initial time
125       */
126      public double getInitialTime() {
127        return t0;
128      }
129    
130      /**
131       * Get the initial state vector.
132       * @return initial state vector
133       */
134      public double[] getInitialState() {
135        return y0;
136      }
137    
138      /**
139       * Get the final time.
140       * @return final time
141       */
142      public double getFinalTime() {
143        return t1;
144      }
145    
146      /**
147       * Get the error scale.
148       * @return error scale
149       */
150      public double[] getErrorScale() {
151        return errorScale;
152      }
153    
154      /**
155       * Get the events handlers.
156       * @return events handlers   */
157      public EventHandler[] getEventsHandlers() {
158        return new EventHandler[0];
159      }
160    
161      /**
162       * Get the number of calls.
163       * @return nuber of calls
164       */
165      public int getCalls() {
166        return calls;
167      }
168    
169      public void computeDerivatives(double t, double[] y, double[] yDot) {
170        ++calls;
171        doComputeDerivatives(t, y, yDot);
172      }
173    
174      abstract public void doComputeDerivatives(double t, double[] y, double[] yDot);
175    
176      /**
177       * Compute the theoretical state at the specified time.
178       * @param t time at which the state is required
179       * @return state vector at time t
180       */
181      abstract public double[] computeTheoreticalState(double t);
182    
183    }