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.EvaluationException; 19 import com.irurueta.numerical.SingleDimensionFunctionEvaluatorListener; 20 21 /** 22 * Implementation of quadrature using trapezoidal algorithm. 23 * This implementation is suitable for non-improper integrands, which consist 24 * of functions with not known singularities that can be evaluated on all the integration 25 * interval, which must be finite. 26 */ 27 public class TrapezoidalQuadrature extends Quadrature { 28 29 /** 30 * Lower limit of integration. 31 */ 32 private final double a; 33 34 /** 35 * Upper limit of integration. 36 */ 37 private final double b; 38 39 /** 40 * Current value of integral. 41 */ 42 private double s; 43 44 /** 45 * Listener to evaluate single dimension functions at required points. 46 */ 47 private final SingleDimensionFunctionEvaluatorListener listener; 48 49 /** 50 * Constructor. 51 * 52 * @param a Lower limit of integration. 53 * @param b Upper limit of integration. 54 * @param listener listener to evaluate a single dimension function at required points. 55 */ 56 public TrapezoidalQuadrature( 57 final double a, final double b, final SingleDimensionFunctionEvaluatorListener listener) { 58 this.n = 0; 59 this.a = a; 60 this.b = b; 61 this.s = 0; 62 this.listener = listener; 63 } 64 65 /** 66 * Gets lower limit of integration. 67 * 68 * @return lower limit of integration. 69 */ 70 public double getA() { 71 return a; 72 } 73 74 /** 75 * Gets upper limit of integration. 76 * 77 * @return upper limit of integration. 78 */ 79 public double getB() { 80 return b; 81 } 82 83 /** 84 * Gets current value of integral. 85 * @return current value of integral. 86 */ 87 public double getS() { 88 return s; 89 } 90 91 /** 92 * Returns the value of the integral at the nth stage of refinement. 93 * 94 * @return the value of the integral at the nth stage of refinement. 95 * @throws EvaluationException Raised if something failed during the evaluation. 96 */ 97 @Override 98 public double next() throws EvaluationException { 99 double x; 100 double tnm; 101 double sum; 102 double del; 103 int it; 104 int j; 105 n++; 106 if (n == 1) { 107 s = 0.5 * (b - a) * (listener.evaluate(a) + listener.evaluate(b)); 108 return s; 109 } else { 110 for (it = 1, j = 1; j < n - 1; j++) { 111 it <<= 1; 112 } 113 tnm = it; 114 // This is the spacing of the points to be added 115 del = (b - a) / tnm; 116 x = a + 0.5 * del; 117 for (sum = 0.0, j = 0; j < it; j++, x += del) { 118 sum += listener.evaluate(x); 119 } 120 // This replaces s by its refined value 121 s = 0.5 * (s + (b - a) * sum / tnm); 122 return s; 123 } 124 } 125 126 /** 127 * Gets type of quadrature. 128 * 129 * @return type of quadrature. 130 */ 131 @Override 132 public QuadratureType getType() { 133 return QuadratureType.TRAPEZOIDAL; 134 } 135 }