View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.math4.legacy.analysis.integration.gauss;
18  
19  import org.apache.commons.math4.legacy.analysis.function.Power;
20  import org.apache.commons.math4.core.jdkmath.JdkMath;
21  import org.junit.Test;
22  import org.junit.Assert;
23  
24  /**
25   * Base class for standard testing of Gaussian quadrature rules,
26   * which are exact for polynomials up to a certain degree. In this test, each
27   * monomial in turn is tested against the specified quadrature rule.
28   *
29   */
30  public abstract class GaussianQuadratureAbstractTest {
31      /**
32       * The maximum absolute error (for zero testing).
33       */
34      private final double eps;
35      /**
36       * The maximum relative error (in ulps).
37       */
38      private final double numUlps;
39      /**
40       * The quadrature rule under test.
41       */
42      private final GaussIntegrator integrator;
43      /**
44       * Maximum degree of monomials to be tested.
45       */
46      private final int maxDegree;
47  
48      /**
49       * Creates a new instance of this abstract test with the specified
50       * quadrature rule.
51       * If the expected value is non-zero, equality of actual and expected values
52       * is checked in the relative sense <center>
53       * |x<sub>act</sub>&nbsp;-&nbsp;x<sub>exp</sub>|&nbsp;&le;&nbsp; n&nbsp;
54       * <code>Math.ulp(</code>x<sub>exp</sub><code>)</code>, </center> where n is
55       * the maximum relative error (in ulps). If the expected value is zero, the
56       * test checks that <center> |x<sub>act</sub>|&nbsp;&le;&nbsp;&epsilon;,
57       * </center> where &epsilon; is the maximum absolute error.
58       *
59       * @param integrator Quadrature rule under test.
60       * @param maxDegree Maximum degree of monomials to be tested.
61       * @param eps &epsilon;.
62       * @param numUlps Value of the maximum relative error (in ulps).
63       */
64      public GaussianQuadratureAbstractTest(GaussIntegrator integrator,
65                                            int maxDegree,
66                                            double eps,
67                                            double numUlps) {
68          this.integrator = integrator;
69          this.maxDegree = maxDegree;
70          this.eps = eps;
71          this.numUlps = numUlps;
72      }
73  
74      /**
75       * Returns the expected value of the integral of the specified monomial.
76       * The integration is carried out on the natural interval of the quadrature
77       * rule under test.
78       *
79       * @param n Degree of the monomial.
80       * @return the expected value of the integral of x<sup>n</sup>.
81       */
82      public abstract double getExpectedValue(int n);
83  
84      /**
85       * Checks that the value of the integral of each monomial
86       *   <code>x<sup>0</sup>, ... , x<sup>p</sup></code>
87       * returned by the quadrature rule under test conforms with the expected
88       * value.
89       * Here {@code p} denotes the degree of the highest polynomial for which
90       * exactness is to be expected.
91       */
92      @Test
93      public void testAllMonomials() {
94          for (int n = 0; n <= maxDegree; n++) {
95              final double expected = getExpectedValue(n);
96  
97              final Power monomial = new Power(n);
98              final double actual = integrator.integrate(monomial);
99  
100             // System.out.println(n + "/" + maxDegree + " " + integrator.getNumberOfPoints()
101             //                    + " " + expected + " " + actual + " " + Math.ulp(expected));
102             if (expected == 0) {
103                 Assert.assertEquals("while integrating monomial x**" + n +
104                                     " with a " +
105                                     integrator.getNumberOfPoints() + "-point quadrature rule",
106                                     expected, actual, eps);
107             } else {
108                 double err = JdkMath.abs(actual - expected) / Math.ulp(expected);
109                 Assert.assertEquals("while integrating monomial x**" + n + " with a " +
110                                     + integrator.getNumberOfPoints() + "-point quadrature rule, " +
111                                     " error was " + err + " ulps",
112                                     expected, actual, Math.ulp(expected) * numUlps);
113             }
114         }
115     }
116 }