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