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.ode.FieldEquationsMapper;
23  import org.apache.commons.math4.legacy.ode.FieldODEStateAndDerivative;
24  import org.apache.commons.math4.legacy.ode.sampling.AbstractFieldStepInterpolator;
25  import org.apache.commons.math4.legacy.core.MathArrays;
26  
27  /** This class represents an interpolator over the last step during an
28   * ODE integration for Runge-Kutta and embedded Runge-Kutta integrators.
29   *
30   * @see RungeKuttaFieldIntegrator
31   * @see EmbeddedRungeKuttaFieldIntegrator
32   *
33   * @param <T> the type of the field elements
34   * @since 3.6
35   */
36  
37  abstract class RungeKuttaFieldStepInterpolator<T extends RealFieldElement<T>>
38      extends AbstractFieldStepInterpolator<T> {
39  
40      /** Field to which the time and state vector elements belong. */
41      private final Field<T> field;
42  
43      /** Slopes at the intermediate points. */
44      private final T[][] yDotK;
45  
46      /** Simple constructor.
47       * @param field field to which the time and state vector elements belong
48       * @param forward integration direction indicator
49       * @param yDotK slopes at the intermediate points
50       * @param globalPreviousState start of the global step
51       * @param globalCurrentState end of the global step
52       * @param softPreviousState start of the restricted step
53       * @param softCurrentState end of the restricted step
54       * @param mapper equations mapper for the all equations
55       */
56      protected RungeKuttaFieldStepInterpolator(final Field<T> field, final boolean forward,
57                                                final T[][] yDotK,
58                                                final FieldODEStateAndDerivative<T> globalPreviousState,
59                                                final FieldODEStateAndDerivative<T> globalCurrentState,
60                                                final FieldODEStateAndDerivative<T> softPreviousState,
61                                                final FieldODEStateAndDerivative<T> softCurrentState,
62                                                final FieldEquationsMapper<T> mapper) {
63          super(forward, globalPreviousState, globalCurrentState, softPreviousState, softCurrentState, mapper);
64          this.field = field;
65          this.yDotK = MathArrays.buildArray(field, yDotK.length, -1);
66          for (int i = 0; i < yDotK.length; ++i) {
67              this.yDotK[i] = yDotK[i].clone();
68          }
69      }
70  
71      /** {@inheritDoc} */
72      @Override
73      protected RungeKuttaFieldStepInterpolator<T> create(boolean newForward,
74                                                          FieldODEStateAndDerivative<T> newGlobalPreviousState,
75                                                          FieldODEStateAndDerivative<T> newGlobalCurrentState,
76                                                          FieldODEStateAndDerivative<T> newSoftPreviousState,
77                                                          FieldODEStateAndDerivative<T> newSoftCurrentState,
78                                                          FieldEquationsMapper<T> newMapper) {
79          return create(field, newForward, yDotK,
80                        newGlobalPreviousState, newGlobalCurrentState,
81                        newSoftPreviousState, newSoftCurrentState,
82                        newMapper);
83      }
84  
85      /** Create a new instance.
86       * @param newField field to which the time and state vector elements belong
87       * @param newForward integration direction indicator
88       * @param newYDotK slopes at the intermediate points
89       * @param newGlobalPreviousState start of the global step
90       * @param newGlobalCurrentState end of the global step
91       * @param newSoftPreviousState start of the restricted step
92       * @param newSoftCurrentState end of the restricted step
93       * @param newMapper equations mapper for the all equations
94       * @return a new instance
95       */
96      protected abstract RungeKuttaFieldStepInterpolator<T> create(Field<T> newField, boolean newForward, T[][] newYDotK,
97                                                                   FieldODEStateAndDerivative<T> newGlobalPreviousState,
98                                                                   FieldODEStateAndDerivative<T> newGlobalCurrentState,
99                                                                   FieldODEStateAndDerivative<T> newSoftPreviousState,
100                                                                  FieldODEStateAndDerivative<T> newSoftCurrentState,
101                                                                  FieldEquationsMapper<T> newMapper);
102 
103     /** Compute a state by linear combination added to previous state.
104      * @param coefficients coefficients to apply to the method staged derivatives
105      * @return combined state
106      */
107     @SafeVarargs
108     protected final T[] previousStateLinearCombination(final T ... coefficients) {
109         return combine(getPreviousState().getState(),
110                        coefficients);
111     }
112 
113     /** Compute a state by linear combination added to current state.
114      * @param coefficients coefficients to apply to the method staged derivatives
115      * @return combined state
116      */
117     @SuppressWarnings("unchecked")
118     protected T[] currentStateLinearCombination(final T ... coefficients) {
119         return combine(getCurrentState().getState(),
120                        coefficients);
121     }
122 
123     /** Compute a state derivative by linear combination.
124      * @param coefficients coefficients to apply to the method staged derivatives
125      * @return combined state
126      */
127     @SuppressWarnings("unchecked")
128     protected T[] derivativeLinearCombination(final T ... coefficients) {
129         return combine(MathArrays.buildArray(field, yDotK[0].length), coefficients);
130     }
131 
132     /** Linearly combine arrays.
133      * @param a array to add to
134      * @param coefficients coefficients to apply to the method staged derivatives
135      * @return a itself, as a convenience for fluent API
136      */
137     @SuppressWarnings("unchecked")
138     private T[] combine(final T[] a, final T ... coefficients) {
139         for (int i = 0; i < a.length; ++i) {
140             for (int k = 0; k < coefficients.length; ++k) {
141                 a[i] = a[i].add(coefficients[k].multiply(yDotK[k][i]));
142             }
143         }
144         return a;
145     }
146 }