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;
23  
24  import org.hipparchus.analysis.QuinticFunction;
25  import org.hipparchus.analysis.UnivariateFunction;
26  import org.hipparchus.analysis.function.Sin;
27  import org.hipparchus.exception.MathIllegalArgumentException;
28  import org.hipparchus.util.FastMath;
29  import org.junit.jupiter.api.Test;
30  
31  import static org.junit.jupiter.api.Assertions.assertEquals;
32  import static org.junit.jupiter.api.Assertions.assertTrue;
33  import static org.junit.jupiter.api.Assertions.fail;
34  
35  /**
36   * Test case for midpoint integrator.
37   * <p>
38   * Test runs show that for a default relative accuracy of 1E-6, it generally
39   * takes 10 to 15 iterations for the integral to converge.
40   *
41   */
42  final class MidPointIntegratorTest {
43  
44      /**
45       * Test of integrator for the sine function.
46       */
47      @Test
48      void testLowAccuracy() {
49          UnivariateFunction f = new QuinticFunction();
50          UnivariateIntegrator integrator = new MidPointIntegrator(0.01, 1.0e-10, 2, 4);
51  
52          double min = -10;
53          double max =  -9;
54          double expected = -3697001.0 / 48.0;
55          double tolerance = FastMath.abs(expected * integrator.getRelativeAccuracy());
56          double result = integrator.integrate(Integer.MAX_VALUE, f, min, max);
57          assertTrue(integrator.getEvaluations() < Integer.MAX_VALUE / 2);
58          assertTrue(integrator.getIterations() < MidPointIntegrator.MIDPOINT_MAX_ITERATIONS_COUNT / 2);
59          assertEquals(expected, result, tolerance);
60  
61      }
62  
63      /**
64       * Test of integrator for the sine function.
65       */
66      @Test
67      void testSinFunction() {
68          UnivariateFunction f = new Sin();
69          UnivariateIntegrator integrator = new MidPointIntegrator();
70  
71          double min = 0;
72          double max = FastMath.PI;
73          double expected = 2;
74          double tolerance = FastMath.abs(expected * integrator.getRelativeAccuracy());
75          double result = integrator.integrate(Integer.MAX_VALUE, f, min, max);
76          assertTrue(integrator.getEvaluations() < Integer.MAX_VALUE / 2);
77          assertTrue(integrator.getIterations() < MidPointIntegrator.MIDPOINT_MAX_ITERATIONS_COUNT / 2);
78          assertEquals(expected, result, tolerance);
79  
80          min = -FastMath.PI/3;
81          max = 0;
82          expected = -0.5;
83          tolerance = FastMath.abs(expected * integrator.getRelativeAccuracy());
84          result = integrator.integrate(Integer.MAX_VALUE, f, min, max);
85          assertTrue(integrator.getEvaluations() < Integer.MAX_VALUE / 2);
86          assertTrue(integrator.getIterations() < MidPointIntegrator.MIDPOINT_MAX_ITERATIONS_COUNT / 2);
87          assertEquals(expected, result, tolerance);
88  
89      }
90  
91      /**
92       * Test of integrator for the quintic function.
93       */
94      @Test
95      void testQuinticFunction() {
96          UnivariateFunction f = new QuinticFunction();
97          UnivariateIntegrator integrator = new MidPointIntegrator();
98  
99          double min = 0;
100         double max = 1;
101         double expected = -1.0 / 48;
102         double tolerance = FastMath.abs(expected * integrator.getRelativeAccuracy());
103         double result = integrator.integrate(Integer.MAX_VALUE, f, min, max);
104         assertTrue(integrator.getEvaluations() < Integer.MAX_VALUE / 2);
105         assertTrue(integrator.getIterations() < MidPointIntegrator.MIDPOINT_MAX_ITERATIONS_COUNT / 2);
106         assertEquals(expected, result, tolerance);
107 
108         min = 0;
109         max = 0.5;
110         expected = 11.0 / 768;
111         tolerance = FastMath.abs(expected * integrator.getRelativeAccuracy());
112         result = integrator.integrate(Integer.MAX_VALUE, f, min, max);
113         assertTrue(integrator.getEvaluations() < Integer.MAX_VALUE / 2);
114         assertTrue(integrator.getIterations() < MidPointIntegrator.MIDPOINT_MAX_ITERATIONS_COUNT / 2);
115         assertEquals(expected, result, tolerance);
116 
117         min = -1;
118         max = 4;
119         expected = 2048 / 3.0 - 78 + 1.0 / 48;
120         tolerance = FastMath.abs(expected * integrator.getRelativeAccuracy());
121         result = integrator.integrate(Integer.MAX_VALUE, f, min, max);
122         assertTrue(integrator.getEvaluations() < Integer.MAX_VALUE / 2);
123         assertTrue(integrator.getIterations() < MidPointIntegrator.MIDPOINT_MAX_ITERATIONS_COUNT / 2);
124         assertEquals(expected, result, tolerance);
125 
126     }
127 
128     /**
129      * Test of parameters for the integrator.
130      */
131     @Test
132     void testParameters() {
133         UnivariateFunction f = new Sin();
134 
135         try {
136             // bad interval
137             new MidPointIntegrator().integrate(1000, f, 1, -1);
138             fail("Expecting MathIllegalArgumentException - bad interval");
139         } catch (MathIllegalArgumentException ex) {
140             // expected
141         }
142         try {
143             // bad iteration limits
144             new MidPointIntegrator(5, 4);
145             fail("Expecting MathIllegalArgumentException - bad iteration limits");
146         } catch (MathIllegalArgumentException ex) {
147             // expected
148         }
149         try {
150             // bad iteration limits
151             new MidPointIntegrator(10, 99);
152             fail("Expecting MathIllegalArgumentException - bad iteration limits");
153         } catch (MathIllegalArgumentException ex) {
154             // expected
155         }
156     }
157 }