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.math4.legacy.ode.nonstiff;
19  
20  import org.apache.commons.math4.legacy.core.Field;
21  import org.apache.commons.math4.legacy.core.RealFieldElement;
22  import org.apache.commons.math4.legacy.exception.DimensionMismatchException;
23  import org.apache.commons.math4.legacy.exception.MaxCountExceededException;
24  import org.apache.commons.math4.legacy.exception.NoBracketingException;
25  import org.apache.commons.math4.legacy.exception.NumberIsTooSmallException;
26  import org.apache.commons.math4.legacy.linear.Array2DRowFieldMatrix;
27  import org.apache.commons.math4.legacy.ode.FieldExpandableODE;
28  import org.apache.commons.math4.legacy.ode.FieldODEState;
29  import org.apache.commons.math4.legacy.ode.FieldODEStateAndDerivative;
30  import org.apache.commons.math4.legacy.ode.MultistepFieldIntegrator;
31  
32  
33  /** Base class for {@link AdamsBashforthFieldIntegrator Adams-Bashforth} and
34   * {@link AdamsMoultonFieldIntegrator Adams-Moulton} integrators.
35   * @param <T> the type of the field elements
36   * @since 3.6
37   */
38  public abstract class AdamsFieldIntegrator<T extends RealFieldElement<T>> extends MultistepFieldIntegrator<T> {
39  
40      /** Transformer. */
41      private final AdamsNordsieckFieldTransformer<T> transformer;
42  
43      /**
44       * Build an Adams integrator with the given order and step control parameters.
45       * @param field field to which the time and state vector elements belong
46       * @param name name of the method
47       * @param nSteps number of steps of the method excluding the one being computed
48       * @param order order of the method
49       * @param minStep minimal step (sign is irrelevant, regardless of
50       * integration direction, forward or backward), the last step can
51       * be smaller than this
52       * @param maxStep maximal step (sign is irrelevant, regardless of
53       * integration direction, forward or backward), the last step can
54       * be smaller than this
55       * @param scalAbsoluteTolerance allowed absolute error
56       * @param scalRelativeTolerance allowed relative error
57       * @exception NumberIsTooSmallException if order is 1 or less
58       */
59      public AdamsFieldIntegrator(final Field<T> field, final String name,
60                                  final int nSteps, final int order,
61                                  final double minStep, final double maxStep,
62                                  final double scalAbsoluteTolerance,
63                                  final double scalRelativeTolerance)
64          throws NumberIsTooSmallException {
65          super(field, name, nSteps, order, minStep, maxStep,
66                scalAbsoluteTolerance, scalRelativeTolerance);
67          transformer = AdamsNordsieckFieldTransformer.getInstance(field, nSteps);
68      }
69  
70      /**
71       * Build an Adams integrator with the given order and step control parameters.
72       * @param field field to which the time and state vector elements belong
73       * @param name name of the method
74       * @param nSteps number of steps of the method excluding the one being computed
75       * @param order order of the method
76       * @param minStep minimal step (sign is irrelevant, regardless of
77       * integration direction, forward or backward), the last step can
78       * be smaller than this
79       * @param maxStep maximal step (sign is irrelevant, regardless of
80       * integration direction, forward or backward), the last step can
81       * be smaller than this
82       * @param vecAbsoluteTolerance allowed absolute error
83       * @param vecRelativeTolerance allowed relative error
84       * @exception IllegalArgumentException if order is 1 or less
85       */
86      public AdamsFieldIntegrator(final Field<T> field, final String name,
87                                  final int nSteps, final int order,
88                                  final double minStep, final double maxStep,
89                                  final double[] vecAbsoluteTolerance,
90                                  final double[] vecRelativeTolerance)
91          throws IllegalArgumentException {
92          super(field, name, nSteps, order, minStep, maxStep,
93                vecAbsoluteTolerance, vecRelativeTolerance);
94          transformer = AdamsNordsieckFieldTransformer.getInstance(field, nSteps);
95      }
96  
97      /** {@inheritDoc} */
98      @Override
99      public abstract FieldODEStateAndDerivative<T> integrate(FieldExpandableODE<T> equations,
100                                                             FieldODEState<T> initialState,
101                                                             T finalTime)
102         throws NumberIsTooSmallException, DimensionMismatchException,
103                MaxCountExceededException, NoBracketingException;
104 
105     /** {@inheritDoc} */
106     @Override
107     protected Array2DRowFieldMatrix<T> initializeHighOrderDerivatives(final T h, final T[] t,
108                                                                       final T[][] y,
109                                                                       final T[][] yDot) {
110         return transformer.initializeHighOrderDerivatives(h, t, y, yDot);
111     }
112 
113     /** Update the high order scaled derivatives for Adams integrators (phase 1).
114      * <p>The complete update of high order derivatives has a form similar to:
115      * <div style="white-space: pre"><code>
116      * 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>
117      * </code></div>
118      * this method computes the P<sup>-1</sup> A P r<sub>n</sub> part.
119      * @param highOrder high order scaled derivatives
120      * (h<sup>2</sup>/2 y'', ... h<sup>k</sup>/k! y(k))
121      * @return updated high order derivatives
122      * @see #updateHighOrderDerivativesPhase2(RealFieldElement[], RealFieldElement[], Array2DRowFieldMatrix)
123      */
124     public Array2DRowFieldMatrix<T> updateHighOrderDerivativesPhase1(final Array2DRowFieldMatrix<T> highOrder) {
125         return transformer.updateHighOrderDerivativesPhase1(highOrder);
126     }
127 
128     /** Update the high order scaled derivatives Adams integrators (phase 2).
129      * <p>The complete update of high order derivatives has a form similar to:
130      * <div style="white-space: pre"><code>
131      * 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>
132      * </code></div>
133      * this method computes the (s<sub>1</sub>(n) - s<sub>1</sub>(n+1)) P<sup>-1</sup> u part.
134      * <p>Phase 1 of the update must already have been performed.</p>
135      * @param start first order scaled derivatives at step start
136      * @param end first order scaled derivatives at step end
137      * @param highOrder high order scaled derivatives, will be modified
138      * (h<sup>2</sup>/2 y'', ... h<sup>k</sup>/k! y(k))
139      * @see #updateHighOrderDerivativesPhase1(Array2DRowFieldMatrix)
140      */
141     public void updateHighOrderDerivativesPhase2(final T[] start, final T[] end,
142                                                  final Array2DRowFieldMatrix<T> highOrder) {
143         transformer.updateHighOrderDerivativesPhase2(start, end, highOrder);
144     }
145 }