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.math3.ode.nonstiff;
019
020 import org.apache.commons.math3.exception.DimensionMismatchException;
021 import org.apache.commons.math3.exception.MaxCountExceededException;
022 import org.apache.commons.math3.exception.NoBracketingException;
023 import org.apache.commons.math3.exception.NumberIsTooSmallException;
024 import org.apache.commons.math3.linear.Array2DRowRealMatrix;
025 import org.apache.commons.math3.ode.ExpandableStatefulODE;
026 import org.apache.commons.math3.ode.MultistepIntegrator;
027
028
029 /** Base class for {@link AdamsBashforthIntegrator Adams-Bashforth} and
030 * {@link AdamsMoultonIntegrator Adams-Moulton} integrators.
031 * @version $Id: AdamsIntegrator.java 1416643 2012-12-03 19:37:14Z tn $
032 * @since 2.0
033 */
034 public abstract class AdamsIntegrator extends MultistepIntegrator {
035
036 /** Transformer. */
037 private final AdamsNordsieckTransformer transformer;
038
039 /**
040 * Build an Adams integrator with the given order and step control parameters.
041 * @param name name of the method
042 * @param nSteps number of steps of the method excluding the one being computed
043 * @param order order of the method
044 * @param minStep minimal step (sign is irrelevant, regardless of
045 * integration direction, forward or backward), the last step can
046 * be smaller than this
047 * @param maxStep maximal step (sign is irrelevant, regardless of
048 * integration direction, forward or backward), the last step can
049 * be smaller than this
050 * @param scalAbsoluteTolerance allowed absolute error
051 * @param scalRelativeTolerance allowed relative error
052 * @exception NumberIsTooSmallException if order is 1 or less
053 */
054 public AdamsIntegrator(final String name, final int nSteps, final int order,
055 final double minStep, final double maxStep,
056 final double scalAbsoluteTolerance,
057 final double scalRelativeTolerance)
058 throws NumberIsTooSmallException {
059 super(name, nSteps, order, minStep, maxStep,
060 scalAbsoluteTolerance, scalRelativeTolerance);
061 transformer = AdamsNordsieckTransformer.getInstance(nSteps);
062 }
063
064 /**
065 * Build an Adams integrator with the given order and step control parameters.
066 * @param name name of the method
067 * @param nSteps number of steps of the method excluding the one being computed
068 * @param order order of the method
069 * @param minStep minimal step (sign is irrelevant, regardless of
070 * integration direction, forward or backward), the last step can
071 * be smaller than this
072 * @param maxStep maximal step (sign is irrelevant, regardless of
073 * integration direction, forward or backward), the last step can
074 * be smaller than this
075 * @param vecAbsoluteTolerance allowed absolute error
076 * @param vecRelativeTolerance allowed relative error
077 * @exception IllegalArgumentException if order is 1 or less
078 */
079 public AdamsIntegrator(final String name, final int nSteps, final int order,
080 final double minStep, final double maxStep,
081 final double[] vecAbsoluteTolerance,
082 final double[] vecRelativeTolerance)
083 throws IllegalArgumentException {
084 super(name, nSteps, order, minStep, maxStep,
085 vecAbsoluteTolerance, vecRelativeTolerance);
086 transformer = AdamsNordsieckTransformer.getInstance(nSteps);
087 }
088
089 /** {@inheritDoc} */
090 @Override
091 public abstract void integrate(final ExpandableStatefulODE equations, final double t)
092 throws NumberIsTooSmallException, DimensionMismatchException,
093 MaxCountExceededException, NoBracketingException;
094
095 /** {@inheritDoc} */
096 @Override
097 protected Array2DRowRealMatrix initializeHighOrderDerivatives(final double h, final double[] t,
098 final double[][] y,
099 final double[][] yDot) {
100 return transformer.initializeHighOrderDerivatives(h, t, y, yDot);
101 }
102
103 /** Update the high order scaled derivatives for Adams integrators (phase 1).
104 * <p>The complete update of high order derivatives has a form similar to:
105 * <pre>
106 * r<sub>n+1</sub> = (s<sub>1</sub>(n) - s<sub>1</sub>(n+1)) P<sup>-1</sup> u + P<sup>-1</sup> A P r<sub>n</sub>
107 * </pre>
108 * this method computes the P<sup>-1</sup> A P r<sub>n</sub> part.</p>
109 * @param highOrder high order scaled derivatives
110 * (h<sup>2</sup>/2 y'', ... h<sup>k</sup>/k! y(k))
111 * @return updated high order derivatives
112 * @see #updateHighOrderDerivativesPhase2(double[], double[], Array2DRowRealMatrix)
113 */
114 public Array2DRowRealMatrix updateHighOrderDerivativesPhase1(final Array2DRowRealMatrix highOrder) {
115 return transformer.updateHighOrderDerivativesPhase1(highOrder);
116 }
117
118 /** Update the high order scaled derivatives Adams integrators (phase 2).
119 * <p>The complete update of high order derivatives has a form similar to:
120 * <pre>
121 * r<sub>n+1</sub> = (s<sub>1</sub>(n) - s<sub>1</sub>(n+1)) P<sup>-1</sup> u + P<sup>-1</sup> A P r<sub>n</sub>
122 * </pre>
123 * this method computes the (s<sub>1</sub>(n) - s<sub>1</sub>(n+1)) P<sup>-1</sup> u part.</p>
124 * <p>Phase 1 of the update must already have been performed.</p>
125 * @param start first order scaled derivatives at step start
126 * @param end first order scaled derivatives at step end
127 * @param highOrder high order scaled derivatives, will be modified
128 * (h<sup>2</sup>/2 y'', ... h<sup>k</sup>/k! y(k))
129 * @see #updateHighOrderDerivativesPhase1(Array2DRowRealMatrix)
130 */
131 public void updateHighOrderDerivativesPhase2(final double[] start,
132 final double[] end,
133 final Array2DRowRealMatrix highOrder) {
134 transformer.updateHighOrderDerivativesPhase2(start, end, highOrder);
135 }
136
137 }