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 org.apache.commons.math4.legacy.ode.AbstractIntegrator;
21 import org.apache.commons.math4.legacy.ode.EquationsMapper;
22 import org.apache.commons.math4.legacy.ode.sampling.StepInterpolator;
23
24
25
26
27
28
29
30
31
32
33 class DormandPrince54StepInterpolator
34 extends RungeKuttaStepInterpolator {
35
36
37 private static final double A70 = 35.0 / 384.0;
38
39
40
41
42 private static final double A72 = 500.0 / 1113.0;
43
44
45 private static final double A73 = 125.0 / 192.0;
46
47
48 private static final double A74 = -2187.0 / 6784.0;
49
50
51 private static final double A75 = 11.0 / 84.0;
52
53
54 private static final double D0 = -12715105075.0 / 11282082432.0;
55
56
57
58
59 private static final double D2 = 87487479700.0 / 32700410799.0;
60
61
62 private static final double D3 = -10690763975.0 / 1880347072.0;
63
64
65 private static final double D4 = 701980252875.0 / 199316789632.0;
66
67
68 private static final double D5 = -1453857185.0 / 822651844.0;
69
70
71 private static final double D6 = 69997945.0 / 29380423.0;
72
73
74 private static final long serialVersionUID = 20111120L;
75
76
77 private double[] v1;
78
79
80 private double[] v2;
81
82
83 private double[] v3;
84
85
86 private double[] v4;
87
88
89 private boolean vectorsInitialized;
90
91
92
93
94
95
96
97
98
99
100
101
102 public DormandPrince54StepInterpolator() {
103 super();
104 v1 = null;
105 v2 = null;
106 v3 = null;
107 v4 = null;
108 vectorsInitialized = false;
109 }
110
111
112
113
114
115
116
117 DormandPrince54StepInterpolator(final DormandPrince54StepInterpolator interpolator) {
118
119 super(interpolator);
120
121 if (interpolator.v1 == null) {
122
123 v1 = null;
124 v2 = null;
125 v3 = null;
126 v4 = null;
127 vectorsInitialized = false;
128 } else {
129
130 v1 = interpolator.v1.clone();
131 v2 = interpolator.v2.clone();
132 v3 = interpolator.v3.clone();
133 v4 = interpolator.v4.clone();
134 vectorsInitialized = interpolator.vectorsInitialized;
135 }
136 }
137
138
139 @Override
140 protected StepInterpolator doCopy() {
141 return new DormandPrince54StepInterpolator(this);
142 }
143
144
145
146 @Override
147 public void reinitialize(final AbstractIntegrator integrator,
148 final double[] y, final double[][] yDotK, final boolean forward,
149 final EquationsMapper primaryMapper,
150 final EquationsMapper[] secondaryMappers) {
151 super.reinitialize(integrator, y, yDotK, forward, primaryMapper, secondaryMappers);
152 v1 = null;
153 v2 = null;
154 v3 = null;
155 v4 = null;
156 vectorsInitialized = false;
157 }
158
159
160 @Override
161 public void storeTime(final double t) {
162 super.storeTime(t);
163 vectorsInitialized = false;
164 }
165
166
167 @Override
168 protected void computeInterpolatedStateAndDerivatives(final double theta,
169 final double oneMinusThetaH) {
170
171 if (! vectorsInitialized) {
172
173 if (v1 == null) {
174 v1 = new double[interpolatedState.length];
175 v2 = new double[interpolatedState.length];
176 v3 = new double[interpolatedState.length];
177 v4 = new double[interpolatedState.length];
178 }
179
180
181
182
183 for (int i = 0; i < interpolatedState.length; ++i) {
184 final double yDot0 = yDotK[0][i];
185 final double yDot2 = yDotK[2][i];
186 final double yDot3 = yDotK[3][i];
187 final double yDot4 = yDotK[4][i];
188 final double yDot5 = yDotK[5][i];
189 final double yDot6 = yDotK[6][i];
190 v1[i] = A70 * yDot0 + A72 * yDot2 + A73 * yDot3 + A74 * yDot4 + A75 * yDot5;
191 v2[i] = yDot0 - v1[i];
192 v3[i] = v1[i] - v2[i] - yDot6;
193 v4[i] = D0 * yDot0 + D2 * yDot2 + D3 * yDot3 + D4 * yDot4 + D5 * yDot5 + D6 * yDot6;
194 }
195
196 vectorsInitialized = true;
197 }
198
199
200 final double eta = 1 - theta;
201 final double twoTheta = 2 * theta;
202 final double dot2 = 1 - twoTheta;
203 final double dot3 = theta * (2 - 3 * theta);
204 final double dot4 = twoTheta * (1 + theta * (twoTheta - 3));
205 if (previousState != null && theta <= 0.5) {
206 for (int i = 0; i < interpolatedState.length; ++i) {
207 interpolatedState[i] =
208 previousState[i] + theta * h * (v1[i] + eta * (v2[i] + theta * (v3[i] + eta * v4[i])));
209 interpolatedDerivatives[i] = v1[i] + dot2 * v2[i] + dot3 * v3[i] + dot4 * v4[i];
210 }
211 } else {
212 for (int i = 0; i < interpolatedState.length; ++i) {
213 interpolatedState[i] =
214 currentState[i] - oneMinusThetaH * (v1[i] - theta * (v2[i] + theta * (v3[i] + eta * v4[i])));
215 interpolatedDerivatives[i] = v1[i] + dot2 * v2[i] + dot3 * v3[i] + dot4 * v4[i];
216 }
217 }
218 }
219 }