⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 graggbulirschstoerintegrator.java

📁 Apache的common math数学软件包
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements.  See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License.  You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.apache.commons.math.ode;/** * This class implements a Gragg-Bulirsch-Stoer integrator for * Ordinary Differential Equations. * * <p>The Gragg-Bulirsch-Stoer algorithm is one of the most efficient * ones currently available for smooth problems. It uses Richardson * extrapolation to estimate what would be the solution if the step * size could be decreased down to zero.</p> * * <p> * This method changes both the step size and the order during * integration, in order to minimize computation cost. It is * particularly well suited when a very high precision is needed. The * limit where this method becomes more efficient than high-order * embedded Runge-Kutta methods like {@link DormandPrince853Integrator * Dormand-Prince 8(5,3)} depends on the problem. Results given in the * Hairer, Norsett and Wanner book show for example that this limit * occurs for accuracy around 1e-6 when integrating Saltzam-Lorenz * equations (the authors note this problem is <i>extremely sensitive * to the errors in the first integration steps</i>), and around 1e-11 * for a two dimensional celestial mechanics problems with seven * bodies (pleiades problem, involving quasi-collisions for which * <i>automatic step size control is essential</i>). * </p> * * <p> * This implementation is basically a reimplementation in Java of the * <a * href="http://www.unige.ch/math/folks/hairer/prog/nonstiff/odex.f">odex</a> * fortran code by E. Hairer and G. Wanner. The redistribution policy * for this code is available <a * href="http://www.unige.ch/~hairer/prog/licence.txt">here</a>, for * convenience, it is reproduced below.</p> * </p> * * <table border="0" width="80%" cellpadding="10" align="center" bgcolor="#E0E0E0"> * <tr><td>Copyright (c) 2004, Ernst Hairer</td></tr> * * <tr><td>Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * <ul> *  <li>Redistributions of source code must retain the above copyright *      notice, this list of conditions and the following disclaimer.</li> *  <li>Redistributions in binary form must reproduce the above copyright *      notice, this list of conditions and the following disclaimer in the *      documentation and/or other materials provided with the distribution.</li> * </ul></td></tr> * * <tr><td><strong>THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</strong></td></tr> * </table> * * @author E. Hairer and G. Wanner (fortran version) * @version $Revision: 620312 $ $Date: 2008-02-10 12:28:59 -0700 (Sun, 10 Feb 2008) $ * @since 1.2 */public class GraggBulirschStoerIntegrator  extends AdaptiveStepsizeIntegrator {  /** Integrator method name. */  private static final String methodName = "Gragg-Bulirsch-Stoer";  /** Simple constructor.   * Build a Gragg-Bulirsch-Stoer integrator with the given step   * bounds. All tuning parameters are set to their default   * values. The default step handler does nothing.   * @param minStep minimal step (must be positive even for backward   * integration), the last step can be smaller than this   * @param maxStep maximal step (must be positive even for backward   * integration)   * @param scalAbsoluteTolerance allowed absolute error   * @param scalRelativeTolerance allowed relative error   */  public GraggBulirschStoerIntegrator(double minStep, double maxStep,                                      double scalAbsoluteTolerance,                                      double scalRelativeTolerance) {    super(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance);    denseOutput = (handler.requiresDenseOutput() || (! switchesHandler.isEmpty()));    setStabilityCheck(true, -1, -1, -1);    setStepsizeControl(-1, -1, -1, -1);    setOrderControl(-1, -1, -1);    setInterpolationControl(true, -1);  }  /** Simple constructor.   * Build a Gragg-Bulirsch-Stoer integrator with the given step   * bounds. All tuning parameters are set to their default   * values. The default step handler does nothing.   * @param minStep minimal step (must be positive even for backward   * integration), the last step can be smaller than this   * @param maxStep maximal step (must be positive even for backward   * integration)   * @param vecAbsoluteTolerance allowed absolute error   * @param vecRelativeTolerance allowed relative error   */  public GraggBulirschStoerIntegrator(double minStep, double maxStep,                                      double[] vecAbsoluteTolerance,                                      double[] vecRelativeTolerance) {    super(minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance);    denseOutput = (handler.requiresDenseOutput() || (! switchesHandler.isEmpty()));    setStabilityCheck(true, -1, -1, -1);    setStepsizeControl(-1, -1, -1, -1);    setOrderControl(-1, -1, -1);    setInterpolationControl(true, -1);  }  /** Set the stability check controls.   * <p>The stability check is performed on the first few iterations of   * the extrapolation scheme. If this test fails, the step is rejected   * and the stepsize is reduced.</p>   * <p>By default, the test is performed, at most during two   * iterations at each step, and at most once for each of these   * iterations. The default stepsize reduction factor is 0.5.</p>   * @param performTest if true, stability check will be performed,     if false, the check will be skipped   * @param maxIter maximal number of iterations for which checks are   * performed (the number of iterations is reset to default if negative   * or null)   * @param maxChecks maximal number of checks for each iteration   * (the number of checks is reset to default if negative or null)   * @param stabilityReduction stepsize reduction factor in case of   * failure (the factor is reset to default if lower than 0.0001 or   * greater than 0.9999)   */  public void setStabilityCheck(boolean performTest,                                int maxIter, int maxChecks,                                double stabilityReduction) {    this.performTest = performTest;    this.maxIter     = (maxIter   <= 0) ? 2 : maxIter;    this.maxChecks   = (maxChecks <= 0) ? 1 : maxChecks;    if ((stabilityReduction < 0.0001) || (stabilityReduction > 0.9999)) {      this.stabilityReduction = 0.5;    } else {      this.stabilityReduction = stabilityReduction;    }  }  /** Set the step size control factors.   * <p>The new step size hNew is computed from the old one h by:   * <pre>   * hNew = h * stepControl2 / (err/stepControl1)^(1/(2k+1))   * </pre>   * where err is the scaled error and k the iteration number of the   * extrapolation scheme (counting from 0). The default values are   * 0.65 for stepControl1 and 0.94 for stepControl2.</p>   * <p>The step size is subject to the restriction:   * <pre>   * stepControl3^(1/(2k+1))/stepControl4 <= hNew/h <= 1/stepControl3^(1/(2k+1))   * </pre>   * The default values are 0.02 for stepControl3 and 4.0 for   * stepControl4.</p>   * @param stepControl1 first stepsize control factor (the factor is   * reset to default if lower than 0.0001 or greater than 0.9999)   * @param stepControl2 second stepsize control factor (the factor   * is reset to default if lower than 0.0001 or greater than 0.9999)   * @param stepControl3 third stepsize control factor (the factor is   * reset to default if lower than 0.0001 or greater than 0.9999)   * @param stepControl4 fourth stepsize control factor (the factor   * is reset to default if lower than 1.0001 or greater than 999.9)   */  public void setStepsizeControl(double stepControl1, double stepControl2,                                 double stepControl3, double stepControl4) {    if ((stepControl1 < 0.0001) || (stepControl1 > 0.9999)) {      this.stepControl1 = 0.65;    } else {      this.stepControl1 = stepControl1;    }    if ((stepControl2 < 0.0001) || (stepControl2 > 0.9999)) {      this.stepControl2 = 0.94;    } else {      this.stepControl2 = stepControl2;    }    if ((stepControl3 < 0.0001) || (stepControl3 > 0.9999)) {      this.stepControl3 = 0.02;    } else {      this.stepControl3 = stepControl3;    }    if ((stepControl4 < 1.0001) || (stepControl4 > 999.9)) {      this.stepControl4 = 4.0;    } else {      this.stepControl4 = stepControl4;    }  }  /** Set the order control parameters.   * <p>The Gragg-Bulirsch-Stoer method changes both the step size and   * the order during integration, in order to minimize computation   * cost. Each extrapolation step increases the order by 2, so the   * maximal order that will be used is always even, it is twice the   * maximal number of columns in the extrapolation table.</p>   * <pre>   * order is decreased if w(k-1) <= w(k)   * orderControl1   * order is increased if w(k)   <= w(k-1) * orderControl2   * </pre>   * <p>where w is the table of work per unit step for each order   * (number of function calls divided by the step length), and k is   * the current order.</p>   * <p>The default maximal order after construction is 18 (i.e. the   * maximal number of columns is 9). The default values are 0.8 for   * orderControl1 and 0.9 for orderControl2.</p>   * @param maxOrder maximal order in the extrapolation table (the   * maximal order is reset to default if order <= 6 or odd)   * @param orderControl1 first order control factor (the factor is   * reset to default if lower than 0.0001 or greater than 0.9999)   * @param orderControl2 second order control factor (the factor   * is reset to default if lower than 0.0001 or greater than 0.9999)   */  public void setOrderControl(int maxOrder,                              double orderControl1, double orderControl2) {    if ((maxOrder <= 6) || (maxOrder % 2 != 0)) {      this.maxOrder = 18;    }    if ((orderControl1 < 0.0001) || (orderControl1 > 0.9999)) {      this.orderControl1 = 0.8;    } else {      this.orderControl1 = orderControl1;    }    if ((orderControl2 < 0.0001) || (orderControl2 > 0.9999)) {      this.orderControl2 = 0.9;    } else {      this.orderControl2 = orderControl2;    }    // reinitialize the arrays    initializeArrays();  }  /** Set the step handler for this integrator.   * The handler will be called by the integrator for each accepted   * step.   * @param handler handler for the accepted steps   */  public void setStepHandler (StepHandler handler) {    super.setStepHandler(handler);    denseOutput = (handler.requiresDenseOutput() || (! switchesHandler.isEmpty()));    // reinitialize the arrays    initializeArrays();  }  /** Add a switching function to the integrator.   * @param function switching function   * @param maxCheckInterval maximal time interval between switching   * function checks (this interval prevents missing sign changes in   * case the integration steps becomes very large)   * @param convergence convergence threshold in the event time search   * @param maxIterationCount upper limit of the iteration count in   * the event time search   */  public void addSwitchingFunction(SwitchingFunction function,                                   double maxCheckInterval,                                   double convergence,                                   int maxIterationCount) {    super.addSwitchingFunction(function, maxCheckInterval, convergence, maxIterationCount);    denseOutput = (handler.requiresDenseOutput() || (! switchesHandler.isEmpty()));    // reinitialize the arrays    initializeArrays();  }  /** Initialize the integrator internal arrays. */  private void initializeArrays() {    int size = maxOrder / 2;    if ((sequence == null) || (sequence.length != size)) {      // all arrays should be reallocated with the right size      sequence        = new int[size];      costPerStep     = new int[size];      coeff           = new double[size][];      costPerTimeUnit = new double[size];      optimalStep     = new double[size];    }    if (denseOutput) {      // step size sequence: 2, 6, 10, 14, ...      for (int k = 0; k < size; ++k) {        sequence[k] = 4 * k + 2;      }    } else {      // step size sequence: 2, 4, 6, 8, ...      for (int k = 0; k < size; ++k) {        sequence[k] = 2 * (k + 1);       }    }    // initialize the order selection cost array    // (number of function calls for each column of the extrapolation table)    costPerStep[0] = sequence[0] + 1;    for (int k = 1; k < size; ++k) {      costPerStep[k] = costPerStep[k-1] + sequence[k];    }    // initialize the extrapolation tables

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -