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.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 }