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 }