1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package com.irurueta.numerical.integration;
17
18 import com.irurueta.numerical.EvaluationException;
19 import com.irurueta.numerical.SingleDimensionFunctionEvaluatorListener;
20
21
22
23
24
25
26
27
28
29
30 public abstract class SimpsonIntegrator<T extends Quadrature> extends Integrator {
31
32
33
34
35 public static final double EPS = 1e-10;
36
37
38
39
40 private static final int JMIN = 5;
41
42
43
44
45 private static final int JMAX = 20;
46
47
48
49
50 private final T q;
51
52
53
54
55 private final double eps;
56
57
58
59
60
61
62
63 protected SimpsonIntegrator(final T q, final double eps) {
64 this.q = q;
65 this.eps = eps;
66 }
67
68
69
70
71
72
73
74 @Override
75 public double integrate() throws IntegrationException {
76 try {
77 double s;
78 double st;
79 var ost = 0.0;
80 var os = 0.0;
81 for (var j = 0; j < JMAX; j++) {
82 st = q.next();
83 s = (4.0 * st - ost) / 3.0;
84 if (j > JMIN && (Math.abs(s - os) < eps * Math.abs(os) || (s == 0.0 && os == 0.0))) {
85 return s;
86 }
87 os = s;
88 ost = st;
89 }
90 } catch (final EvaluationException e) {
91 throw new IntegrationException(e);
92 }
93
94
95 throw new IntegrationException();
96 }
97
98
99
100
101
102
103 @Override
104 public IntegratorType getIntegratorType() {
105 return IntegratorType.SIMPSON;
106 }
107
108
109
110
111
112
113
114
115
116
117
118
119 public static SimpsonIntegrator<Quadrature> create(
120 final double a, final double b, final SingleDimensionFunctionEvaluatorListener listener, final double eps,
121 final QuadratureType quadratureType) {
122 return switch (quadratureType) {
123 case TRAPEZOIDAL -> cast(new SimpsonTrapezoidalQuadratureIntegrator(a, b, listener, eps));
124 case MID_POINT -> cast(new SimpsonMidPointQuadratureIntegrator(a, b, listener, eps));
125 case INFINITY_MID_POINT -> cast(new SimpsonInfinityMidPointQuadratureIntegrator(a, b, listener, eps));
126 case LOWER_SQUARE_ROOT_MID_POINT ->
127 cast(new SimpsonLowerSquareRootMidPointQuadratureIntegrator(a, b, listener, eps));
128 case UPPER_SQUARE_ROOT_MID_POINT ->
129 cast(new SimpsonUpperSquareRootMidPointQuadratureIntegrator(a, b, listener, eps));
130 case DOUBLE_EXPONENTIAL_RULE ->
131 cast(new SimpsonDoubleExponentialRuleQuadratureIntegrator(a, b, listener, eps));
132 default -> throw new IllegalArgumentException();
133 };
134 }
135
136
137
138
139
140
141
142
143
144
145
146 public static SimpsonIntegrator<Quadrature> create(
147 final double a, final double b, final SingleDimensionFunctionEvaluatorListener listener,
148 final QuadratureType quadratureType) {
149 return switch (quadratureType) {
150 case TRAPEZOIDAL -> cast(new SimpsonTrapezoidalQuadratureIntegrator(a, b, listener));
151 case MID_POINT -> cast(new SimpsonMidPointQuadratureIntegrator(a, b, listener));
152 case INFINITY_MID_POINT -> cast(new SimpsonInfinityMidPointQuadratureIntegrator(a, b, listener));
153 case LOWER_SQUARE_ROOT_MID_POINT ->
154 cast(new SimpsonLowerSquareRootMidPointQuadratureIntegrator(a, b, listener));
155 case UPPER_SQUARE_ROOT_MID_POINT ->
156 cast(new SimpsonUpperSquareRootMidPointQuadratureIntegrator(a, b, listener));
157 case DOUBLE_EXPONENTIAL_RULE -> cast(new SimpsonDoubleExponentialRuleQuadratureIntegrator(a, b, listener));
158 default -> throw new IllegalArgumentException();
159 };
160 }
161
162
163
164
165
166
167
168
169
170
171 public static SimpsonIntegrator<Quadrature> create(
172 final double a, final double b, final SingleDimensionFunctionEvaluatorListener listener, final double eps) {
173 return create(a, b, listener, eps, DEFAULT_QUADRATURE_TYPE);
174 }
175
176
177
178
179
180
181
182
183
184 public static SimpsonIntegrator<Quadrature> create(
185 final double a, final double b, final SingleDimensionFunctionEvaluatorListener listener) {
186 return create(a, b, listener, DEFAULT_QUADRATURE_TYPE);
187 }
188
189
190
191
192
193
194
195 private static SimpsonIntegrator<Quadrature> cast(final SimpsonIntegrator<?> integrator) {
196
197 return (SimpsonIntegrator<Quadrature>) integrator;
198 }
199 }