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    *      https://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  
18  /*
19   * This is not the original file distributed by the Apache Software Foundation
20   * It has been modified by the Hipparchus project
21   */
22  package org.hipparchus.analysis.integration.gauss;
23  
24  import org.hipparchus.util.Binary64;
25  import org.hipparchus.util.FastMath;
26  import org.junit.Assert;
27  import org.junit.Test;
28  
29  /**
30   * Base class for standard testing of Gaussian quadrature rules,
31   * which are exact for polynomials up to a certain degree. In this test, each
32   * monomial in turn is tested against the specified quadrature rule.
33   *
34   */
35  public abstract class FieldGaussianQuadratureAbstractTest {
36      /**
37       * The maximum absolute error (for zero testing).
38       */
39      private final double eps;
40      /**
41       * The maximum relative error (in ulps).
42       */
43      private final double numUlps;
44      /**
45       * The quadrature rule under test.
46       */
47      private final FieldGaussIntegrator<Binary64> integrator;
48      /**
49       * Maximum degree of monomials to be tested.
50       */
51      private final int maxDegree;
52  
53      /**
54       * Creates a new instance of this abstract test with the specified
55       * quadrature rule.
56       * If the expected value is non-zero, equality of actual and expected values
57       * is checked in the relative sense <center>
58       * |x<sub>act</sub>&nbsp;-&nbsp;x<sub>exp</sub>|&nbsp;&le;&nbsp; n&nbsp;
59       * <code>Math.ulp(</code>x<sub>exp</sub><code>)</code>, </center> where n is
60       * the maximum relative error (in ulps). If the expected value is zero, the
61       * test checks that <center> |x<sub>act</sub>|&nbsp;&le;&nbsp;&epsilon;,
62       * </center> where &epsilon; is the maximum absolute error.
63       *
64       * @param integrator Quadrature rule under test.
65       * @param maxDegree Maximum degree of monomials to be tested.
66       * @param eps &epsilon;.
67       * @param numUlps Value of the maximum relative error (in ulps).
68       */
69      public FieldGaussianQuadratureAbstractTest(FieldGaussIntegrator<Binary64> integrator,
70                                                 int maxDegree,
71                                                 double eps,
72                                                 double numUlps) {
73          this.integrator = integrator;
74          this.maxDegree = maxDegree;
75          this.eps = eps;
76          this.numUlps = numUlps;
77      }
78  
79      /**
80       * Returns the expected value of the integral of the specified monomial.
81       * The integration is carried out on the natural interval of the quadrature
82       * rule under test.
83       *
84       * @param n Degree of the monomial.
85       * @return the expected value of the integral of x<sup>n</sup>.
86       */
87      public abstract double getExpectedValue(final int n);
88  
89      /**
90       * Checks that the value of the integral of each monomial
91       *   <code>x<sup>0</sup>, ... , x<sup>p</sup></code>
92       * returned by the quadrature rule under test conforms with the expected
93       * value.
94       * Here {@code p} denotes the degree of the highest polynomial for which
95       * exactness is to be expected.
96       */
97      @Test
98      public void testAllMonomials() {
99          for (int n = 0; n <= maxDegree; n++) {
100             final double expected = getExpectedValue(n);
101 
102             final int p = n;
103             final double actual = integrator.integrate(x -> FastMath.pow(x, p)).getReal();
104 
105             // System.out.println(n + "/" + maxDegree + " " + integrator.getNumberOfPoints()
106             //                    + " " + expected + " " + actual + " " + Math.ulp(expected));
107             if (expected == 0) {
108                 Assert.assertEquals("while integrating monomial x**" + n +
109                                     " with a " +
110                                     integrator.getNumberOfPoints() + "-point quadrature rule",
111                                     expected, actual, eps);
112             } else {
113                 double err = FastMath.abs(actual - expected) / Math.ulp(expected);
114                 Assert.assertEquals("while integrating monomial x**" + n + " with a " +
115                                     + integrator.getNumberOfPoints() + "-point quadrature rule, " +
116                                     " error was " + err + " ulps",
117                                     expected, actual, Math.ulp(expected) * numUlps);
118             }
119         }
120     }
121 }