View Javadoc
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 }