1 /*
2 * Copyright (C) 2023 Alberto Irurueta Carro (alberto@irurueta.com)
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package com.irurueta.numerical.integration;
17
18 import com.irurueta.algebra.Matrix;
19 import com.irurueta.algebra.WrongSizeException;
20
21 /**
22 * Integrates single dimension matrix (multivariate) functions over a specified interval.
23 */
24 public abstract class MatrixIntegrator {
25
26 /**
27 * Default integrator type. Picks the safest option when no prior knowledge about the integrand
28 * is known.
29 */
30 public static final IntegratorType DEFAULT_INTEGRATOR_TYPE = IntegratorType.ROMBERG;
31
32 /**
33 * Default quadrature type. Picks the safest option when no prior knowledge about the integrand
34 * is known.
35 */
36 public static final QuadratureType DEFAULT_QUADRATURE_TYPE = QuadratureType.TRAPEZOIDAL;
37
38 /**
39 * Gets type of integrator.
40 *
41 * @return type of integrator.
42 */
43 public abstract IntegratorType getIntegratorType();
44
45 /**
46 * Gets type of quadrature.
47 *
48 * @return type of quadrature.
49 */
50 public abstract QuadratureType getQuadratureType();
51
52 /**
53 * Integrates function between provided lower and upper limits.
54 *
55 * @param result instance where result of integration will be stored.
56 * @throws IntegrationException if integration fails for numerical reasons.
57 */
58 public abstract void integrate(final Matrix result) throws IntegrationException;
59
60 /**
61 * Creates an integrator using provided integrator and quadrature types.
62 * It must be noticed that upper limit of integration is ignored when using exponential
63 * mid-point quadrature type for Romberg's integration method.
64 *
65 * @param a Lower limit of integration.
66 * @param b Upper limit of integration.
67 * @param listener listener to evaluate a single dimension function at required points.
68 * @param eps required accuracy.
69 * @param integratorType integrator type.
70 * @param quadratureType quadrature type.
71 * @return created integrator.
72 * @throws IllegalArgumentException if provided quadrature type is not supported for required
73 * integrator type.
74 * @throws WrongSizeException if size notified by provided listener is invalid.
75 */
76 public static MatrixIntegrator create(
77 final double a, final double b, final MatrixSingleDimensionFunctionEvaluatorListener listener,
78 final double eps, final IntegratorType integratorType, final QuadratureType quadratureType)
79 throws WrongSizeException {
80 return switch (integratorType) {
81 case ROMBERG -> RombergMatrixIntegrator.create(a, b, listener, eps, quadratureType);
82 case SIMPSON -> SimpsonMatrixIntegrator.create(a, b, listener, eps, quadratureType);
83 default -> QuadratureMatrixIntegrator.create(a, b, listener, eps, quadratureType);
84 };
85 }
86
87 /**
88 * Creates an integrator using provided integrator and quadrature types with default accuracy.
89 * It must be noticed that upper limit of integration is ignored when using exponential
90 * mid-point quadrature type for Romberg's integration method.
91 *
92 * @param a Lower limit of integration.
93 * @param b Upper limit of integration.
94 * @param listener listener to evaluate a single dimension function at required points.
95 * @param integratorType integrator type.
96 * @param quadratureType quadrature type.
97 * @return created integrator.
98 * @throws IllegalArgumentException if provided quadrature type is not supported for required
99 * integrator type.
100 * @throws WrongSizeException if size notified by provided listener is invalid.
101 */
102 @SuppressWarnings("Duplicates")
103 public static MatrixIntegrator create(
104 final double a, final double b, final MatrixSingleDimensionFunctionEvaluatorListener listener,
105 final IntegratorType integratorType, final QuadratureType quadratureType) throws WrongSizeException {
106 return switch (integratorType) {
107 case ROMBERG -> RombergMatrixIntegrator.create(a, b, listener, quadratureType);
108 case SIMPSON -> SimpsonMatrixIntegrator.create(a, b, listener, quadratureType);
109 default -> QuadratureMatrixIntegrator.create(a, b, listener, quadratureType);
110 };
111 }
112
113 /**
114 * Creates an integrator using provided integrator type and using default quadrature type.
115 * It must be noticed that upper limit of integration is ignored when using exponential
116 * mid-point quadrature type for Romberg's integration method.
117 *
118 * @param a Lower limit of integration.
119 * @param b Upper limit of integration.
120 * @param listener listener to evaluate a single dimension function at required points.
121 * @param eps required accuracy.
122 * @param integratorType integrator type.
123 * @return created integrator.
124 * @throws WrongSizeException if size notified by provided listener is invalid.
125 */
126 @SuppressWarnings("Duplicates")
127 public static MatrixIntegrator create(
128 final double a, final double b, final MatrixSingleDimensionFunctionEvaluatorListener listener,
129 final double eps, final IntegratorType integratorType) throws WrongSizeException {
130 return switch (integratorType) {
131 case ROMBERG -> RombergMatrixIntegrator.create(a, b, listener, eps);
132 case SIMPSON -> SimpsonMatrixIntegrator.create(a, b, listener, eps);
133 default -> QuadratureMatrixIntegrator.create(a, b, listener, eps);
134 };
135 }
136
137 /**
138 * Creates an integrator using provided integrator type with default accuracy and using default
139 * quadrature type.
140 * It must be noticed that upper limit of integration is ignored when using exponential
141 * mid-point quadrature type for Romberg's integration method.
142 *
143 * @param a Lower limit of integration.
144 * @param b Upper limit of integration.
145 * @param listener listener to evaluate a single dimension function at required points.
146 * @param integratorType integrator type.
147 * @return created integrator.
148 * @throws WrongSizeException if size notified by provided listener is invalid.
149 */
150 public static MatrixIntegrator create(
151 final double a, final double b, final MatrixSingleDimensionFunctionEvaluatorListener listener,
152 final IntegratorType integratorType) throws WrongSizeException {
153 return switch (integratorType) {
154 case ROMBERG -> RombergMatrixIntegrator.create(a, b, listener);
155 case SIMPSON -> SimpsonMatrixIntegrator.create(a, b, listener);
156 default -> QuadratureMatrixIntegrator.create(a, b, listener);
157 };
158 }
159
160 /**
161 * Creates an integrator using default integrator and quadrature types.
162 * It must be noticed that upper limit of integration is ignored when using exponential
163 * mid-point quadrature type for Romberg's integration method.
164 *
165 * @param a Lower limit of integration.
166 * @param b Upper limit of integration.
167 * @param listener listener to evaluate a single dimension function at required points.
168 * @param eps required accuracy.
169 * @return created integrator.
170 * @throws WrongSizeException if size notified by provided listener is invalid.
171 */
172 public static MatrixIntegrator create(
173 final double a, final double b, final MatrixSingleDimensionFunctionEvaluatorListener listener,
174 final double eps) throws WrongSizeException {
175 return create(a, b, listener, eps, DEFAULT_INTEGRATOR_TYPE);
176 }
177
178 /**
179 * Creates an integrator using default integrator and quadrature types with default accuracy.
180 * It must be noticed that upper limit of integration is ignored when using exponential
181 * mid-point quadrature type for Romberg's integration method.
182 *
183 * @param a Lower limit of integration.
184 * @param b Upper limit of integration.
185 * @param listener listener to evaluate a single dimension function at required points.
186 * @return created integrator.
187 * @throws WrongSizeException if size notified by provided listener is invalid.
188 */
189 public static MatrixIntegrator create(
190 final double a, final double b, final MatrixSingleDimensionFunctionEvaluatorListener listener)
191 throws WrongSizeException {
192 return create(a, b, listener, DEFAULT_INTEGRATOR_TYPE);
193 }
194 }