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