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 org.hipparchus.CalculusFieldElement;
26 import org.hipparchus.Field;
27 import org.hipparchus.ode.FieldEquationsMapper;
28 import org.hipparchus.ode.FieldODEStateAndDerivative;
29 import org.hipparchus.ode.nonstiff.interpolators.DormandPrince853FieldStateInterpolator;
30 import org.hipparchus.util.FastMath;
31 import org.hipparchus.util.MathArrays;
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67 public class DormandPrince853FieldIntegrator<T extends CalculusFieldElement<T>>
68 extends EmbeddedRungeKuttaFieldIntegrator<T> {
69
70
71 public static final String METHOD_NAME = DormandPrince853Integrator.METHOD_NAME;
72
73
74
75
76
77
78
79
80
81
82
83
84
85 public DormandPrince853FieldIntegrator(final Field<T> field,
86 final double minStep, final double maxStep,
87 final double scalAbsoluteTolerance,
88 final double scalRelativeTolerance) {
89 super(field, METHOD_NAME, 12,
90 minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance);
91 }
92
93
94
95
96
97
98
99
100
101
102
103
104
105 public DormandPrince853FieldIntegrator(final Field<T> field,
106 final double minStep, final double maxStep,
107 final double[] vecAbsoluteTolerance,
108 final double[] vecRelativeTolerance) {
109 super(field, DormandPrince853Integrator.METHOD_NAME, 12,
110 minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance);
111 }
112
113
114 @Override
115 public T[] getC() {
116
117 final T sqrt6 = getField().getOne().newInstance(6).sqrt();
118
119 final T[] c = MathArrays.buildArray(getField(), 15);
120 c[ 0] = sqrt6.add(-6).divide(-67.5);
121 c[ 1] = sqrt6.add(-6).divide(-45.0);
122 c[ 2] = sqrt6.add(-6).divide(-30.0);
123 c[ 3] = sqrt6.add( 6).divide( 30.0);
124 c[ 4] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 1, 3);
125 c[ 5] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 1, 4);
126 c[ 6] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 4, 13);
127 c[ 7] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 127, 195);
128 c[ 8] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 3, 5);
129 c[ 9] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 6, 7);
130 c[10] = getField().getOne();
131 c[11] = getField().getOne();
132 c[12] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 1.0, 10.0);
133 c[13] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 1.0, 5.0);
134 c[14] = FieldExplicitRungeKuttaIntegrator.fraction(getField(),7.0, 9.0);
135
136 return c;
137
138 }
139
140
141 @Override
142 public T[][] getA() {
143
144 final T sqrt6 = getField().getOne().newInstance(6).sqrt();
145
146 final T[][] a = MathArrays.buildArray(getField(), 15, -1);
147 for (int i = 0; i < a.length; ++i) {
148 a[i] = MathArrays.buildArray(getField(), i + 1);
149 }
150
151 a[ 0][ 0] = sqrt6.add(-6).divide(-67.5);
152
153 a[ 1][ 0] = sqrt6.add(-6).divide(-180);
154 a[ 1][ 1] = sqrt6.add(-6).divide( -60);
155
156 a[ 2][ 0] = sqrt6.add(-6).divide(-120);
157 a[ 2][ 1] = getField().getZero();
158 a[ 2][ 2] = sqrt6.add(-6).divide( -40);
159
160 a[ 3][ 0] = sqrt6.multiply(107).add(462).divide( 3000);
161 a[ 3][ 1] = getField().getZero();
162 a[ 3][ 2] = sqrt6.multiply(197).add(402).divide(-1000);
163 a[ 3][ 3] = sqrt6.multiply( 73).add(168).divide( 375);
164
165 a[ 4][ 0] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 1, 27);
166 a[ 4][ 1] = getField().getZero();
167 a[ 4][ 2] = getField().getZero();
168 a[ 4][ 3] = sqrt6.add( 16).divide( 108);
169 a[ 4][ 4] = sqrt6.add(-16).divide(-108);
170
171 a[ 5][ 0] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 19, 512);
172 a[ 5][ 1] = getField().getZero();
173 a[ 5][ 2] = getField().getZero();
174 a[ 5][ 3] = sqrt6.multiply( 23).add(118).divide(1024);
175 a[ 5][ 4] = sqrt6.multiply(-23).add(118).divide(1024);
176 a[ 5][ 5] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), -9, 512);
177
178 a[ 6][ 0] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 13772, 371293);
179 a[ 6][ 1] = getField().getZero();
180 a[ 6][ 2] = getField().getZero();
181 a[ 6][ 3] = sqrt6.multiply( 4784).add(51544).divide(371293);
182 a[ 6][ 4] = sqrt6.multiply(-4784).add(51544).divide(371293);
183 a[ 6][ 5] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), -5688, 371293);
184 a[ 6][ 6] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 3072, 371293);
185
186 a[ 7][ 0] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 58656157643.0, 93983540625.0);
187 a[ 7][ 1] = getField().getZero();
188 a[ 7][ 2] = getField().getZero();
189 a[ 7][ 3] = sqrt6.multiply(-318801444819.0).add(-1324889724104.0).divide(626556937500.0);
190 a[ 7][ 4] = sqrt6.multiply( 318801444819.0).add(-1324889724104.0).divide(626556937500.0);
191 a[ 7][ 5] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 96044563816.0, 3480871875.0);
192 a[ 7][ 6] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 5682451879168.0, 281950621875.0);
193 a[ 7][ 7] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), -165125654.0, 3796875.0);
194
195 a[ 8][ 0] = FieldExplicitRungeKuttaIntegrator.fraction(getField(),8909899.0, 18653125.0);
196 a[ 8][ 1] = getField().getZero();
197 a[ 8][ 2] = getField().getZero();
198 a[ 8][ 3] = sqrt6.multiply(-1137963.0).add(-4521408.0).divide(2937500.0);
199 a[ 8][ 4] = sqrt6.multiply( 1137963.0).add(-4521408.0).divide(2937500.0);
200 a[ 8][ 5] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 96663078.0, 4553125.0);
201 a[ 8][ 6] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 2107245056.0, 137915625.0);
202 a[ 8][ 7] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), -4913652016.0, 147609375.0);
203 a[ 8][ 8] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), -78894270.0, 3880452869.0);
204
205 a[ 9][ 0] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), -20401265806.0, 21769653311.0);
206 a[ 9][ 1] = getField().getZero();
207 a[ 9][ 2] = getField().getZero();
208 a[ 9][ 3] = sqrt6.multiply( 94326.0).add(354216.0).divide(112847.0);
209 a[ 9][ 4] = sqrt6.multiply(-94326.0).add(354216.0).divide(112847.0);
210 a[ 9][ 5] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), -43306765128.0, 5313852383.0);
211 a[ 9][ 6] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), -20866708358144.0, 1126708119789.0);
212 a[ 9][ 7] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 14886003438020.0, 654632330667.0);
213 a[ 9][ 8] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 35290686222309375.0, 14152473387134411.0);
214 a[ 9][ 9] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), -1477884375.0, 485066827.0);
215
216 a[10][ 0] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 39815761.0, 17514443.0);
217 a[10][ 1] = getField().getZero();
218 a[10][ 2] = getField().getZero();
219 a[10][ 3] = sqrt6.multiply(-960905.0).add(-3457480.0).divide(551636.0);
220 a[10][ 4] = sqrt6.multiply( 960905.0).add(-3457480.0).divide(551636.0);
221 a[10][ 5] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), -844554132.0, 47026969.0);
222 a[10][ 6] = FieldExplicitRungeKuttaIntegrator.fraction(getField(),8444996352.0, 302158619.0);
223 a[10][ 7] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), -2509602342.0, 877790785.0);
224 a[10][ 8] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), -28388795297996250.0, 3199510091356783.0);
225 a[10][ 9] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 226716250.0, 18341897.0);
226 a[10][10] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 1371316744.0, 2131383595.0);
227
228
229
230 a[11][ 0] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 104257.0, 1920240.0);
231 a[11][ 1] = getField().getZero();
232 a[11][ 2] = getField().getZero();
233 a[11][ 3] = getField().getZero();
234 a[11][ 4] = getField().getZero();
235 a[11][ 5] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 3399327.0, 763840.0);
236 a[11][ 6] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 66578432.0, 35198415.0);
237 a[11][ 7] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), -1674902723.0, 288716400.0);
238 a[11][ 8] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 54980371265625.0, 176692375811392.0);
239 a[11][ 9] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), -734375.0, 4826304.0);
240 a[11][10] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 171414593.0, 851261400.0);
241 a[11][11] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 137909.0, 3084480.0);
242
243
244 a[12][ 0] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 13481885573.0, 240030000000.0);
245 a[12][ 1] = getField().getZero();
246 a[12][ 2] = getField().getZero();
247 a[12][ 3] = getField().getZero();
248 a[12][ 4] = getField().getZero();
249 a[12][ 5] = getField().getZero();
250 a[12][ 6] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 139418837528.0, 549975234375.0);
251 a[12][ 7] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), -11108320068443.0, 45111937500000.0);
252 a[12][ 8] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), -1769651421925959.0, 14249385146080000.0);
253 a[12][ 9] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 57799439.0, 377055000.0);
254 a[12][10] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 793322643029.0, 96734250000000.0);
255 a[12][11] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 1458939311.0, 192780000000.0);
256 a[12][12] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), -4149.0, 500000.0);
257
258 a[13][ 0] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 1595561272731.0, 50120273500000.0);
259 a[13][ 1] = getField().getZero();
260 a[13][ 2] = getField().getZero();
261 a[13][ 3] = getField().getZero();
262 a[13][ 4] = getField().getZero();
263 a[13][ 5] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 975183916491.0, 34457688031250.0);
264 a[13][ 6] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 38492013932672.0, 718912673015625.0);
265 a[13][ 7] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), -1114881286517557.0, 20298710767500000.0);
266 a[13][ 8] = getField().getZero();
267 a[13][ 9] = getField().getZero();
268 a[13][10] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), -2538710946863.0, 23431227861250000.0);
269 a[13][11] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 8824659001.0, 23066716781250.0);
270 a[13][12] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), -11518334563.0, 33831184612500.0);
271 a[13][13] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 1912306948.0, 13532473845.0);
272
273 a[14][ 0] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), -13613986967.0, 31741908048.0);
274 a[14][ 1] = getField().getZero();
275 a[14][ 2] = getField().getZero();
276 a[14][ 3] = getField().getZero();
277 a[14][ 4] = getField().getZero();
278 a[14][ 5] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), -4755612631.0, 1012344804.0);
279 a[14][ 6] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 42939257944576.0, 5588559685701.0);
280 a[14][ 7] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 77881972900277.0, 19140370552944.0);
281 a[14][ 8] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 22719829234375.0, 63689648654052.0);
282 a[14][ 9] = getField().getZero();
283 a[14][10] = getField().getZero();
284 a[14][11] = getField().getZero();
285 a[14][12] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), -1199007803.0, 857031517296.0);
286 a[14][13] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 157882067000.0, 53564469831.0);
287 a[14][14] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), -290468882375.0, 31741908048.0);
288
289 return a;
290
291 }
292
293
294 @Override
295 public T[] getB() {
296 final T[] b = MathArrays.buildArray(getField(), 16);
297 b[ 0] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 104257, 1920240);
298 b[ 1] = getField().getZero();
299 b[ 2] = getField().getZero();
300 b[ 3] = getField().getZero();
301 b[ 4] = getField().getZero();
302 b[ 5] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 3399327.0, 763840.0);
303 b[ 6] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 66578432.0, 35198415.0);
304 b[ 7] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), -1674902723.0, 288716400.0);
305 b[ 8] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 54980371265625.0, 176692375811392.0);
306 b[ 9] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), -734375.0, 4826304.0);
307 b[10] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 171414593.0, 851261400.0);
308 b[11] = FieldExplicitRungeKuttaIntegrator.fraction(getField(), 137909.0, 3084480.0);
309 b[12] = getField().getZero();
310 b[13] = getField().getZero();
311 b[14] = getField().getZero();
312 b[15] = getField().getZero();
313 return b;
314 }
315
316
317 @Override
318 protected DormandPrince853FieldStateInterpolator<T>
319 createInterpolator(final boolean forward, T[][] yDotK,
320 final FieldODEStateAndDerivative<T> globalPreviousState,
321 final FieldODEStateAndDerivative<T> globalCurrentState, final FieldEquationsMapper<T> mapper) {
322 return new DormandPrince853FieldStateInterpolator<>(getField(), forward, yDotK,
323 globalPreviousState, globalCurrentState,
324 globalPreviousState, globalCurrentState,
325 mapper);
326 }
327
328
329 @Override
330 public int getOrder() {
331 return 8;
332 }
333
334
335 @Override
336 protected double estimateError(final T[][] yDotK, final T[] y0, final T[] y1, final T h) {
337
338 final StepsizeHelper helper = getStepSizeHelper();
339 double error1 = 0;
340 double error2 = 0;
341
342 for (int j = 0; j < helper.getMainSetDimension(); ++j) {
343 final double errSum1 = DormandPrince853Integrator.E1_01 * yDotK[ 0][j].getReal() + DormandPrince853Integrator.E1_06 * yDotK[ 5][j].getReal() +
344 DormandPrince853Integrator.E1_07 * yDotK[ 6][j].getReal() + DormandPrince853Integrator.E1_08 * yDotK[ 7][j].getReal() +
345 DormandPrince853Integrator.E1_09 * yDotK[ 8][j].getReal() + DormandPrince853Integrator.E1_10 * yDotK[ 9][j].getReal() +
346 DormandPrince853Integrator.E1_11 * yDotK[10][j].getReal() + DormandPrince853Integrator.E1_12 * yDotK[11][j].getReal();
347 final double errSum2 = DormandPrince853Integrator.E2_01 * yDotK[ 0][j].getReal() + DormandPrince853Integrator.E2_06 * yDotK[ 5][j].getReal() +
348 DormandPrince853Integrator.E2_07 * yDotK[ 6][j].getReal() + DormandPrince853Integrator.E2_08 * yDotK[ 7][j].getReal() +
349 DormandPrince853Integrator.E2_09 * yDotK[ 8][j].getReal() + DormandPrince853Integrator.E2_10 * yDotK[ 9][j].getReal() +
350 DormandPrince853Integrator.E2_11 * yDotK[10][j].getReal() + DormandPrince853Integrator.E2_12 * yDotK[11][j].getReal();
351 final double tol = helper.getTolerance(j, FastMath.max(FastMath.abs(y0[j].getReal()), FastMath.abs(y1[j].getReal())));
352 final double ratio1 = errSum1 / tol;
353 error1 += ratio1 * ratio1;
354 final double ratio2 = errSum2 / tol;
355 error2 += ratio2 * ratio2;
356
357 }
358
359 double den = error1 + 0.01 * error2;
360 if (den <= 0.0) {
361 den = 1.0;
362 }
363
364 return FastMath.abs(h.getReal()) * error1 / FastMath.sqrt(helper.getMainSetDimension() * den);
365
366 }
367
368 }