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