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.CalculusFieldUnivariateFunction;
25  import org.hipparchus.exception.MathIllegalArgumentException;
26  import org.hipparchus.util.Binary64;
27  import org.hipparchus.util.Binary64Field;
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 FieldMidPointIntegratorTest {
43  
44      /**
45       * Test of integrator for the sine function.
46       */
47      @Test
48      void testLowAccuracy() {
49          CalculusFieldUnivariateFunction<Binary64> f =
50                          t -> t.subtract(1).multiply(t.subtract(0.5)).multiply(t).multiply(t.add(0.5)).multiply(t.add(1));
51          FieldUnivariateIntegrator<Binary64> integrator = new FieldMidPointIntegrator<>(Binary64Field.getInstance(), 0.01, 1.0e-10, 2, 4);
52  
53          Binary64 min = new Binary64(-10);
54          Binary64 max =  new Binary64(-9);
55          double expected = -3697001.0 / 48.0;
56          double tolerance = FastMath.abs(expected * integrator.getRelativeAccuracy());
57          double result = integrator.integrate(Integer.MAX_VALUE, f, min, max).getReal();
58          assertTrue(integrator.getEvaluations() < Integer.MAX_VALUE / 2);
59          assertTrue(integrator.getIterations() < MidPointIntegrator.MIDPOINT_MAX_ITERATIONS_COUNT / 2);
60          assertEquals(expected, result, tolerance);
61  
62      }
63  
64      /**
65       * Test of integrator for the sine function.
66       */
67      @Test
68      void testSinFunction() {
69          FieldUnivariateIntegrator<Binary64> integrator = new FieldMidPointIntegrator<>(Binary64Field.getInstance());
70  
71          Binary64 min = new Binary64(0);
72          Binary64 max = new Binary64(FastMath.PI);
73          double expected = 2;
74          double tolerance = FastMath.abs(expected * integrator.getRelativeAccuracy());
75          double result = integrator.integrate(Integer.MAX_VALUE, x -> x.sin(), min, max).getReal();
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 = new Binary64(-FastMath.PI/3);
81          max = new Binary64(0);
82          expected = -0.5;
83          tolerance = FastMath.abs(expected * integrator.getRelativeAccuracy());
84          result = integrator.integrate(Integer.MAX_VALUE, x -> x.sin(), min, max).getReal();
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          CalculusFieldUnivariateFunction<Binary64> f =
97                          t -> t.subtract(1).multiply(t.subtract(0.5)).multiply(t).multiply(t.add(0.5)).multiply(t.add(1));
98          FieldUnivariateIntegrator<Binary64> integrator = new FieldMidPointIntegrator<>(Binary64Field.getInstance());
99  
100         Binary64 min = new Binary64(0);
101         Binary64 max = new Binary64(1);
102         double expected = -1.0 / 48;
103         double tolerance = FastMath.abs(expected * integrator.getRelativeAccuracy());
104         double result = integrator.integrate(Integer.MAX_VALUE, f, min, max).getReal();
105         assertTrue(integrator.getEvaluations() < Integer.MAX_VALUE / 2);
106         assertTrue(integrator.getIterations() < MidPointIntegrator.MIDPOINT_MAX_ITERATIONS_COUNT / 2);
107         assertEquals(expected, result, tolerance);
108 
109         min = new Binary64(0);
110         max = new Binary64(0.5);
111         expected = 11.0 / 768;
112         tolerance = FastMath.abs(expected * integrator.getRelativeAccuracy());
113         result = integrator.integrate(Integer.MAX_VALUE, f, min, max).getReal();
114         assertTrue(integrator.getEvaluations() < Integer.MAX_VALUE / 2);
115         assertTrue(integrator.getIterations() < MidPointIntegrator.MIDPOINT_MAX_ITERATIONS_COUNT / 2);
116         assertEquals(expected, result, tolerance);
117 
118         min = new Binary64(-1);
119         max = new Binary64(4);
120         expected = 2048 / 3.0 - 78 + 1.0 / 48;
121         tolerance = FastMath.abs(expected * integrator.getRelativeAccuracy());
122         result = integrator.integrate(Integer.MAX_VALUE, f, min, max).getReal();
123         assertTrue(integrator.getEvaluations() < Integer.MAX_VALUE / 2);
124         assertTrue(integrator.getIterations() < MidPointIntegrator.MIDPOINT_MAX_ITERATIONS_COUNT / 2);
125         assertEquals(expected, result, tolerance);
126 
127     }
128 
129     /**
130      * Test of parameters for the integrator.
131      */
132     @Test
133     void testParameters() {
134 
135         try {
136             // bad interval
137             new FieldMidPointIntegrator<>(Binary64Field.getInstance()).integrate(1000, x -> x.sin(),
138                                                                                   new Binary64(1), new Binary64(-1));
139             fail("Expecting MathIllegalArgumentException - bad interval");
140         } catch (MathIllegalArgumentException ex) {
141             // expected
142         }
143         try {
144             // bad iteration limits
145             new FieldMidPointIntegrator<>(Binary64Field.getInstance(), 5, 4);
146             fail("Expecting MathIllegalArgumentException - bad iteration limits");
147         } catch (MathIllegalArgumentException ex) {
148             // expected
149         }
150         try {
151             // bad iteration limits
152             new FieldMidPointIntegrator<>(Binary64Field.getInstance(), 10, 99);
153             fail("Expecting MathIllegalArgumentException - bad iteration limits");
154         } catch (MathIllegalArgumentException ex) {
155             // expected
156         }
157     }
158 }