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.algebra.AlgebraException;
19 import com.irurueta.algebra.Matrix;
20 import com.irurueta.algebra.WrongSizeException;
21 import com.irurueta.numerical.EvaluationException;
22
23
24
25
26
27
28
29
30
31
32
33 public abstract class QuadratureMatrixIntegrator<T extends MatrixQuadrature> extends MatrixIntegrator {
34
35
36
37 public static final double EPS = 1e-10;
38
39
40
41
42 private static final int JMIN = 5;
43
44
45
46
47 private static final int JMAX = 35;
48
49
50
51
52 private final T q;
53
54
55
56
57 private final double eps;
58
59
60
61
62
63
64
65 protected QuadratureMatrixIntegrator(final T q, final double eps) {
66 this.q = q;
67 this.eps = eps;
68 }
69
70
71
72
73
74
75
76 @SuppressWarnings("Duplicates")
77 @Override
78 public void integrate(final Matrix result) throws IntegrationException {
79 try {
80 final var rows = q.getRows();
81 final var columns = q.getColumns();
82 final var s = new Matrix(rows, columns);
83
84
85 final var olds = new Matrix(rows, columns);
86
87 for (var j = 0; j < JMAX; j++) {
88 q.next(s);
89 if (j > JMIN && (Math.abs(normMin(s) - normMin(olds)) < eps * normMin(olds)
90 || (normMin(s) == 0.0 && normMin(olds) == 0.0))) {
91
92 result.copyFrom(s);
93 return;
94 }
95 olds.copyFrom(s);
96 }
97 } catch (final EvaluationException | AlgebraException e) {
98 throw new IntegrationException(e);
99 }
100
101
102 throw new IntegrationException();
103 }
104
105
106
107
108
109
110 @Override
111 public IntegratorType getIntegratorType() {
112 return IntegratorType.QUADRATURE;
113 }
114
115
116
117
118
119
120
121
122
123
124
125
126
127 public static QuadratureMatrixIntegrator<MatrixQuadrature> create(
128 final double a, final double b, final MatrixSingleDimensionFunctionEvaluatorListener listener,
129 final double eps, final QuadratureType quadratureType) throws WrongSizeException {
130 return switch (quadratureType) {
131 case TRAPEZOIDAL -> cast(new TrapezoidalQuadratureMatrixIntegrator(a, b, listener, eps));
132 case MID_POINT -> cast(new MidPointQuadratureMatrixIntegrator(a, b, listener, eps));
133 case INFINITY_MID_POINT -> cast(new InfinityMidPointQuadratureMatrixIntegrator(a, b, listener, eps));
134 case LOWER_SQUARE_ROOT_MID_POINT ->
135 cast(new LowerSquareRootMidPointQuadratureMatrixIntegrator(a, b, listener, eps));
136 case UPPER_SQUARE_ROOT_MID_POINT ->
137 cast(new UpperSquareRootMidPointQuadratureMatrixIntegrator(a, b, listener, eps));
138 case DOUBLE_EXPONENTIAL_RULE ->
139 cast(new DoubleExponentialRuleQuadratureMatrixIntegrator(a, b, listener, eps));
140 default -> throw new IllegalArgumentException();
141 };
142 }
143
144
145
146
147
148
149
150
151
152
153
154
155 public static QuadratureMatrixIntegrator<MatrixQuadrature> create(
156 final double a, final double b, final MatrixSingleDimensionFunctionEvaluatorListener listener,
157 final QuadratureType quadratureType) throws WrongSizeException {
158 return switch (quadratureType) {
159 case TRAPEZOIDAL -> cast(new TrapezoidalQuadratureMatrixIntegrator(a, b, listener));
160 case MID_POINT -> cast(new MidPointQuadratureMatrixIntegrator(a, b, listener));
161 case INFINITY_MID_POINT -> cast(new InfinityMidPointQuadratureMatrixIntegrator(a, b, listener));
162 case LOWER_SQUARE_ROOT_MID_POINT ->
163 cast(new LowerSquareRootMidPointQuadratureMatrixIntegrator(a, b, listener));
164 case UPPER_SQUARE_ROOT_MID_POINT ->
165 cast(new UpperSquareRootMidPointQuadratureMatrixIntegrator(a, b, listener));
166 case DOUBLE_EXPONENTIAL_RULE -> cast(new DoubleExponentialRuleQuadratureMatrixIntegrator(a, b, listener));
167 default -> throw new IllegalArgumentException();
168 };
169 }
170
171
172
173
174
175
176
177
178
179
180
181 public static QuadratureMatrixIntegrator<MatrixQuadrature> create(
182 final double a, final double b, final MatrixSingleDimensionFunctionEvaluatorListener listener,
183 final double eps) throws WrongSizeException {
184 return create(a, b, listener, eps, DEFAULT_QUADRATURE_TYPE);
185 }
186
187
188
189
190
191
192
193
194
195
196 public static QuadratureMatrixIntegrator<MatrixQuadrature> create(
197 final double a, final double b, final MatrixSingleDimensionFunctionEvaluatorListener listener)
198 throws WrongSizeException {
199 return create(a, b, listener, DEFAULT_QUADRATURE_TYPE);
200 }
201
202
203
204
205
206
207
208
209 @SuppressWarnings("Duplicates")
210 private static double normMin(final Matrix a) {
211 var min = Double.MAX_VALUE;
212 final var buffer = a.getBuffer();
213 for (var v : buffer) {
214 var value = Math.abs(v);
215 if (Double.isNaN(value)) {
216 return value;
217 }
218
219 if (value < min) {
220 min = value;
221 }
222 }
223 return min;
224 }
225
226
227
228
229
230
231
232 private static QuadratureMatrixIntegrator<MatrixQuadrature> cast(final QuadratureMatrixIntegrator<?> integrator) {
233
234 return (QuadratureMatrixIntegrator<MatrixQuadrature>) integrator;
235 }
236 }