1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.math4.legacy.ode.nonstiff;
19
20 import java.util.Arrays;
21
22 import org.apache.commons.math4.legacy.core.RealFieldElement;
23 import org.apache.commons.math4.legacy.linear.Array2DRowFieldMatrix;
24 import org.apache.commons.math4.legacy.ode.FieldEquationsMapper;
25 import org.apache.commons.math4.legacy.ode.FieldODEStateAndDerivative;
26 import org.apache.commons.math4.legacy.ode.sampling.AbstractFieldStepInterpolator;
27 import org.apache.commons.math4.legacy.core.MathArrays;
28
29
30
31
32
33
34
35
36
37
38
39
40
41 class AdamsFieldStepInterpolator<T extends RealFieldElement<T>> extends AbstractFieldStepInterpolator<T> {
42
43
44 private T scalingH;
45
46
47
48
49
50
51
52 private final FieldODEStateAndDerivative<T> reference;
53
54
55 private final T[] scaled;
56
57
58 private final Array2DRowFieldMatrix<T> nordsieck;
59
60
61
62
63
64
65
66
67
68
69
70 AdamsFieldStepInterpolator(final T stepSize, final FieldODEStateAndDerivative<T> reference,
71 final T[] scaled, final Array2DRowFieldMatrix<T> nordsieck,
72 final boolean isForward,
73 final FieldODEStateAndDerivative<T> globalPreviousState,
74 final FieldODEStateAndDerivative<T> globalCurrentState,
75 final FieldEquationsMapper<T> equationsMapper) {
76 this(stepSize, reference, scaled, nordsieck,
77 isForward, globalPreviousState, globalCurrentState,
78 globalPreviousState, globalCurrentState, equationsMapper);
79 }
80
81
82
83
84
85
86
87
88
89
90
91
92
93 private AdamsFieldStepInterpolator(final T stepSize, final FieldODEStateAndDerivative<T> reference,
94 final T[] scaled, final Array2DRowFieldMatrix<T> nordsieck,
95 final boolean isForward,
96 final FieldODEStateAndDerivative<T> globalPreviousState,
97 final FieldODEStateAndDerivative<T> globalCurrentState,
98 final FieldODEStateAndDerivative<T> softPreviousState,
99 final FieldODEStateAndDerivative<T> softCurrentState,
100 final FieldEquationsMapper<T> equationsMapper) {
101 super(isForward, globalPreviousState, globalCurrentState,
102 softPreviousState, softCurrentState, equationsMapper);
103 this.scalingH = stepSize;
104 this.reference = reference;
105 this.scaled = scaled.clone();
106 this.nordsieck = new Array2DRowFieldMatrix<>(nordsieck.getData(), false);
107 }
108
109
110
111
112
113
114
115
116
117
118 @Override
119 protected AdamsFieldStepInterpolator<T> create(boolean newForward,
120 FieldODEStateAndDerivative<T> newGlobalPreviousState,
121 FieldODEStateAndDerivative<T> newGlobalCurrentState,
122 FieldODEStateAndDerivative<T> newSoftPreviousState,
123 FieldODEStateAndDerivative<T> newSoftCurrentState,
124 FieldEquationsMapper<T> newMapper) {
125 return new AdamsFieldStepInterpolator<>(scalingH, reference, scaled, nordsieck,
126 newForward,
127 newGlobalPreviousState, newGlobalCurrentState,
128 newSoftPreviousState, newSoftCurrentState,
129 newMapper);
130 }
131
132
133 @Override
134 protected FieldODEStateAndDerivative<T> computeInterpolatedStateAndDerivatives(final FieldEquationsMapper<T> equationsMapper,
135 final T time, final T theta,
136 final T thetaH, final T oneMinusThetaH) {
137 return taylor(reference, time, scalingH, scaled, nordsieck);
138 }
139
140
141
142
143
144
145
146
147
148
149 public static <S extends RealFieldElement<S>> FieldODEStateAndDerivative<S> taylor(final FieldODEStateAndDerivative<S> reference,
150 final S time, final S stepSize,
151 final S[] scaled,
152 final Array2DRowFieldMatrix<S> nordsieck) {
153
154 final S x = time.subtract(reference.getTime());
155 final S normalizedAbscissa = x.divide(stepSize);
156
157 S[] stateVariation = MathArrays.buildArray(time.getField(), scaled.length);
158 Arrays.fill(stateVariation, time.getField().getZero());
159 S[] estimatedDerivatives = MathArrays.buildArray(time.getField(), scaled.length);
160 Arrays.fill(estimatedDerivatives, time.getField().getZero());
161
162
163
164 final S[][] nData = nordsieck.getDataRef();
165 for (int i = nData.length - 1; i >= 0; --i) {
166 final int order = i + 2;
167 final S[] nDataI = nData[i];
168 final S power = normalizedAbscissa.pow(order);
169 for (int j = 0; j < nDataI.length; ++j) {
170 final S d = nDataI[j].multiply(power);
171 stateVariation[j] = stateVariation[j].add(d);
172 estimatedDerivatives[j] = estimatedDerivatives[j].add(d.multiply(order));
173 }
174 }
175
176 S[] estimatedState = reference.getState();
177 for (int j = 0; j < stateVariation.length; ++j) {
178 stateVariation[j] = stateVariation[j].add(scaled[j].multiply(normalizedAbscissa));
179 estimatedState[j] = estimatedState[j].add(stateVariation[j]);
180 estimatedDerivatives[j] =
181 estimatedDerivatives[j].add(scaled[j].multiply(normalizedAbscissa)).divide(x);
182 }
183
184 return new FieldODEStateAndDerivative<>(time, estimatedState, estimatedDerivatives);
185 }
186 }