1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  package org.apache.commons.math4.legacy.analysis.integration;
18  
19  import org.apache.commons.math4.legacy.analysis.QuinticFunction;
20  import org.apache.commons.math4.legacy.analysis.UnivariateFunction;
21  import org.apache.commons.math4.legacy.analysis.function.Sin;
22  import org.apache.commons.math4.legacy.exception.NumberIsTooLargeException;
23  import org.apache.commons.math4.legacy.exception.NumberIsTooSmallException;
24  import org.apache.commons.math4.core.jdkmath.JdkMath;
25  import org.junit.Assert;
26  import org.junit.Test;
27  
28  
29  
30  
31  
32  
33  
34  
35  public final class MidPointIntegratorTest {
36      private static final int NUM_ITER = 30;
37  
38      
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53      private long expectedEvaluations(int iterations) {
54          return (long) JdkMath.pow(3, iterations);
55      }
56  
57      
58  
59  
60      @Test
61      public void testLowAccuracy() {
62          UnivariateFunction f = new QuinticFunction();
63          UnivariateIntegrator integrator = new MidPointIntegrator(0.01, 1.0e-10, 2, 4);
64  
65          double min = -10;
66          double max =  -9;
67          double expected = -3697001.0 / 48.0;
68          double tolerance = JdkMath.abs(expected * integrator.getRelativeAccuracy());
69          double result = integrator.integrate(Integer.MAX_VALUE, f, min, max);
70          Assert.assertTrue(integrator.getEvaluations() < Integer.MAX_VALUE / 3);
71          Assert.assertTrue(integrator.getIterations() < NUM_ITER);
72          Assert.assertEquals(expectedEvaluations(integrator.getIterations()), integrator.getEvaluations());
73          Assert.assertEquals(expected, result, tolerance);
74      }
75  
76      
77  
78  
79      @Test
80      public void testSinFunction() {
81          UnivariateFunction f = new Sin();
82          UnivariateIntegrator integrator = new MidPointIntegrator();
83  
84          double min = 0;
85          double max = JdkMath.PI;
86          double expected = 2;
87          double tolerance = JdkMath.abs(expected * integrator.getRelativeAccuracy());
88          double result = integrator.integrate(Integer.MAX_VALUE, f, min, max);
89          Assert.assertTrue(integrator.getEvaluations() < Integer.MAX_VALUE / 3);
90          Assert.assertTrue(integrator.getIterations() < NUM_ITER);
91          Assert.assertEquals(expectedEvaluations(integrator.getIterations()), integrator.getEvaluations());
92          Assert.assertEquals(expected, result, tolerance);
93  
94          min = -JdkMath.PI/3;
95          max = 0;
96          expected = -0.5;
97          tolerance = JdkMath.abs(expected * integrator.getRelativeAccuracy());
98          result = integrator.integrate(Integer.MAX_VALUE, f, min, max);
99          Assert.assertTrue(integrator.getEvaluations() < Integer.MAX_VALUE / 3);
100         Assert.assertTrue(integrator.getIterations() < NUM_ITER);
101         Assert.assertEquals(expectedEvaluations(integrator.getIterations()), integrator.getEvaluations());
102         Assert.assertEquals(expected, result, tolerance);
103     }
104 
105     
106 
107 
108     @Test
109     public void testQuinticFunction() {
110         UnivariateFunction f = new QuinticFunction();
111         UnivariateIntegrator integrator = new MidPointIntegrator();
112 
113         double min = 0;
114         double max = 1;
115         double expected = -1.0 / 48;
116         double tolerance = JdkMath.abs(expected * integrator.getRelativeAccuracy());
117         double result = integrator.integrate(Integer.MAX_VALUE, f, min, max);
118         Assert.assertTrue(integrator.getEvaluations() < Integer.MAX_VALUE / 3);
119         Assert.assertTrue(integrator.getIterations() < NUM_ITER);
120         Assert.assertEquals(expectedEvaluations(integrator.getIterations()), integrator.getEvaluations());
121         Assert.assertEquals(expected, result, tolerance);
122 
123         min = 0;
124         max = 0.5;
125         expected = 11.0 / 768;
126         tolerance = JdkMath.abs(expected * integrator.getRelativeAccuracy());
127         result = integrator.integrate(Integer.MAX_VALUE, f, min, max);
128         Assert.assertTrue(integrator.getEvaluations() < Integer.MAX_VALUE / 3);
129         Assert.assertTrue(integrator.getIterations() < NUM_ITER);
130         Assert.assertEquals(expected, result, tolerance);
131 
132         min = -1;
133         max = 4;
134         expected = 2048 / 3.0 - 78 + 1.0 / 48;
135         tolerance = JdkMath.abs(expected * integrator.getRelativeAccuracy());
136         result = integrator.integrate(Integer.MAX_VALUE, f, min, max);
137         Assert.assertTrue(integrator.getEvaluations() < Integer.MAX_VALUE / 3);
138         Assert.assertTrue(integrator.getIterations() < NUM_ITER);
139         Assert.assertEquals(expectedEvaluations(integrator.getIterations()), integrator.getEvaluations());
140         Assert.assertEquals(expected, result, tolerance);
141     }
142 
143     
144 
145 
146     @Test
147     public void testParameters() {
148         UnivariateFunction f = new Sin();
149 
150         try {
151             
152             new MidPointIntegrator().integrate(1000, f, 1, -1);
153             Assert.fail("Expecting NumberIsTooLargeException - bad interval");
154         } catch (NumberIsTooLargeException ex) {
155             
156         }
157         try {
158             
159             new MidPointIntegrator(5, 4);
160             Assert.fail("Expecting NumberIsTooSmallException - bad iteration limits");
161         } catch (NumberIsTooSmallException ex) {
162             
163         }
164         try {
165             
166             new MidPointIntegrator(10, 99);
167             Assert.fail("Expecting NumberIsTooLargeException - bad iteration limits");
168         } catch (NumberIsTooLargeException ex) {
169             
170         }
171     }
172 }