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.numerical.SingleDimensionFunctionEvaluatorListener;
19
20 /**
21 * Integrates single dimension functions over a specified interval.
22 */
23 public abstract class Integrator {
24
25 /**
26 * Default integrator type. Picks the safest option when no prior knowledge about the integrand
27 * is known.
28 */
29 public static final IntegratorType DEFAULT_INTEGRATOR_TYPE = IntegratorType.ROMBERG;
30
31 /**
32 * Default quadrature type. Picks the safest option when no prior knowledge about the integrand
33 * is known.
34 */
35 public static final QuadratureType DEFAULT_QUADRATURE_TYPE = QuadratureType.TRAPEZOIDAL;
36
37 /**
38 * Gets type of integrator.
39 *
40 * @return type of integrator.
41 */
42 public abstract IntegratorType getIntegratorType();
43
44 /**
45 * Gets type of quadrature.
46 *
47 * @return type of quadrature.
48 */
49 public abstract QuadratureType getQuadratureType();
50
51 /**
52 * Integrates function between provided lower and upper limits.
53 *
54 * @return result of integration.
55 * @throws IntegrationException if integration fails for numerical reasons.
56 */
57 public abstract double integrate() throws IntegrationException;
58
59 /**
60 * Creates an integrator using provided integrator and quadrature types.
61 * It must be noticed that upper limit of integration is ignored when using exponential
62 * mid-point quadrature type for Romberg's integration method.
63 *
64 * @param a Lower limit of integration.
65 * @param b Upper limit of integration.
66 * @param listener listener to evaluate a single dimension function at required points.
67 * @param eps required accuracy.
68 * @param integratorType integrator type.
69 * @param quadratureType quadrature type.
70 * @return created integrator.
71 * @throws IllegalArgumentException if provided quadrature type is not supported for required
72 * integrator type.
73 */
74 public static Integrator create(
75 final double a, final double b, final SingleDimensionFunctionEvaluatorListener listener, final double eps,
76 final IntegratorType integratorType, final QuadratureType quadratureType) {
77 return switch (integratorType) {
78 case ROMBERG -> RombergIntegrator.create(a, b, listener, eps, quadratureType);
79 case SIMPSON -> SimpsonIntegrator.create(a, b, listener, eps, quadratureType);
80 default -> QuadratureIntegrator.create(a, b, listener, eps, quadratureType);
81 };
82 }
83
84 /**
85 * Creates an integrator using provided integrator and quadrature types with default accuracy.
86 * It must be noticed that upper limit of integration is ignored when using exponential
87 * mid-point quadrature type for Romberg's integration method.
88 *
89 * @param a Lower limit of integration.
90 * @param b Upper limit of integration.
91 * @param listener listener to evaluate a single dimension function at required points.
92 * @param integratorType integrator type.
93 * @param quadratureType quadrature type.
94 * @return created integrator.
95 * @throws IllegalArgumentException if provided quadrature type is not supported for required
96 * integrator type.
97 */
98 @SuppressWarnings("Duplicates")
99 public static Integrator create(
100 final double a, final double b, final SingleDimensionFunctionEvaluatorListener listener,
101 final IntegratorType integratorType, final QuadratureType quadratureType) {
102 return switch (integratorType) {
103 case ROMBERG -> RombergIntegrator.create(a, b, listener, quadratureType);
104 case SIMPSON -> SimpsonIntegrator.create(a, b, listener, quadratureType);
105 default -> QuadratureIntegrator.create(a, b, listener, quadratureType);
106 };
107 }
108
109 /**
110 * Creates an integrator using provided integrator type and using default quadrature type.
111 * It must be noticed that upper limit of integration is ignored when using exponential
112 * mid-point quadrature type for Romberg's integration method.
113 *
114 * @param a Lower limit of integration.
115 * @param b Upper limit of integration.
116 * @param listener listener to evaluate a single dimension function at required points.
117 * @param eps required accuracy.
118 * @param integratorType integrator type.
119 * @return created integrator.
120 */
121 @SuppressWarnings("Duplicates")
122 public static Integrator create(
123 final double a, final double b, final SingleDimensionFunctionEvaluatorListener listener, final double eps,
124 final IntegratorType integratorType) {
125 return switch (integratorType) {
126 case ROMBERG -> RombergIntegrator.create(a, b, listener, eps);
127 case SIMPSON -> SimpsonIntegrator.create(a, b, listener, eps);
128 default -> QuadratureIntegrator.create(a, b, listener, eps);
129 };
130 }
131
132 /**
133 * Creates an integrator using provided integrator type with default accuracy and using default
134 * quadrature type.
135 * It must be noticed that upper limit of integration is ignored when using exponential
136 * mid-point quadrature type for Romberg's integration method.
137 *
138 * @param a Lower limit of integration.
139 * @param b Upper limit of integration.
140 * @param listener listener to evaluate a single dimension function at required points.
141 * @param integratorType integrator type.
142 * @return created integrator.
143 */
144 public static Integrator create(
145 final double a, final double b, final SingleDimensionFunctionEvaluatorListener listener,
146 final IntegratorType integratorType) {
147 return switch (integratorType) {
148 case ROMBERG -> RombergIntegrator.create(a, b, listener);
149 case SIMPSON -> SimpsonIntegrator.create(a, b, listener);
150 default -> QuadratureIntegrator.create(a, b, listener);
151 };
152 }
153
154 /**
155 * Creates an integrator using default integrator and quadrature types.
156 * It must be noticed that upper limit of integration is ignored when using exponential
157 * mid-point quadrature type for Romberg's integration method.
158 *
159 * @param a Lower limit of integration.
160 * @param b Upper limit of integration.
161 * @param listener listener to evaluate a single dimension function at required points.
162 * @param eps required accuracy.
163 * @return created integrator.
164 */
165 public static Integrator create(
166 final double a, final double b, final SingleDimensionFunctionEvaluatorListener listener, final double eps) {
167 return create(a, b, listener, eps, DEFAULT_INTEGRATOR_TYPE);
168 }
169
170 /**
171 * Creates an integrator using default integrator and quadrature types with default accuracy.
172 * It must be noticed that upper limit of integration is ignored when using exponential
173 * mid-point quadrature type for Romberg's integration method.
174 *
175 * @param a Lower limit of integration.
176 * @param b Upper limit of integration.
177 * @param listener listener to evaluate a single dimension function at required points.
178 * @return created integrator.
179 */
180 public static Integrator create(
181 final double a, final double b, final SingleDimensionFunctionEvaluatorListener listener) {
182 return create(a, b, listener, DEFAULT_INTEGRATOR_TYPE);
183 }
184 }