1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.commons.math.util;
17
18 import junit.framework.Test;
19 import junit.framework.TestCase;
20 import junit.framework.TestSuite;
21
22 /***
23 * Test cases for the MathUtils class.
24 *
25 * @version $Revision: 1.15 $ $Date: 2004/10/14 04:01:04 $
26 */
27
28 public final class MathUtilsTest extends TestCase {
29
30 public MathUtilsTest(String name) {
31 super(name);
32 }
33
34 public void setUp() {
35 }
36
37 public static Test suite() {
38 TestSuite suite = new TestSuite(MathUtilsTest.class);
39 suite.setName("MathUtils Tests");
40 return suite;
41 }
42
43 public void testBinomialCoefficient() {
44 long[] bcoef5 = {1,5,10,10,5,1};
45 long[] bcoef6 = {1,6,15,20,15,6,1};
46 for (int i = 0; i < 6; i++) {
47 assertEquals("5 choose " + i, bcoef5[i],
48 MathUtils.binomialCoefficient(5,i));
49 }
50 for (int i = 0; i < 7; i++) {
51 assertEquals("6 choose " + i, bcoef6[i],
52 MathUtils.binomialCoefficient(6,i));
53 }
54
55 for (int n = 1; n < 10; n++) {
56 for (int k = 0; k <= n; k++) {
57 assertEquals(n + " choose " + k, binomialCoefficient(n, k),
58 MathUtils.binomialCoefficient(n, k));
59 assertEquals(n + " choose " + k,(double) binomialCoefficient(n, k),
60 MathUtils.binomialCoefficientDouble(n, k),Double.MIN_VALUE);
61 assertEquals(n + " choose " + k,
62 Math.log((double) binomialCoefficient(n, k)),
63 MathUtils.binomialCoefficientLog(n, k),10E-12);
64 }
65 }
66
67
68
69
70
71
72
73
74 }
75
76 /*** Verify that b(0,0) = 1 */
77 public void test0Choose0() {
78 assertEquals(MathUtils.binomialCoefficientDouble(0, 0), 1d, 0);
79 assertEquals(MathUtils.binomialCoefficientLog(0, 0), 0d, 0);
80 assertEquals(MathUtils.binomialCoefficient(0, 0), 1);
81 }
82
83 public void testBinomialCoefficientFail() {
84 try {
85 long x = MathUtils.binomialCoefficient(4,5);
86 fail ("expecting IllegalArgumentException");
87 } catch (IllegalArgumentException ex) {
88 ;
89 }
90
91 try {
92 double x = MathUtils.binomialCoefficientDouble(4,5);
93 fail ("expecting IllegalArgumentException");
94 } catch (IllegalArgumentException ex) {
95 ;
96 }
97
98 try {
99 double x = MathUtils.binomialCoefficientLog(4,5);
100 fail ("expecting IllegalArgumentException");
101 } catch (IllegalArgumentException ex) {
102 ;
103 }
104 try {
105 long x = MathUtils.binomialCoefficient(67,34);
106 fail ("expecting ArithmeticException");
107 } catch (ArithmeticException ex) {
108 ;
109 }
110 double x = MathUtils.binomialCoefficientDouble(1030,515);
111 assertTrue("expecting infinite binomial coefficient",
112 Double.isInfinite(x));
113 }
114
115 public void testFactorial() {
116 for (int i = 1; i < 10; i++) {
117 assertEquals(i + "! ",factorial(i),MathUtils.factorial(i));
118 assertEquals(i + "! ",(double)factorial(i),
119 MathUtils.factorialDouble(i),Double.MIN_VALUE);
120 assertEquals(i + "! ",Math.log((double)factorial(i)),
121 MathUtils.factorialLog(i),10E-12);
122 }
123 assertEquals("0", 1, MathUtils.factorial(0));
124 assertEquals("0", 1.0d, MathUtils.factorialDouble(0), 1E-14);
125 assertEquals("0", 0.0d, MathUtils.factorialLog(0), 1E-14);
126 }
127
128 public void testFactorialFail() {
129 try {
130 long x = MathUtils.factorial(-1);
131 fail ("expecting IllegalArgumentException");
132 } catch (IllegalArgumentException ex) {
133 ;
134 }
135 try {
136 double x = MathUtils.factorialDouble(-1);
137 fail ("expecting IllegalArgumentException");
138 } catch (IllegalArgumentException ex) {
139 ;
140 }
141 try {
142 double x = MathUtils.factorialLog(-1);
143 fail ("expecting IllegalArgumentException");
144 } catch (IllegalArgumentException ex) {
145 ;
146 }
147 try {
148 double x = MathUtils.factorial(21);
149 fail ("expecting ArithmeticException");
150 } catch (ArithmeticException ex) {
151 ;
152 }
153 assertTrue("expecting infinite factorial value",
154 Double.isInfinite(MathUtils.factorialDouble(171)));
155 }
156
157
158 /***
159 * Exact recursive implementation to test against
160 */
161 private long binomialCoefficient(int n, int k) {
162 if ((n == k) || (k == 0)) {
163 return 1;
164 }
165 if ((k == 1) || (k == n - 1)) {
166 return n;
167 }
168 return binomialCoefficient(n - 1, k - 1) +
169 binomialCoefficient(n - 1, k);
170 }
171
172 /***
173 * Finds the largest values of n for which binomialCoefficient and
174 * binomialCoefficientDouble will return values that fit in a long, double,
175 * resp. Remove comments around test below to get this in test-report
176 *
177 public void testLimits() {
178 findBinomialLimits();
179 }
180 */
181
182 private void findBinomialLimits() {
183 /***
184 * will kick out 66 as the limit for long
185 */
186 boolean foundLimit = false;
187 int test = 10;
188 while (!foundLimit) {
189 try {
190 double x = MathUtils.binomialCoefficient(test, test / 2);
191 } catch (ArithmeticException ex) {
192 foundLimit = true;
193 System.out.println
194 ("largest n for binomialCoefficient = " + (test - 1) );
195 }
196 test++;
197 }
198
199 /***
200 * will kick out 1029 as the limit for double
201 */
202 foundLimit = false;
203 test = 10;
204 while (!foundLimit) {
205 double x = MathUtils.binomialCoefficientDouble(test, test / 2);
206 if (Double.isInfinite(x)) {
207 foundLimit = true;
208 System.out.println
209 ("largest n for binomialCoefficientD = " + (test - 1) );
210 }
211 test++;
212 }
213 }
214
215 /***
216 * Finds the largest values of n for which factiorial and
217 * factorialDouble will return values that fit in a long, double,
218 * resp. Remove comments around test below to get this in test-report
219
220 public void testFactiorialLimits() {
221 findFactorialLimits();
222 }
223 */
224
225 private void findFactorialLimits() {
226 /***
227 * will kick out 20 as the limit for long
228 */
229 boolean foundLimit = false;
230 int test = 10;
231 while (!foundLimit) {
232 try {
233 double x = MathUtils.factorial(test);
234 } catch (ArithmeticException ex) {
235 foundLimit = true;
236 System.out.println
237 ("largest n for factorial = " + (test - 1) );
238 }
239 test++;
240 }
241
242 /***
243 * will kick out 170 as the limit for double
244 */
245 foundLimit = false;
246 test = 10;
247 while (!foundLimit) {
248 double x = MathUtils.factorialDouble(test);
249 if (Double.isInfinite(x)) {
250 foundLimit = true;
251 System.out.println
252 ("largest n for factorialDouble = " + (test - 1) );
253 }
254 test++;
255 }
256 }
257
258
259 /***
260 * Exact direct multiplication implementation to test against
261 */
262 private long factorial(int n) {
263 long result = 1;
264 for (int i = 2; i <= n; i++) {
265 result *= i;
266 }
267 return result;
268 }
269
270 public void testSignDouble() {
271 double delta = 0.0 ;
272 assertEquals( 1.0, MathUtils.indicator( 2.0 ), delta ) ;
273 assertEquals( -1.0, MathUtils.indicator( -2.0 ), delta ) ;
274 }
275
276 public void testSignFloat() {
277 float delta = 0.0F ;
278 assertEquals( 1.0F, MathUtils.indicator( 2.0F ), delta ) ;
279 assertEquals( -1.0F, MathUtils.indicator( -2.0F ), delta ) ;
280 }
281
282 public void testSignByte() {
283 assertEquals( (byte)1, MathUtils.indicator( (byte)2 ) ) ;
284 assertEquals( (byte)(-1), MathUtils.indicator( (byte)(-2) ) ) ;
285 }
286
287 public void testSignShort() {
288 assertEquals( (short)1, MathUtils.indicator( (short)2 ) ) ;
289 assertEquals( (short)(-1), MathUtils.indicator( (short)(-2) ) ) ;
290 }
291
292 public void testSignInt() {
293 assertEquals( (int)1, MathUtils.indicator( (int)(2) ) ) ;
294 assertEquals( (int)(-1), MathUtils.indicator( (int)(-2) ) ) ;
295 }
296
297 public void testSignLong() {
298 assertEquals( 1L, MathUtils.indicator( 2L ) ) ;
299 assertEquals( -1L, MathUtils.indicator( -2L ) ) ;
300 }
301
302 public void testIndicatorDouble() {
303 double delta = 0.0 ;
304 assertEquals( 1.0, MathUtils.indicator( 2.0 ), delta ) ;
305 assertEquals( 1.0, MathUtils.indicator( 0.0 ), delta ) ;
306 assertEquals( -1.0, MathUtils.indicator( -2.0 ), delta ) ;
307 }
308
309 public void testIndicatorFloat() {
310 float delta = 0.0F ;
311 assertEquals( 1.0F, MathUtils.indicator( 2.0F ), delta ) ;
312 assertEquals( 1.0F, MathUtils.indicator( 0.0F ), delta ) ;
313 assertEquals( -1.0F, MathUtils.indicator( -2.0F ), delta ) ;
314 }
315
316 public void testIndicatorByte() {
317 assertEquals( (byte)1, MathUtils.indicator( (byte)2 ) ) ;
318 assertEquals( (byte)1, MathUtils.indicator( (byte)0 ) ) ;
319 assertEquals( (byte)(-1), MathUtils.indicator( (byte)(-2) ) ) ;
320 }
321
322 public void testIndicatorShort() {
323 assertEquals( (short)1, MathUtils.indicator( (short)2 ) ) ;
324 assertEquals( (short)1, MathUtils.indicator( (short)0 ) ) ;
325 assertEquals( (short)(-1), MathUtils.indicator( (short)(-2) ) ) ;
326 }
327
328 public void testIndicatorInt() {
329 assertEquals( (int)1, MathUtils.indicator( (int)(2) ) ) ;
330 assertEquals( (int)1, MathUtils.indicator( (int)(0) ) ) ;
331 assertEquals( (int)(-1), MathUtils.indicator( (int)(-2) ) ) ;
332 }
333
334 public void testIndicatorLong() {
335 assertEquals( 1L, MathUtils.indicator( 2L ) ) ;
336 assertEquals( 1L, MathUtils.indicator( 0L ) ) ;
337 assertEquals( -1L, MathUtils.indicator( -2L ) ) ;
338 }
339
340 public void testCosh() {
341 double x = 3.0;
342 double expected = 10.06766;
343 assertEquals(expected, MathUtils.cosh(x), 1.0e-5);
344 }
345
346 public void testSinh() {
347 double x = 3.0;
348 double expected = 10.01787;
349 assertEquals(expected, MathUtils.sinh(x), 1.0e-5);
350 }
351
352 public void testCoshNaN() {
353 assertTrue(Double.isNaN(MathUtils.cosh(Double.NaN)));
354 }
355
356 public void testSinhNaN() {
357 assertTrue(Double.isNaN(MathUtils.sinh(Double.NaN)));
358 }
359
360 public void testEquals() {
361 double[] testArray = {Double.NaN, Double.POSITIVE_INFINITY,
362 Double.NEGATIVE_INFINITY, 1d, 0d};
363 for (int i = 0; i < testArray.length; i++) {
364 for (int j = 0; j < testArray.length; j ++) {
365 if (i == j) {
366 assertTrue(MathUtils.equals(testArray[i], testArray[j]));
367 assertTrue(MathUtils.equals(testArray[j], testArray[i]));
368 } else {
369 assertTrue(!MathUtils.equals(testArray[i], testArray[j]));
370 assertTrue(!MathUtils.equals(testArray[j], testArray[i]));
371 }
372 }
373 }
374 }
375
376 public void testHash() {
377 double[] testArray = {Double.NaN, Double.POSITIVE_INFINITY,
378 Double.NEGATIVE_INFINITY, 1d, 0d, 1E-14, (1 + 1E-14),
379 Double.MIN_VALUE, Double.MAX_VALUE};
380 for (int i = 0; i < testArray.length; i++) {
381 for (int j = 0; j < testArray.length; j ++) {
382 if (i == j) {
383 assertEquals(MathUtils.hash(testArray[i]), MathUtils.hash(testArray[j]));
384 assertEquals(MathUtils.hash(testArray[j]), MathUtils.hash(testArray[i]));
385 } else {
386 assertTrue(MathUtils.hash(testArray[i]) != MathUtils.hash(testArray[j]));
387 assertTrue(MathUtils.hash(testArray[j]) != MathUtils.hash(testArray[i]));
388 }
389 }
390 }
391 }
392 }