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 }