f11ba89c3797d98ffe590853929b4e2412bfef80
[debian/openrocket] / core / test / net / sf / openrocket / util / MathUtilTest.java
1 package net.sf.openrocket.util;
2
3 import static java.lang.Double.NaN;
4 import static java.lang.Math.PI;
5 import static org.junit.Assert.*;
6
7 import java.util.ArrayList;
8 import java.util.List;
9
10 import org.junit.Test;
11
12 public class MathUtilTest {
13         
14         public static final double EPS = 0.00000000001;
15         
16         @Test
17         public void miscMathTest() {
18                 
19                 assertEquals(PI * PI, MathUtil.pow2(PI), EPS);
20                 assertEquals(PI * PI * PI, MathUtil.pow3(PI), EPS);
21                 assertEquals(PI * PI * PI * PI, MathUtil.pow4(PI), EPS);
22                 
23                 assertEquals(1.0, MathUtil.clamp(0.9999, 1.0, 2.0), 0);
24                 assertEquals(1.23, MathUtil.clamp(1.23, 1.0, 2.0), 0);
25                 assertEquals(2.0, MathUtil.clamp(2 + EPS / 100, 1.0, 2.0), 0);
26                 
27                 assertEquals(1.0f, MathUtil.clamp(0.9999f, 1.0f, 2.0f), 0);
28                 assertEquals(1.23f, MathUtil.clamp(1.23f, 1.0f, 2.0f), 0);
29                 assertEquals(2.0f, MathUtil.clamp(2.0001f, 1.0f, 2.0f), 0);
30                 
31                 assertEquals(1, MathUtil.clamp(-3, 1, 5));
32                 assertEquals(3, MathUtil.clamp(3, 1, 5));
33                 assertEquals(5, MathUtil.clamp(6, 1, 5));
34                 
35                 assertEquals(-1.0, MathUtil.sign(Double.NEGATIVE_INFINITY), EPS);
36                 assertEquals(-1.0, MathUtil.sign(-100), EPS);
37                 assertEquals(-1.0, MathUtil.sign(Math.nextAfter(0.0, -1.0)), EPS);
38                 assertEquals(1.0, MathUtil.sign(Math.nextUp(0.0)), EPS);
39                 assertEquals(1.0, MathUtil.sign(100), EPS);
40                 assertEquals(1.0, MathUtil.sign(Double.POSITIVE_INFINITY), EPS);
41         }
42         
43         @Test
44         public void hypotTest() {
45                 
46                 for (int i = 0; i < 10000; i++) {
47                         double x = Math.random() * 100 - 50;
48                         double y = Math.random() * i - i / 2;
49                         double z = Math.hypot(x, y);
50                         assertEquals(z, MathUtil.hypot(x, y), EPS);
51                 }
52                 
53         }
54         
55         @Test
56         public void reduceTest() {
57                 
58                 for (int i = -1000; i < 1000; i++) {
59                         double angle = Math.random() * 2 * PI;
60                         double shift = angle + i * 2 * PI;
61                         assertEquals(angle, MathUtil.reduce360(shift), EPS);
62                 }
63                 
64                 for (int i = -1000; i < 1000; i++) {
65                         double angle = Math.random() * 2 * PI - PI;
66                         double shift = angle + i * 2 * PI;
67                         assertEquals(angle, MathUtil.reduce180(shift), EPS);
68                 }
69                 
70         }
71         
72         @Test
73         public void minmaxTest() {
74                 assertEquals(1.0, MathUtil.min(1.0, Math.nextUp(1.0)), 0);
75                 assertEquals(1.0, MathUtil.min(1.0, Double.POSITIVE_INFINITY), 0);
76                 assertEquals(1.0, MathUtil.min(NaN, 1.0), 0);
77                 assertEquals(1.0, MathUtil.min(1.0, NaN), 0);
78                 assertEquals(NaN, MathUtil.min(NaN, NaN), 0);
79                 
80                 assertEquals(Math.nextUp(1.0), MathUtil.max(1.0, Math.nextUp(1.0)), 0);
81                 assertEquals(Double.POSITIVE_INFINITY, MathUtil.max(1.0, Double.POSITIVE_INFINITY), 0);
82                 assertEquals(1.0, MathUtil.max(NaN, 1.0), 0);
83                 assertEquals(1.0, MathUtil.max(1.0, NaN), 0);
84                 assertEquals(NaN, MathUtil.max(NaN, NaN), 0);
85                 
86                 assertEquals(1.0, MathUtil.min(1.0, 2.0, 3.0), 0);
87                 assertEquals(1.0, MathUtil.min(1.0, NaN, NaN), 0);
88                 assertEquals(1.0, MathUtil.min(NaN, 1.0, NaN), 0);
89                 assertEquals(1.0, MathUtil.min(NaN, NaN, 1.0), 0);
90                 assertEquals(1.0, MathUtil.min(2.0, NaN, 1.0), 0);
91                 assertEquals(1.0, MathUtil.min(1.0, 2.0, NaN), 0);
92                 assertEquals(1.0, MathUtil.min(NaN, 2.0, 1.0), 0);
93                 
94                 assertEquals(3.0, MathUtil.max(1.0, 3.0, 2.0), 0);
95                 assertEquals(1.0, MathUtil.max(1.0, NaN, NaN), 0);
96                 assertEquals(1.0, MathUtil.max(NaN, 1.0, NaN), 0);
97                 assertEquals(1.0, MathUtil.max(NaN, NaN, 1.0), 0);
98                 assertEquals(2.0, MathUtil.max(2.0, NaN, 1.0), 0);
99                 assertEquals(2.0, MathUtil.max(1.0, 2.0, NaN), 0);
100                 assertEquals(2.0, MathUtil.max(NaN, 2.0, 1.0), 0);
101                 
102                 assertEquals(1.0, MathUtil.min(1.0, 2.0, 3.0, 4.0), 0);
103                 assertEquals(1.0, MathUtil.min(1.0, NaN, NaN, NaN), 0);
104                 assertEquals(1.0, MathUtil.min(NaN, 1.0, NaN, NaN), 0);
105                 assertEquals(1.0, MathUtil.min(NaN, NaN, 1.0, NaN), 0);
106                 assertEquals(1.0, MathUtil.min(2.0, NaN, 1.0, NaN), 0);
107                 assertEquals(1.0, MathUtil.min(2.0, NaN, NaN, 1.0), 0);
108                 assertEquals(1.0, MathUtil.min(1.0, 2.0, NaN, 3.0), 0);
109                 assertEquals(1.0, MathUtil.min(NaN, 2.0, 3.0, 1.0), 0);
110                 
111         }
112         
113         @Test
114         public void mapTest() {
115                 assertEquals(1.0, MathUtil.map(1.0, 0.0, 5.0, -1.0, 9.0), EPS);
116                 assertEquals(7.0, MathUtil.map(1.0, 5.0, 0.0, -1.0, 9.0), EPS);
117                 assertEquals(7.0, MathUtil.map(1.0, 0.0, 5.0, 9.0, -1.0), EPS);
118                 assertEquals(6.0, MathUtil.map(6.0, 0.0, 5.0, Math.nextUp(6.0), 6.0), EPS);
119                 assertEquals(6.0, MathUtil.map(6.0, 0.0, 0.0, Math.nextUp(6.0), 6.0), EPS);
120                 try {
121                         MathUtil.map(6.0, 1.0, Math.nextUp(1.0), 1.0, 2.0);
122                         fail("Should not be reached.");
123                 } catch (IllegalArgumentException normal) {
124                 }
125                 
126                 assertEquals(7.0, MathUtil.map(Math.nextUp(1.0), 0.0, 5.0, 9.0, -1.0), EPS);
127         }
128         
129         
130         @Test
131         public void mapCoordinateTest() {
132                 assertEquals(new Coordinate(0.8, 2.0, 1.6, 4.0),
133                                 MathUtil.map(1.0, 0.0, 5.0, new Coordinate(0, 1, 2, 3), new Coordinate(4, 6, 0, 8)));
134         }
135         
136         
137         @Test
138         public void equalsTest() {
139                 assertTrue(MathUtil.equals(1.0, 1.0 + MathUtil.EPSILON / 3));
140                 assertFalse(MathUtil.equals(1.0, 1.0 + MathUtil.EPSILON * 2));
141                 assertTrue(MathUtil.equals(-1.0, -1.0 + MathUtil.EPSILON / 3));
142                 assertFalse(MathUtil.equals(-1.0, -1.0 + MathUtil.EPSILON * 2));
143                 
144                 for (double zero : new double[] { 0.0, MathUtil.EPSILON / 10, -MathUtil.EPSILON / 10 }) {
145                         
146                         assertTrue(MathUtil.equals(zero, MathUtil.EPSILON / 3));
147                         assertTrue(MathUtil.equals(zero, -MathUtil.EPSILON / 3));
148                         assertFalse(MathUtil.equals(zero, MathUtil.EPSILON * 2));
149                         assertFalse(MathUtil.equals(zero, -MathUtil.EPSILON * 2));
150                         
151                         assertTrue(MathUtil.equals(MathUtil.EPSILON / 3, zero));
152                         assertTrue(MathUtil.equals(-MathUtil.EPSILON / 3, zero));
153                         assertFalse(MathUtil.equals(MathUtil.EPSILON * 2, zero));
154                         assertFalse(MathUtil.equals(-MathUtil.EPSILON * 2, zero));
155                         
156                 }
157                 
158                 for (double value : new double[] { PI * 1e20, -PI * 1e20 }) {
159                         assertTrue("value=" + value, MathUtil.equals(value, value + 1));
160                         assertTrue("value=" + value, MathUtil.equals(value, Math.nextUp(value)));
161                         assertTrue("value=" + value, MathUtil.equals(value, value * (1 + MathUtil.EPSILON)));
162                 }
163                 
164                 assertFalse(MathUtil.equals(NaN, 0.0));
165                 assertFalse(MathUtil.equals(0.0, NaN));
166                 assertFalse(MathUtil.equals(NaN, NaN));
167         }
168         
169         @Test
170         public void testAverageStddev() {
171                 List<Integer> ints = new ArrayList<Integer>();
172                 List<Double> doubles = new ArrayList<Double>();
173                 
174                 ints.add(3);
175                 ints.add(4);
176                 ints.add(7);
177                 ints.add(5);
178                 
179                 doubles.add(3.4);
180                 doubles.add(2.9);
181                 doubles.add(7.5);
182                 doubles.add(5.43);
183                 doubles.add(2.8);
184                 doubles.add(6.6);
185                 
186                 assertEquals(4.75, MathUtil.average(ints), EPS);
187                 assertEquals(1.707825127659933, MathUtil.stddev(ints), EPS);
188                 assertEquals(4.771666666666667, MathUtil.average(doubles), EPS);
189                 assertEquals(2.024454659078999, MathUtil.stddev(doubles), EPS);
190         }
191         
192         @Test
193         public void testMedian() {
194                 List<Integer> ints = new ArrayList<Integer>();
195                 List<Double> doubles = new ArrayList<Double>();
196                 
197                 ints.add(3);
198                 ints.add(4);
199                 ints.add(7);
200                 ints.add(5);
201                 
202                 doubles.add(3.4);
203                 doubles.add(2.9);
204                 doubles.add(7.5);
205                 doubles.add(5.43);
206                 doubles.add(2.8);
207                 doubles.add(6.6);
208                 
209                 assertEquals(4.5, MathUtil.median(ints), EPS);
210                 assertEquals(4.415, MathUtil.median(doubles), EPS);
211                 
212                 ints.add(9);
213                 doubles.add(10.0);
214                 
215                 assertEquals(5, MathUtil.median(ints), EPS);
216                 assertEquals(5.43, MathUtil.median(doubles), EPS);
217         }
218         
219         @Test
220         public void testInterpolate() {
221                 double v;
222                 List<Double> x;
223                 List<Double> y;
224
225                 x = new ArrayList<Double>();
226                 y = new ArrayList<Double>();
227                 y.add(1.0);
228                 
229                 v= MathUtil.interpolate(null, y, 0.0);
230                 assertEquals("Failed to test for domain null", Double.NaN, v, EPS);
231                 
232                 v = MathUtil.interpolate(x, y, 0.0);
233                 assertEquals("Failed to test for empty domain", Double.NaN, v, EPS);
234                 
235                 x = new ArrayList<Double>();
236                 x.add(1.0);
237                 y = new ArrayList<Double>();
238                 
239                 v = MathUtil.interpolate(x, null, 0.0);
240                 assertEquals("Failed to test for range null", Double.NaN, v, EPS);
241                 
242                 v = MathUtil.interpolate(x, y, 0.0);
243                 assertEquals("Failed to test for empty range", Double.NaN, v, EPS);
244                 
245                 x = new ArrayList<Double>();
246                 x.add(1.0);
247                 x.add(2.0);
248                 y = new ArrayList<Double>();
249                 y.add(15.0);
250                 y.add(17.0);
251                 
252                 v = MathUtil.interpolate(x,y,0.0);
253                 assertEquals("Failed to test t out of domain", Double.NaN, v, EPS);
254                 
255                 v = MathUtil.interpolate(x,y,5.0);
256                 assertEquals("Failed to test t out of domain", Double.NaN, v, EPS);
257                 
258                 v = MathUtil.interpolate(x,y,1.0);
259                 assertEquals("Failed to calculate left endpoint", 15.0, v, EPS);
260                 v = MathUtil.interpolate(x,y,2.0);
261                 assertEquals("Failed to calculate right endpoint", 17.0, v, EPS);
262                 v = MathUtil.interpolate(x,y,1.5);
263                 assertEquals("Failed to calculate center", 16.0, v, EPS);
264                 
265                 x = new ArrayList<Double>();
266                 x.add(0.25);
267                 x.add(0.5);
268                 x.add(1.0);
269                 x.add(2.0);
270                 y = new ArrayList<Double>();
271                 y.add(0.0);
272                 y.add(0.0);
273                 y.add(15.0);
274                 y.add(17.0);
275                 v = MathUtil.interpolate(x,y,1.5);
276                 assertEquals("Failed to calculate center with longer list", 16.0, v, EPS);
277                 
278         }
279 }