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.sampling.StepInterpolator;
21 import org.apache.commons.math4.core.jdkmath.JdkMath;
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54 class GillStepInterpolator
55 extends RungeKuttaStepInterpolator {
56
57
58 private static final double ONE_MINUS_INV_SQRT_2 = 1 - JdkMath.sqrt(0.5);
59
60
61 private static final double ONE_PLUS_INV_SQRT_2 = 1 + JdkMath.sqrt(0.5);
62
63
64 private static final long serialVersionUID = 20111120L;
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79 public GillStepInterpolator() {
80 }
81
82
83
84
85
86
87
88 GillStepInterpolator(final GillStepInterpolator interpolator) {
89 super(interpolator);
90 }
91
92
93 @Override
94 protected StepInterpolator doCopy() {
95 return new GillStepInterpolator(this);
96 }
97
98
99
100 @Override
101 protected void computeInterpolatedStateAndDerivatives(final double theta,
102 final double oneMinusThetaH) {
103
104 final double twoTheta = 2 * theta;
105 final double fourTheta2 = twoTheta * twoTheta;
106 final double coeffDot1 = theta * (twoTheta - 3) + 1;
107 final double cDot23 = twoTheta * (1 - theta);
108 final double coeffDot2 = cDot23 * ONE_MINUS_INV_SQRT_2;
109 final double coeffDot3 = cDot23 * ONE_PLUS_INV_SQRT_2;
110 final double coeffDot4 = theta * (twoTheta - 1);
111
112 if (previousState != null && theta <= 0.5) {
113 final double s = theta * h / 6.0;
114 final double c23 = s * (6 * theta - fourTheta2);
115 final double coeff1 = s * (6 - 9 * theta + fourTheta2);
116 final double coeff2 = c23 * ONE_MINUS_INV_SQRT_2;
117 final double coeff3 = c23 * ONE_PLUS_INV_SQRT_2;
118 final double coeff4 = s * (-3 * theta + fourTheta2);
119 for (int i = 0; i < interpolatedState.length; ++i) {
120 final double yDot1 = yDotK[0][i];
121 final double yDot2 = yDotK[1][i];
122 final double yDot3 = yDotK[2][i];
123 final double yDot4 = yDotK[3][i];
124 interpolatedState[i] =
125 previousState[i] + coeff1 * yDot1 + coeff2 * yDot2 + coeff3 * yDot3 + coeff4 * yDot4;
126 interpolatedDerivatives[i] =
127 coeffDot1 * yDot1 + coeffDot2 * yDot2 + coeffDot3 * yDot3 + coeffDot4 * yDot4;
128 }
129 } else {
130 final double s = oneMinusThetaH / 6.0;
131 final double c23 = s * (2 + twoTheta - fourTheta2);
132 final double coeff1 = s * (1 - 5 * theta + fourTheta2);
133 final double coeff2 = c23 * ONE_MINUS_INV_SQRT_2;
134 final double coeff3 = c23 * ONE_PLUS_INV_SQRT_2;
135 final double coeff4 = s * (1 + theta + fourTheta2);
136 for (int i = 0; i < interpolatedState.length; ++i) {
137 final double yDot1 = yDotK[0][i];
138 final double yDot2 = yDotK[1][i];
139 final double yDot3 = yDotK[2][i];
140 final double yDot4 = yDotK[3][i];
141 interpolatedState[i] =
142 currentState[i] - coeff1 * yDot1 - coeff2 * yDot2 - coeff3 * yDot3 - coeff4 * yDot4;
143 interpolatedDerivatives[i] =
144 coeffDot1 * yDot1 + coeffDot2 * yDot2 + coeffDot3 * yDot3 + coeffDot4 * yDot4;
145 }
146 }
147 }
148 }