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 this
4    * work for additional information regarding copyright ownership. The ASF
5    * licenses this file to You under the Apache License, Version 2.0 (the
6    * "License"); you may not use this file except in compliance with the License.
7    * You may obtain a copy of the License at
8    * https://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
9    * or agreed to in writing, software distributed under the License is
10   * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11   * KIND, either express or implied. See the License for the specific language
12   * governing permissions and limitations under the License.
13   */
14  package org.hipparchus.util;
15  
16  import java.util.Arrays;
17  
18  import org.hipparchus.UnitTestUtils;
19  import org.hipparchus.exception.MathIllegalArgumentException;
20  import org.hipparchus.exception.MathRuntimeException;
21  import org.hipparchus.exception.NullArgumentException;
22  import org.hipparchus.random.Well1024a;
23  import org.junit.Assert;
24  import org.junit.Test;
25  
26  /**
27   * Test cases for the {@link MathArrays} class.
28   */
29  public class MathArraysTest {
30  
31      private double[] testArray = {0, 1, 2, 3, 4, 5};
32      private double[] testWeightsArray = {0.3, 0.2, 1.3, 1.1, 1.0, 1.8};
33      private double[] testNegativeWeightsArray = {-0.3, 0.2, -1.3, 1.1, 1.0, 1.8};
34      private double[] nullArray = null;
35      private double[] singletonArray = {0};
36  
37      @Test
38      public void testScale() {
39          final double[] test = new double[] { -2.5, -1, 0, 1, 2.5 };
40          final double[] correctTest = test.clone();
41          final double[] correctScaled = new double[]{5.25, 2.1, 0, -2.1, -5.25};
42  
43          final double[] scaled = MathArrays.scale(-2.1, test);
44  
45          // Make sure test has not changed
46          for (int i = 0; i < test.length; i++) {
47              Assert.assertEquals(correctTest[i], test[i], 0);
48          }
49  
50          // Test scaled values
51          for (int i = 0; i < scaled.length; i++) {
52              Assert.assertEquals(correctScaled[i], scaled[i], 0);
53          }
54      }
55  
56      @Test
57      public void testScaleInPlace() {
58          final double[] test = new double[] { -2.5, -1, 0, 1, 2.5 };
59          final double[] correctScaled = new double[]{5.25, 2.1, 0, -2.1, -5.25};
60          MathArrays.scaleInPlace(-2.1, test);
61  
62          // Make sure test has changed
63          for (int i = 0; i < test.length; i++) {
64              Assert.assertEquals(correctScaled[i], test[i], 0);
65          }
66      }
67  
68      @Test(expected=MathIllegalArgumentException.class)
69      public void testEbeAddPrecondition() {
70          MathArrays.ebeAdd(new double[3], new double[4]);
71      }
72      @Test(expected=MathIllegalArgumentException.class)
73      public void testEbeSubtractPrecondition() {
74          MathArrays.ebeSubtract(new double[3], new double[4]);
75      }
76      @Test(expected=MathIllegalArgumentException.class)
77      public void testEbeMultiplyPrecondition() {
78          MathArrays.ebeMultiply(new double[3], new double[4]);
79      }
80      @Test(expected=MathIllegalArgumentException.class)
81      public void testEbeDividePrecondition() {
82          MathArrays.ebeDivide(new double[3], new double[4]);
83      }
84  
85      @Test
86      public void testEbeAdd() {
87          final double[] a = { 0, 1, 2 };
88          final double[] b = { 3, 5, 7 };
89          final double[] r = MathArrays.ebeAdd(a, b);
90  
91          for (int i = 0; i < a.length; i++) {
92              Assert.assertEquals(a[i] + b[i], r[i], 0);
93          }
94      }
95      @Test
96      public void testEbeSubtract() {
97          final double[] a = { 0, 1, 2 };
98          final double[] b = { 3, 5, 7 };
99          final double[] r = MathArrays.ebeSubtract(a, b);
100 
101         for (int i = 0; i < a.length; i++) {
102             Assert.assertEquals(a[i] - b[i], r[i], 0);
103         }
104     }
105     @Test
106     public void testEbeMultiply() {
107         final double[] a = { 0, 1, 2 };
108         final double[] b = { 3, 5, 7 };
109         final double[] r = MathArrays.ebeMultiply(a, b);
110 
111         for (int i = 0; i < a.length; i++) {
112             Assert.assertEquals(a[i] * b[i], r[i], 0);
113         }
114     }
115     @Test
116     public void testEbeDivide() {
117         final double[] a = { 0, 1, 2 };
118         final double[] b = { 3, 5, 7 };
119         final double[] r = MathArrays.ebeDivide(a, b);
120 
121         for (int i = 0; i < a.length; i++) {
122             Assert.assertEquals(a[i] / b[i], r[i], 0);
123         }
124     }
125 
126     @Test
127     public void testL1DistanceDouble() {
128         double[] p1 = { 2.5,  0.0 };
129         double[] p2 = { -0.5, 4.0 };
130         Assert.assertTrue(Precision.equals(7.0, MathArrays.distance1(p1, p2), 1));
131     }
132 
133     @Test
134     public void testL1DistanceInt() {
135         int[] p1 = { 3, 0 };
136         int[] p2 = { 0, 4 };
137         Assert.assertEquals(7, MathArrays.distance1(p1, p2));
138     }
139 
140     @Test
141     public void testL2DistanceDouble() {
142         double[] p1 = { 2.5,  0.0 };
143         double[] p2 = { -0.5, 4.0 };
144         Assert.assertTrue(Precision.equals(5.0, MathArrays.distance(p1, p2), 1));
145     }
146 
147     @Test
148     public void testL2DistanceInt() {
149         int[] p1 = { 3, 0 };
150         int[] p2 = { 0, 4 };
151         Assert.assertTrue(Precision.equals(5, MathArrays.distance(p1, p2), 1));
152     }
153 
154     @Test
155     public void testLInfDistanceDouble() {
156         double[] p1 = { 2.5,  0.0 };
157         double[] p2 = { -0.5, 4.0 };
158         Assert.assertTrue(Precision.equals(4.0, MathArrays.distanceInf(p1, p2), 1));
159     }
160 
161     @Test
162     public void testLInfDistanceInt() {
163         int[] p1 = { 3, 0 };
164         int[] p2 = { 0, 4 };
165         Assert.assertEquals(4, MathArrays.distanceInf(p1, p2));
166     }
167 
168     @Test
169     public void testCosAngle2D() {
170         double expected;
171 
172         final double[] v1 = { 1, 0 };
173         expected = 1;
174         Assert.assertEquals(expected, MathArrays.cosAngle(v1, v1), 0d);
175 
176         final double[] v2 = { 0, 1 };
177         expected = 0;
178         Assert.assertEquals(expected, MathArrays.cosAngle(v1, v2), 0d);
179 
180         final double[] v3 = { 7, 7 };
181         expected = Math.sqrt(2) / 2;
182         Assert.assertEquals(expected, MathArrays.cosAngle(v1, v3), 1e-15);
183         Assert.assertEquals(expected, MathArrays.cosAngle(v3, v2), 1e-15);
184 
185         final double[] v4 = { -5, 0 };
186         expected = -1;
187         Assert.assertEquals(expected, MathArrays.cosAngle(v1, v4), 0);
188 
189         final double[] v5 = { -100, 100 };
190         expected = 0;
191         Assert.assertEquals(expected, MathArrays.cosAngle(v3, v5), 0);
192     }
193 
194     @Test
195     public void testCosAngle3D() {
196         double expected;
197 
198         final double[] v1 = { 1, 1, 0 };
199         expected = 1;
200         Assert.assertEquals(expected, MathArrays.cosAngle(v1, v1), 1e-15);
201 
202         final double[] v2 = { 1, 1, 1 };
203         expected = Math.sqrt(2) / Math.sqrt(3);
204         Assert.assertEquals(expected, MathArrays.cosAngle(v1, v2), 1e-15);
205     }
206 
207     @Test
208     public void testCosAngleExtreme() {
209         double expected;
210 
211         final double tiny = 1e-200;
212         final double[] v1 = { tiny, tiny };
213         final double big = 1e200;
214         final double[] v2 = { -big, -big };
215         expected = -1;
216         Assert.assertEquals(expected, MathArrays.cosAngle(v1, v2), 1e-15);
217 
218         final double[] v3 = { big, -big };
219         expected = 0;
220         Assert.assertEquals(expected, MathArrays.cosAngle(v1, v3), 1e-15);
221     }
222 
223     @Test
224     public void testCheckOrder() {
225         MathArrays.checkOrder(new double[] {-15, -5.5, -1, 2, 15},
226                              MathArrays.OrderDirection.INCREASING, true);
227         MathArrays.checkOrder(new double[] {-15, -5.5, -1, 2, 2},
228                              MathArrays.OrderDirection.INCREASING, false);
229         MathArrays.checkOrder(new double[] {3, -5.5, -11, -27.5},
230                              MathArrays.OrderDirection.DECREASING, true);
231         MathArrays.checkOrder(new double[] {3, 0, 0, -5.5, -11, -27.5},
232                              MathArrays.OrderDirection.DECREASING, false);
233 
234         try {
235             MathArrays.checkOrder(new double[] {-15, -5.5, -1, -1, 2, 15},
236                                  MathArrays.OrderDirection.INCREASING, true);
237             Assert.fail("an exception should have been thrown");
238         } catch (MathIllegalArgumentException e) {
239             // Expected
240         }
241         try {
242             MathArrays.checkOrder(new double[] {-15, -5.5, -1, -2, 2},
243                                  MathArrays.OrderDirection.INCREASING, false);
244             Assert.fail("an exception should have been thrown");
245         } catch (MathIllegalArgumentException e) {
246             // Expected
247         }
248         try {
249             MathArrays.checkOrder(new double[] {3, 3, -5.5, -11, -27.5},
250                                  MathArrays.OrderDirection.DECREASING, true);
251             Assert.fail("an exception should have been thrown");
252         } catch (MathIllegalArgumentException e) {
253             // Expected
254         }
255         try {
256             MathArrays.checkOrder(new double[] {3, -1, 0, -5.5, -11, -27.5},
257                                  MathArrays.OrderDirection.DECREASING, false);
258             Assert.fail("an exception should have been thrown");
259         } catch (MathIllegalArgumentException e) {
260             // Expected
261         }
262         try {
263             MathArrays.checkOrder(new double[] {3, 0, -5.5, -11, -10},
264                                  MathArrays.OrderDirection.DECREASING, false);
265             Assert.fail("an exception should have been thrown");
266         } catch (MathIllegalArgumentException e) {
267             // Expected
268         }
269     }
270 
271     @Test
272     public void testIsMonotonic() {
273         Assert.assertFalse(MathArrays.isMonotonic(new double[] { -15, -5.5, -1, -1, 2, 15 },
274                                                   MathArrays.OrderDirection.INCREASING, true));
275         Assert.assertTrue(MathArrays.isMonotonic(new double[] { -15, -5.5, -1, 0, 2, 15 },
276                                                  MathArrays.OrderDirection.INCREASING, true));
277         Assert.assertFalse(MathArrays.isMonotonic(new double[] { -15, -5.5, -1, -2, 2 },
278                                                   MathArrays.OrderDirection.INCREASING, false));
279         Assert.assertTrue(MathArrays.isMonotonic(new double[] { -15, -5.5, -1, -1, 2 },
280                                                  MathArrays.OrderDirection.INCREASING, false));
281         Assert.assertFalse(MathArrays.isMonotonic(new double[] { 3, 3, -5.5, -11, -27.5 },
282                                                   MathArrays.OrderDirection.DECREASING, true));
283         Assert.assertTrue(MathArrays.isMonotonic(new double[] { 3, 2, -5.5, -11, -27.5 },
284                                                  MathArrays.OrderDirection.DECREASING, true));
285         Assert.assertFalse(MathArrays.isMonotonic(new double[] { 3, -1, 0, -5.5, -11, -27.5 },
286                                                   MathArrays.OrderDirection.DECREASING, false));
287         Assert.assertTrue(MathArrays.isMonotonic(new double[] { 3, 0, 0, -5.5, -11, -27.5 },
288                                                  MathArrays.OrderDirection.DECREASING, false));
289     }
290 
291     @Test
292     public void testIsMonotonicComparable() {
293         Assert.assertFalse(MathArrays.isMonotonic(new Double[] { Double.valueOf(-15),
294                                                                  Double.valueOf(-5.5),
295                                                                  Double.valueOf(-1),
296                                                                  Double.valueOf(-1),
297                                                                  Double.valueOf(2),
298                                                                  Double.valueOf(15) },
299                 MathArrays.OrderDirection.INCREASING, true));
300         Assert.assertTrue(MathArrays.isMonotonic(new Double[] { Double.valueOf(-15),
301                                                                 Double.valueOf(-5.5),
302                                                                 Double.valueOf(-1),
303                                                                 Double.valueOf(0),
304                                                                 Double.valueOf(2),
305                                                                 Double.valueOf(15) },
306                 MathArrays.OrderDirection.INCREASING, true));
307         Assert.assertFalse(MathArrays.isMonotonic(new Double[] { Double.valueOf(-15),
308                                                                  Double.valueOf(-5.5),
309                                                                  Double.valueOf(-1),
310                                                                  Double.valueOf(-2),
311                                                                  Double.valueOf(2) },
312                 MathArrays.OrderDirection.INCREASING, false));
313         Assert.assertTrue(MathArrays.isMonotonic(new Double[] { Double.valueOf(-15),
314                                                                 Double.valueOf(-5.5),
315                                                                 Double.valueOf(-1),
316                                                                 Double.valueOf(-1),
317                                                                 Double.valueOf(2) },
318                 MathArrays.OrderDirection.INCREASING, false));
319         Assert.assertFalse(MathArrays.isMonotonic(new Double[] { Double.valueOf(3),
320                                                                  Double.valueOf(3),
321                                                                  Double.valueOf(-5.5),
322                                                                  Double.valueOf(-11),
323                                                                  Double.valueOf(-27.5) },
324                 MathArrays.OrderDirection.DECREASING, true));
325         Assert.assertTrue(MathArrays.isMonotonic(new Double[] { Double.valueOf(3),
326                                                                 Double.valueOf(2),
327                                                                 Double.valueOf(-5.5),
328                                                                 Double.valueOf(-11),
329                                                                 Double.valueOf(-27.5) },
330                 MathArrays.OrderDirection.DECREASING, true));
331         Assert.assertFalse(MathArrays.isMonotonic(new Double[] { Double.valueOf(3),
332                                                                  Double.valueOf(-1),
333                                                                  Double.valueOf(0),
334                                                                  Double.valueOf(-5.5),
335                                                                  Double.valueOf(-11),
336                                                                  Double.valueOf(-27.5) },
337                 MathArrays.OrderDirection.DECREASING, false));
338         Assert.assertTrue(MathArrays.isMonotonic(new Double[] { Double.valueOf(3),
339                                                                 Double.valueOf(0),
340                                                                 Double.valueOf(0),
341                                                                 Double.valueOf(-5.5),
342                                                                 Double.valueOf(-11),
343                                                                 Double.valueOf(-27.5) },
344                 MathArrays.OrderDirection.DECREASING, false));
345     }
346 
347     @Test
348     public void testCheckRectangular() {
349         final long[][] rect = new long[][] {{0, 1}, {2, 3}};
350         final long[][] ragged = new long[][] {{0, 1}, {2}};
351         final long[][] nullArray = null;
352         final long[][] empty = new long[][] {};
353         MathArrays.checkRectangular(rect);
354         MathArrays.checkRectangular(empty);
355         try {
356             MathArrays.checkRectangular(ragged);
357             Assert.fail("Expecting MathIllegalArgumentException");
358         } catch (MathIllegalArgumentException ex) {
359             // Expected
360         }
361         try {
362             MathArrays.checkRectangular(nullArray);
363             Assert.fail("Expecting NullArgumentException");
364         } catch (NullArgumentException ex) {
365             // Expected
366         }
367     }
368 
369     @Test
370     public void testCheckPositive() {
371         final double[] positive = new double[] {1, 2, 3};
372         final double[] nonNegative = new double[] {0, 1, 2};
373         final double[] nullArray = null;
374         final double[] empty = new double[] {};
375         MathArrays.checkPositive(positive);
376         MathArrays.checkPositive(empty);
377         try {
378             MathArrays.checkPositive(nullArray);
379             Assert.fail("Expecting NullPointerException");
380         } catch (NullPointerException ex) {
381             // Expected
382         }
383         try {
384             MathArrays.checkPositive(nonNegative);
385             Assert.fail("Expecting MathIllegalArgumentException");
386         } catch (MathIllegalArgumentException ex) {
387             // Expected
388         }
389     }
390 
391     @Test
392     public void testCheckNonNegative() {
393         final long[] nonNegative = new long[] {0, 1};
394         final long[] hasNegative = new long[] {-1};
395         final long[] nullArray = null;
396         final long[] empty = new long[] {};
397         MathArrays.checkNonNegative(nonNegative);
398         MathArrays.checkNonNegative(empty);
399         try {
400             MathArrays.checkNonNegative(nullArray);
401             Assert.fail("Expecting NullPointerException");
402         } catch (NullPointerException ex) {
403             // Expected
404         }
405         try {
406             MathArrays.checkNonNegative(hasNegative);
407             Assert.fail("Expecting MathIllegalArgumentException");
408         } catch (MathIllegalArgumentException ex) {
409             // Expected
410         }
411     }
412 
413     @Test
414     public void testCheckNonNegative2D() {
415         final long[][] nonNegative = new long[][] {{0, 1}, {1, 0}};
416         final long[][] hasNegative = new long[][] {{-1}, {0}};
417         final long[][] nullArray = null;
418         final long[][] empty = new long[][] {};
419         MathArrays.checkNonNegative(nonNegative);
420         MathArrays.checkNonNegative(empty);
421         try {
422             MathArrays.checkNonNegative(nullArray);
423             Assert.fail("Expecting NullPointerException");
424         } catch (NullPointerException ex) {
425             // Expected
426         }
427         try {
428             MathArrays.checkNonNegative(hasNegative);
429             Assert.fail("Expecting MathIllegalArgumentException");
430         } catch (MathIllegalArgumentException ex) {
431             // Expected
432         }
433     }
434 
435     @Test
436     public void testCheckNotNaN() {
437         final double[] withoutNaN = { Double.NEGATIVE_INFINITY,
438                                       -Double.MAX_VALUE,
439                                       -1, 0,
440                                       Double.MIN_VALUE,
441                                       FastMath.ulp(1d),
442                                       1, 3, 113, 4769,
443                                       Double.MAX_VALUE,
444                                       Double.POSITIVE_INFINITY };
445 
446         final double[] withNaN = { Double.NEGATIVE_INFINITY,
447                                    -Double.MAX_VALUE,
448                                    -1, 0,
449                                    Double.MIN_VALUE,
450                                    FastMath.ulp(1d),
451                                    1, 3, 113, 4769,
452                                    Double.MAX_VALUE,
453                                    Double.POSITIVE_INFINITY,
454                                    Double.NaN };
455 
456 
457         final double[] nullArray = null;
458         final double[] empty = new double[] {};
459         MathArrays.checkNotNaN(withoutNaN);
460         MathArrays.checkNotNaN(empty);
461         try {
462             MathArrays.checkNotNaN(nullArray);
463             Assert.fail("Expecting NullPointerException");
464         } catch (NullPointerException ex) {
465             // Expected
466         }
467         try {
468             MathArrays.checkNotNaN(withNaN);
469             Assert.fail("Expecting MathIllegalArgumentException");
470         } catch (MathIllegalArgumentException ex) {
471             // Expected
472         }
473     }
474 
475     @Test(expected=MathIllegalArgumentException.class)
476     public void testCheckEqualLength1() {
477         MathArrays.checkEqualLength(new double[] {1, 2, 3},
478                                     new double[] {1, 2, 3, 4});
479     }
480 
481     @Test
482     public void testCheckEqualLength2() {
483         final double[] a = new double[] {-1, -12, -23, -34};
484         final double[] b = new double[] {56, 67, 78, 89};
485         Assert.assertTrue(MathArrays.checkEqualLength(a, b, false));
486     }
487 
488     @Test
489     public void testSortInPlace() {
490         final double[] x1 = {2,   5,  -3, 1,  4};
491         final double[] x2 = {4,  25,   9, 1, 16};
492         final double[] x3 = {8, 125, -27, 1, 64};
493 
494         MathArrays.sortInPlace(x1, x2, x3);
495 
496         Assert.assertEquals(-3,  x1[0], FastMath.ulp(1d));
497         Assert.assertEquals(9,   x2[0], FastMath.ulp(1d));
498         Assert.assertEquals(-27, x3[0], FastMath.ulp(1d));
499 
500         Assert.assertEquals(1, x1[1], FastMath.ulp(1d));
501         Assert.assertEquals(1, x2[1], FastMath.ulp(1d));
502         Assert.assertEquals(1, x3[1], FastMath.ulp(1d));
503 
504         Assert.assertEquals(2, x1[2], FastMath.ulp(1d));
505         Assert.assertEquals(4, x2[2], FastMath.ulp(1d));
506         Assert.assertEquals(8, x3[2], FastMath.ulp(1d));
507 
508         Assert.assertEquals(4,  x1[3], FastMath.ulp(1d));
509         Assert.assertEquals(16, x2[3], FastMath.ulp(1d));
510         Assert.assertEquals(64, x3[3], FastMath.ulp(1d));
511 
512         Assert.assertEquals(5,   x1[4], FastMath.ulp(1d));
513         Assert.assertEquals(25,  x2[4], FastMath.ulp(1d));
514         Assert.assertEquals(125, x3[4], FastMath.ulp(1d));
515     }
516 
517     @Test
518     public void testSortInPlaceDecresasingOrder() {
519         final double[] x1 = {2,   5,  -3, 1,  4};
520         final double[] x2 = {4,  25,   9, 1, 16};
521         final double[] x3 = {8, 125, -27, 1, 64};
522 
523         MathArrays.sortInPlace(x1,
524                                MathArrays.OrderDirection.DECREASING,
525                                x2, x3);
526 
527         Assert.assertEquals(-3,  x1[4], FastMath.ulp(1d));
528         Assert.assertEquals(9,   x2[4], FastMath.ulp(1d));
529         Assert.assertEquals(-27, x3[4], FastMath.ulp(1d));
530 
531         Assert.assertEquals(1, x1[3], FastMath.ulp(1d));
532         Assert.assertEquals(1, x2[3], FastMath.ulp(1d));
533         Assert.assertEquals(1, x3[3], FastMath.ulp(1d));
534 
535         Assert.assertEquals(2, x1[2], FastMath.ulp(1d));
536         Assert.assertEquals(4, x2[2], FastMath.ulp(1d));
537         Assert.assertEquals(8, x3[2], FastMath.ulp(1d));
538 
539         Assert.assertEquals(4,  x1[1], FastMath.ulp(1d));
540         Assert.assertEquals(16, x2[1], FastMath.ulp(1d));
541         Assert.assertEquals(64, x3[1], FastMath.ulp(1d));
542 
543         Assert.assertEquals(5,   x1[0], FastMath.ulp(1d));
544         Assert.assertEquals(25,  x2[0], FastMath.ulp(1d));
545         Assert.assertEquals(125, x3[0], FastMath.ulp(1d));
546     }
547 
548     @Test
549     /** Example in javadoc */
550     public void testSortInPlaceExample() {
551         final double[] x = {3, 1, 2};
552         final double[] y = {1, 2, 3};
553         final double[] z = {0, 5, 7};
554         MathArrays.sortInPlace(x, y, z);
555         final double[] sx = {1, 2, 3};
556         final double[] sy = {2, 3, 1};
557         final double[] sz = {5, 7, 0};
558         Assert.assertTrue(Arrays.equals(sx, x));
559         Assert.assertTrue(Arrays.equals(sy, y));
560         Assert.assertTrue(Arrays.equals(sz, z));
561     }
562 
563     @Test
564     public void testSortInPlaceFailures() {
565         final double[] nullArray = null;
566         final double[] one = {1};
567         final double[] two = {1, 2};
568         final double[] onep = {2};
569         try {
570             MathArrays.sortInPlace(one, two);
571             Assert.fail("Expecting MathIllegalArgumentException");
572         } catch (MathIllegalArgumentException ex) {
573             // expected
574         }
575         try {
576             MathArrays.sortInPlace(one, nullArray);
577             Assert.fail("Expecting NullArgumentException");
578         } catch (NullArgumentException ex) {
579             // expected
580         }
581         try {
582             MathArrays.sortInPlace(one, onep, nullArray);
583             Assert.fail("Expecting NullArgumentException");
584         } catch (NullArgumentException ex) {
585             // expected
586         }
587     }
588 
589     // MATH-1005
590     @Test
591     public void testLinearCombinationWithSingleElementArray() {
592         final double[] a = { 1.23456789 };
593         final double[] b = { 98765432.1 };
594 
595         Assert.assertEquals(a[0] * b[0], MathArrays.linearCombination(a, b), 0d);
596     }
597 
598     @Test
599     public void testLinearCombination1() {
600         final double[] a = new double[] {
601             -1321008684645961.0 / 268435456.0,
602             -5774608829631843.0 / 268435456.0,
603             -7645843051051357.0 / 8589934592.0
604         };
605         final double[] b = new double[] {
606             -5712344449280879.0 / 2097152.0,
607             -4550117129121957.0 / 2097152.0,
608             8846951984510141.0 / 131072.0
609         };
610 
611         final double abSumInline = MathArrays.linearCombination(a[0], b[0],
612                                                                 a[1], b[1],
613                                                                 a[2], b[2]);
614         final double abSumArray = MathArrays.linearCombination(a, b);
615 
616         Assert.assertEquals(abSumInline, abSumArray, 0);
617         Assert.assertEquals(-1.8551294182586248737720779899, abSumInline, 1.0e-15);
618 
619         final double naive = a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
620         Assert.assertTrue(FastMath.abs(naive - abSumInline) > 1.5);
621 
622     }
623 
624     @Test
625     public void testLinearCombinationSignedZero() {
626         Assert.assertTrue(FastMath.copySign(1, MathArrays.linearCombination(+0.0, 1.0, +0.0, 1.0)) > 0);
627         Assert.assertTrue(FastMath.copySign(1, MathArrays.linearCombination(-0.0, 1.0, -0.0, 1.0)) < 0);
628         Assert.assertTrue(FastMath.copySign(1, MathArrays.linearCombination(+0.0, 1.0, +0.0, 1.0, +0.0, 1.0)) > 0);
629         Assert.assertTrue(FastMath.copySign(1, MathArrays.linearCombination(-0.0, 1.0, -0.0, 1.0, -0.0, 1.0)) < 0);
630         Assert.assertTrue(FastMath.copySign(1, MathArrays.linearCombination(+0.0, 1.0, +0.0, 1.0, +0.0, 1.0)) > 0);
631         Assert.assertTrue(FastMath.copySign(1, MathArrays.linearCombination(-0.0, 1.0, -0.0, 1.0, -0.0, 1.0)) < 0);
632         Assert.assertTrue(FastMath.copySign(1, MathArrays.linearCombination(+0.0, 1.0, +0.0, 1.0, +0.0, 1.0, +0.0, 1.0)) > 0);
633         Assert.assertTrue(FastMath.copySign(1, MathArrays.linearCombination(-0.0, 1.0, -0.0, 1.0, -0.0, 1.0, -0.0, 1.0)) < 0);
634         Assert.assertTrue(FastMath.copySign(1, MathArrays.linearCombination(new double[] {+0.0, +0.0}, new double[] {1.0, 1.0})) > 0);
635         Assert.assertTrue(FastMath.copySign(1, MathArrays.linearCombination(new double[] {-0.0, -0.0}, new double[] {1.0, 1.0})) < 0);
636     }
637 
638     @Test
639     public void testLinearCombination2() {
640         // we compare accurate versus naive dot product implementations
641         // on regular vectors (i.e. not extreme cases like in the previous test)
642         Well1024a random = new Well1024a(553267312521321234l);
643 
644         for (int i = 0; i < 10000; ++i) {
645             final double ux = 1e17 * random.nextDouble();
646             final double uy = 1e17 * random.nextDouble();
647             final double uz = 1e17 * random.nextDouble();
648             final double vx = 1e17 * random.nextDouble();
649             final double vy = 1e17 * random.nextDouble();
650             final double vz = 1e17 * random.nextDouble();
651             final double sInline = MathArrays.linearCombination(ux, vx,
652                                                                 uy, vy,
653                                                                 uz, vz);
654             final double sArray = MathArrays.linearCombination(new double[] {ux, uy, uz},
655                                                                new double[] {vx, vy, vz});
656             Assert.assertEquals(sInline, sArray, 0);
657         }
658     }
659 
660     @Test
661     public void testLinearCombinationHuge() {
662         int scale = 971;
663         final double[] a = new double[] {
664                                          -1321008684645961.0 / 268435456.0,
665                                          -5774608829631843.0 / 268435456.0,
666                                          -7645843051051357.0 / 8589934592.0
667                                      };
668         final double[] b = new double[] {
669                                          -5712344449280879.0 / 2097152.0,
670                                          -4550117129121957.0 / 2097152.0,
671                                           8846951984510141.0 / 131072.0
672                                      };
673 
674         double[] scaledA = new double[a.length];
675         double[] scaledB = new double[b.length];
676         for (int i = 0; i < scaledA.length; ++i) {
677             scaledA[i] = FastMath.scalb(a[i], -scale);
678             scaledB[i] = FastMath.scalb(b[i], +scale);
679         }
680         final double abSumInline = MathArrays.linearCombination(scaledA[0], scaledB[0],
681                                                                 scaledA[1], scaledB[1],
682                                                                 scaledA[2], scaledB[2]);
683         final double abSumArray = MathArrays.linearCombination(scaledA, scaledB);
684 
685         Assert.assertEquals(abSumInline, abSumArray, 0);
686         Assert.assertEquals(-1.8551294182586248737720779899, abSumInline, 1.0e-15);
687 
688         final double naive = scaledA[0] * scaledB[0] + scaledA[1] * scaledB[1] + scaledA[2] * scaledB[2];
689         Assert.assertTrue(FastMath.abs(naive - abSumInline) > 1.5);
690 
691     }
692 
693     @Test
694     public void testLinearCombinationInfinite() {
695         final double[][] a = new double[][] {
696             { 1, 2, 3, 4},
697             { 1, Double.POSITIVE_INFINITY, 3, 4},
698             { 1, 2, Double.POSITIVE_INFINITY, 4},
699             { 1, Double.POSITIVE_INFINITY, 3, Double.NEGATIVE_INFINITY},
700             { 1, 2, 3, 4},
701             { 1, 2, 3, 4},
702             { 1, 2, 3, 4},
703             { 1, 2, 3, 4}
704         };
705         final double[][] b = new double[][] {
706             { 1, -2, 3, 4},
707             { 1, -2, 3, 4},
708             { 1, -2, 3, 4},
709             { 1, -2, 3, 4},
710             { 1, Double.POSITIVE_INFINITY, 3, 4},
711             { 1, -2, Double.POSITIVE_INFINITY, 4},
712             { 1, Double.POSITIVE_INFINITY, 3, Double.NEGATIVE_INFINITY},
713             { Double.NaN, -2, 3, 4}
714         };
715 
716         Assert.assertEquals(-3,
717                             MathArrays.linearCombination(a[0][0], b[0][0],
718                                                          a[0][1], b[0][1]),
719                             1.0e-10);
720         Assert.assertEquals(6,
721                             MathArrays.linearCombination(a[0][0], b[0][0],
722                                                          a[0][1], b[0][1],
723                                                          a[0][2], b[0][2]),
724                             1.0e-10);
725         Assert.assertEquals(22,
726                             MathArrays.linearCombination(a[0][0], b[0][0],
727                                                          a[0][1], b[0][1],
728                                                          a[0][2], b[0][2],
729                                                          a[0][3], b[0][3]),
730                             1.0e-10);
731         Assert.assertEquals(22, MathArrays.linearCombination(a[0], b[0]), 1.0e-10);
732 
733         Assert.assertEquals(Double.NEGATIVE_INFINITY,
734                             MathArrays.linearCombination(a[1][0], b[1][0],
735                                                          a[1][1], b[1][1]),
736                             1.0e-10);
737         Assert.assertEquals(Double.NEGATIVE_INFINITY,
738                             MathArrays.linearCombination(a[1][0], b[1][0],
739                                                          a[1][1], b[1][1],
740                                                          a[1][2], b[1][2]),
741                             1.0e-10);
742         Assert.assertEquals(Double.NEGATIVE_INFINITY,
743                             MathArrays.linearCombination(a[1][0], b[1][0],
744                                                          a[1][1], b[1][1],
745                                                          a[1][2], b[1][2],
746                                                          a[1][3], b[1][3]),
747                             1.0e-10);
748         Assert.assertEquals(Double.NEGATIVE_INFINITY, MathArrays.linearCombination(a[1], b[1]), 1.0e-10);
749 
750         Assert.assertEquals(-3,
751                             MathArrays.linearCombination(a[2][0], b[2][0],
752                                                          a[2][1], b[2][1]),
753                             1.0e-10);
754         Assert.assertEquals(Double.POSITIVE_INFINITY,
755                             MathArrays.linearCombination(a[2][0], b[2][0],
756                                                          a[2][1], b[2][1],
757                                                          a[2][2], b[2][2]),
758                             1.0e-10);
759         Assert.assertEquals(Double.POSITIVE_INFINITY,
760                             MathArrays.linearCombination(a[2][0], b[2][0],
761                                                          a[2][1], b[2][1],
762                                                          a[2][2], b[2][2],
763                                                          a[2][3], b[2][3]),
764                             1.0e-10);
765         Assert.assertEquals(Double.POSITIVE_INFINITY, MathArrays.linearCombination(a[2], b[2]), 1.0e-10);
766 
767         Assert.assertEquals(Double.NEGATIVE_INFINITY,
768                             MathArrays.linearCombination(a[3][0], b[3][0],
769                                                          a[3][1], b[3][1]),
770                             1.0e-10);
771         Assert.assertEquals(Double.NEGATIVE_INFINITY,
772                             MathArrays.linearCombination(a[3][0], b[3][0],
773                                                          a[3][1], b[3][1],
774                                                          a[3][2], b[3][2]),
775                             1.0e-10);
776         Assert.assertEquals(Double.NEGATIVE_INFINITY,
777                             MathArrays.linearCombination(a[3][0], b[3][0],
778                                                          a[3][1], b[3][1],
779                                                          a[3][2], b[3][2],
780                                                          a[3][3], b[3][3]),
781                             1.0e-10);
782         Assert.assertEquals(Double.NEGATIVE_INFINITY, MathArrays.linearCombination(a[3], b[3]), 1.0e-10);
783 
784         Assert.assertEquals(Double.POSITIVE_INFINITY,
785                             MathArrays.linearCombination(a[4][0], b[4][0],
786                                                          a[4][1], b[4][1]),
787                             1.0e-10);
788         Assert.assertEquals(Double.POSITIVE_INFINITY,
789                             MathArrays.linearCombination(a[4][0], b[4][0],
790                                                          a[4][1], b[4][1],
791                                                          a[4][2], b[4][2]),
792                             1.0e-10);
793         Assert.assertEquals(Double.POSITIVE_INFINITY,
794                             MathArrays.linearCombination(a[4][0], b[4][0],
795                                                          a[4][1], b[4][1],
796                                                          a[4][2], b[4][2],
797                                                          a[4][3], b[4][3]),
798                             1.0e-10);
799         Assert.assertEquals(Double.POSITIVE_INFINITY, MathArrays.linearCombination(a[4], b[4]), 1.0e-10);
800 
801         Assert.assertEquals(-3,
802                             MathArrays.linearCombination(a[5][0], b[5][0],
803                                                          a[5][1], b[5][1]),
804                             1.0e-10);
805         Assert.assertEquals(Double.POSITIVE_INFINITY,
806                             MathArrays.linearCombination(a[5][0], b[5][0],
807                                                          a[5][1], b[5][1],
808                                                          a[5][2], b[5][2]),
809                             1.0e-10);
810         Assert.assertEquals(Double.POSITIVE_INFINITY,
811                             MathArrays.linearCombination(a[5][0], b[5][0],
812                                                          a[5][1], b[5][1],
813                                                          a[5][2], b[5][2],
814                                                          a[5][3], b[5][3]),
815                             1.0e-10);
816         Assert.assertEquals(Double.POSITIVE_INFINITY, MathArrays.linearCombination(a[5], b[5]), 1.0e-10);
817 
818         Assert.assertEquals(Double.POSITIVE_INFINITY,
819                             MathArrays.linearCombination(a[6][0], b[6][0],
820                                                          a[6][1], b[6][1]),
821                             1.0e-10);
822         Assert.assertEquals(Double.POSITIVE_INFINITY,
823                             MathArrays.linearCombination(a[6][0], b[6][0],
824                                                          a[6][1], b[6][1],
825                                                          a[6][2], b[6][2]),
826                             1.0e-10);
827         Assert.assertTrue(Double.isNaN(MathArrays.linearCombination(a[6][0], b[6][0],
828                                                                     a[6][1], b[6][1],
829                                                                     a[6][2], b[6][2],
830                                                                     a[6][3], b[6][3])));
831         Assert.assertTrue(Double.isNaN(MathArrays.linearCombination(a[6], b[6])));
832 
833         Assert.assertTrue(Double.isNaN(MathArrays.linearCombination(a[7][0], b[7][0],
834                                                                     a[7][1], b[7][1])));
835         Assert.assertTrue(Double.isNaN(MathArrays.linearCombination(a[7][0], b[7][0],
836                                                                     a[7][1], b[7][1],
837                                                                     a[7][2], b[7][2])));
838         Assert.assertTrue(Double.isNaN(MathArrays.linearCombination(a[7][0], b[7][0],
839                                                                     a[7][1], b[7][1],
840                                                                     a[7][2], b[7][2],
841                                                                     a[7][3], b[7][3])));
842         Assert.assertTrue(Double.isNaN(MathArrays.linearCombination(a[7], b[7])));
843     }
844 
845     @Test
846     public void testArrayEquals() {
847         Assert.assertFalse(MathArrays.equals(new double[] { 1d }, null));
848         Assert.assertFalse(MathArrays.equals(null, new double[] { 1d }));
849         Assert.assertTrue(MathArrays.equals((double[]) null, (double[]) null));
850 
851         Assert.assertFalse(MathArrays.equals(new double[] { 1d }, new double[0]));
852         Assert.assertTrue(MathArrays.equals(new double[] { 1d }, new double[] { 1d }));
853         Assert.assertTrue(MathArrays.equals(new double[] { Double.POSITIVE_INFINITY,
854                                                            Double.NEGATIVE_INFINITY, 1d, 0d },
855                                             new double[] { Double.POSITIVE_INFINITY,
856                                                            Double.NEGATIVE_INFINITY, 1d, 0d }));
857         Assert.assertFalse(MathArrays.equals(new double[] { Double.NaN },
858                                              new double[] { Double.NaN }));
859         Assert.assertFalse(MathArrays.equals(new double[] { Double.POSITIVE_INFINITY },
860                                              new double[] { Double.NEGATIVE_INFINITY }));
861         Assert.assertFalse(MathArrays.equals(new double[] { 1d },
862                                              new double[] { FastMath.nextAfter(FastMath.nextAfter(1d, 2d), 2d) }));
863 
864     }
865 
866     @Test
867     public void testArrayEqualsIncludingNaN() {
868         Assert.assertFalse(MathArrays.equalsIncludingNaN(new double[] { 1d }, null));
869         Assert.assertFalse(MathArrays.equalsIncludingNaN(null, new double[] { 1d }));
870         Assert.assertTrue(MathArrays.equalsIncludingNaN((double[]) null, (double[]) null));
871 
872         Assert.assertFalse(MathArrays.equalsIncludingNaN(new double[] { 1d }, new double[0]));
873         Assert.assertTrue(MathArrays.equalsIncludingNaN(new double[] { 1d }, new double[] { 1d }));
874         Assert.assertTrue(MathArrays.equalsIncludingNaN(new double[] { Double.NaN, Double.POSITIVE_INFINITY,
875                                                                        Double.NEGATIVE_INFINITY, 1d, 0d },
876                                                         new double[] { Double.NaN, Double.POSITIVE_INFINITY,
877                                                                        Double.NEGATIVE_INFINITY, 1d, 0d }));
878         Assert.assertFalse(MathArrays.equalsIncludingNaN(new double[] { Double.POSITIVE_INFINITY },
879                                                          new double[] { Double.NEGATIVE_INFINITY }));
880         Assert.assertFalse(MathArrays.equalsIncludingNaN(new double[] { 1d },
881                                                          new double[] { FastMath.nextAfter(FastMath.nextAfter(1d, 2d), 2d) }));
882     }
883 
884     @Test
885     public void testLongArrayEquals() {
886         Assert.assertFalse(MathArrays.equals(new long[] { 1L }, null));
887         Assert.assertFalse(MathArrays.equals(null, new long[] { 1L }));
888         Assert.assertTrue(MathArrays.equals((long[]) null, (long[]) null));
889 
890         Assert.assertFalse(MathArrays.equals(new long[] { 1L }, new long[0]));
891         Assert.assertTrue(MathArrays.equals(new long[] { 1L }, new long[] { 1L }));
892         Assert.assertTrue(MathArrays.equals(new long[] { 0x7ff0000000000000L,
893                                                            0xfff0000000000000L, 1L, 0L },
894                                             new long[] { 0x7ff0000000000000L,
895                                                            0xfff0000000000000L, 1L, 0L }));
896         Assert.assertFalse(MathArrays.equals(new long[] { 0x7ff0000000000000L },
897                                              new long[] { 0xfff0000000000000L }));
898 
899     }
900 
901     @Test
902     public void testIntArrayEquals() {
903         Assert.assertFalse(MathArrays.equals(new int[] { 1 }, null));
904         Assert.assertFalse(MathArrays.equals(null, new int[] { 1 }));
905         Assert.assertTrue(MathArrays.equals((int[]) null, (int[]) null));
906 
907         Assert.assertFalse(MathArrays.equals(new int[] { 1 }, new int[0]));
908         Assert.assertTrue(MathArrays.equals(new int[] { 1 }, new int[] { 1 }));
909         Assert.assertTrue(MathArrays.equals(new int[] { Integer.MAX_VALUE,
910                                                         Integer.MIN_VALUE, 1, 0 },
911                                             new int[] { Integer.MAX_VALUE,
912                                                         Integer.MIN_VALUE, 1, 0 }));
913         Assert.assertFalse(MathArrays.equals(new int[] { Integer.MAX_VALUE },
914                                              new int[] { Integer.MIN_VALUE }));
915 
916     }
917 
918     @Test
919     public void testByteArrayEquals() {
920         Assert.assertFalse(MathArrays.equals(new byte[] { 1 }, null));
921         Assert.assertFalse(MathArrays.equals(null, new byte[] { 1 }));
922         Assert.assertTrue(MathArrays.equals((byte[]) null, (byte[]) null));
923 
924         Assert.assertFalse(MathArrays.equals(new byte[] { 1 }, new byte[0]));
925         Assert.assertTrue(MathArrays.equals(new byte[] { 1 }, new byte[] { 1 }));
926         Assert.assertTrue(MathArrays.equals(new byte[] { Byte.MAX_VALUE,
927                                                          Byte.MIN_VALUE, 1, 0 },
928                                             new byte[] { Byte.MAX_VALUE,
929                                                          Byte.MIN_VALUE, 1, 0 }));
930         Assert.assertFalse(MathArrays.equals(new byte[] { Byte.MAX_VALUE },
931                                              new byte[] { Byte.MIN_VALUE }));
932 
933     }
934 
935     @Test
936     public void testShortArrayEquals() {
937         Assert.assertFalse(MathArrays.equals(new short[] { 1 }, null));
938         Assert.assertFalse(MathArrays.equals(null, new short[] { 1 }));
939         Assert.assertTrue(MathArrays.equals((short[]) null, (short[]) null));
940 
941         Assert.assertFalse(MathArrays.equals(new short[] { 1 }, new short[0]));
942         Assert.assertTrue(MathArrays.equals(new short[] { 1 }, new short[] { 1 }));
943         Assert.assertTrue(MathArrays.equals(new short[] { Short.MAX_VALUE,
944                                                           Short.MIN_VALUE, 1, 0 },
945                                             new short[] { Short.MAX_VALUE,
946                                                           Short.MIN_VALUE, 1, 0 }));
947         Assert.assertFalse(MathArrays.equals(new short[] { Short.MAX_VALUE },
948                                              new short[] { Short.MIN_VALUE }));
949 
950     }
951 
952     @Test
953     public void testNormalizeArray() {
954         double[] testValues1 = new double[] {1, 1, 2};
955         UnitTestUtils.assertEquals( new double[] {.25, .25, .5},
956                                 MathArrays.normalizeArray(testValues1, 1),
957                                 Double.MIN_VALUE);
958 
959         double[] testValues2 = new double[] {-1, -1, 1};
960         UnitTestUtils.assertEquals( new double[] {1, 1, -1},
961                                 MathArrays.normalizeArray(testValues2, 1),
962                                 Double.MIN_VALUE);
963 
964         // Ignore NaNs
965         double[] testValues3 = new double[] {-1, -1, Double.NaN, 1, Double.NaN};
966         UnitTestUtils.assertEquals( new double[] {1, 1,Double.NaN, -1, Double.NaN},
967                                 MathArrays.normalizeArray(testValues3, 1),
968                                 Double.MIN_VALUE);
969 
970         // Zero sum -> MathRuntimeException
971         double[] zeroSum = new double[] {-1, 1};
972         try {
973             MathArrays.normalizeArray(zeroSum, 1);
974             Assert.fail("expecting MathRuntimeException");
975         } catch (MathRuntimeException ex) {}
976 
977         // Infinite elements -> MathRuntimeException
978         double[] hasInf = new double[] {1, 2, 1, Double.NEGATIVE_INFINITY};
979         try {
980             MathArrays.normalizeArray(hasInf, 1);
981             Assert.fail("expecting MathIllegalArgumentException");
982         } catch (MathIllegalArgumentException ex) {}
983 
984         // Infinite target -> MathIllegalArgumentException
985         try {
986             MathArrays.normalizeArray(testValues1, Double.POSITIVE_INFINITY);
987             Assert.fail("expecting MathIllegalArgumentException");
988         } catch (MathIllegalArgumentException ex) {}
989 
990         // NaN target -> MathIllegalArgumentException
991         try {
992             MathArrays.normalizeArray(testValues1, Double.NaN);
993             Assert.fail("expecting MathIllegalArgumentException");
994         } catch (MathIllegalArgumentException ex) {}
995     }
996 
997     @Test
998     public void testConvolve() {
999         /* Test Case (obtained via SciPy)
1000          * x=[1.2,-1.8,1.4]
1001          * h=[1,0.8,0.5,0.3]
1002          * convolve(x,h) -> array([ 1.2 , -0.84,  0.56,  0.58,  0.16,  0.42])
1003          */
1004         double[] x1 = { 1.2, -1.8, 1.4 };
1005         double[] h1 = { 1, 0.8, 0.5, 0.3 };
1006         double[] y1 = { 1.2, -0.84, 0.56, 0.58, 0.16, 0.42 };
1007         double tolerance = 1e-13;
1008 
1009         double[] yActual = MathArrays.convolve(x1, h1);
1010         Assert.assertArrayEquals(y1, yActual, tolerance);
1011 
1012         double[] x2 = { 1, 2, 3 };
1013         double[] h2 = { 0, 1, 0.5 };
1014         double[] y2 = { 0, 1, 2.5, 4, 1.5 };
1015 
1016         yActual = MathArrays.convolve(x2, h2);
1017         Assert.assertArrayEquals(y2, yActual, tolerance);
1018 
1019         try {
1020             MathArrays.convolve(new double[]{1, 2}, null);
1021             Assert.fail("an exception should have been thrown");
1022         } catch (NullArgumentException e) {
1023             // expected behavior
1024         }
1025 
1026         try {
1027             MathArrays.convolve(null, new double[]{1, 2});
1028             Assert.fail("an exception should have been thrown");
1029         } catch (NullArgumentException e) {
1030             // expected behavior
1031         }
1032 
1033         try {
1034             MathArrays.convolve(new double[]{1, 2}, new double[]{});
1035             Assert.fail("an exception should have been thrown");
1036         } catch (MathIllegalArgumentException e) {
1037             // expected behavior
1038         }
1039 
1040         try {
1041             MathArrays.convolve(new double[]{}, new double[]{1, 2});
1042             Assert.fail("an exception should have been thrown");
1043         } catch (MathIllegalArgumentException e) {
1044             // expected behavior
1045         }
1046 
1047         try {
1048             MathArrays.convolve(new double[]{}, new double[]{});
1049             Assert.fail("an exception should have been thrown");
1050         } catch (MathIllegalArgumentException e) {
1051             // expected behavior
1052         }
1053     }
1054 
1055     @Test
1056     public void testShuffleTail() {
1057         final int[] orig = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
1058         final int[] list = orig.clone();
1059         final int start = 4;
1060         MathArrays.shuffle(list, start, MathArrays.Position.TAIL, new Well1024a(7654321L));
1061 
1062         // Ensure that all entries below index "start" did not move.
1063         for (int i = 0; i < start; i++) {
1064             Assert.assertEquals(orig[i], list[i]);
1065         }
1066 
1067         // Ensure that at least one entry has moved.
1068         boolean ok = false;
1069         for (int i = start; i < orig.length - 1; i++) {
1070             if (orig[i] != list[i]) {
1071                 ok = true;
1072                 break;
1073             }
1074         }
1075         Assert.assertTrue(ok);
1076     }
1077 
1078     @Test
1079     public void testShuffleHead() {
1080         final int[] orig = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
1081         final int[] list = orig.clone();
1082         final int start = 4;
1083         MathArrays.shuffle(list, start, MathArrays.Position.HEAD, new Well1024a(1234567L));
1084 
1085         // Ensure that all entries above index "start" did not move.
1086         for (int i = start + 1; i < orig.length; i++) {
1087             Assert.assertEquals(orig[i], list[i]);
1088         }
1089 
1090         // Ensure that at least one entry has moved.
1091         boolean ok = false;
1092         for (int i = 0; i <= start; i++) {
1093             if (orig[i] != list[i]) {
1094                 ok = true;
1095                 break;
1096             }
1097         }
1098         Assert.assertTrue(ok);
1099     }
1100 
1101     @Test
1102     public void testNatural() {
1103         final int n = 4;
1104         final int[] expected = {0, 1, 2, 3};
1105 
1106         final int[] natural = MathArrays.natural(n);
1107         for (int i = 0; i < n; i++) {
1108             Assert.assertEquals(expected[i], natural[i]);
1109         }
1110     }
1111 
1112     @Test
1113     public void testNaturalZero() {
1114         final int[] natural = MathArrays.natural(0);
1115         Assert.assertEquals(0, natural.length);
1116     }
1117 
1118     @Test
1119     public void testSequence() {
1120         final int size = 4;
1121         final int start = 5;
1122         final int stride = 2;
1123         final int[] expected = {5, 7, 9, 11};
1124 
1125         final int[] seq = MathArrays.sequence(size, start, stride);
1126         for (int i = 0; i < size; i++) {
1127             Assert.assertEquals(expected[i], seq[i]);
1128         }
1129     }
1130 
1131     @Test
1132     public void testSequenceZero() {
1133         final int[] seq = MathArrays.sequence(0, 12345, 6789);
1134         Assert.assertEquals(0, seq.length);
1135     }
1136 
1137     @Test
1138     public void testVerifyValuesPositive() {
1139         for (int j = 0; j < 6; j++) {
1140             for (int i = 1; i < (7 - j); i++) {
1141                 Assert.assertTrue(MathArrays.verifyValues(testArray, 0, i));
1142             }
1143         }
1144         Assert.assertTrue(MathArrays.verifyValues(singletonArray, 0, 1));
1145         Assert.assertTrue(MathArrays.verifyValues(singletonArray, 0, 0, true));
1146     }
1147 
1148     @Test
1149     public void testVerifyValuesNegative() {
1150         Assert.assertFalse(MathArrays.verifyValues(singletonArray, 0, 0));
1151         Assert.assertFalse(MathArrays.verifyValues(testArray, 0, 0));
1152         try {
1153             MathArrays.verifyValues(singletonArray, 2, 1);  // start past end
1154             Assert.fail("Expecting MathIllegalArgumentException");
1155         } catch (MathIllegalArgumentException ex) {
1156             // expected
1157         }
1158         try {
1159             MathArrays.verifyValues(testArray, 0, 7);  // end past end
1160             Assert.fail("Expecting MathIllegalArgumentException");
1161         } catch (MathIllegalArgumentException ex) {
1162             // expected
1163         }
1164         try {
1165             MathArrays.verifyValues(testArray, -1, 1);  // start negative
1166             Assert.fail("Expecting MathIllegalArgumentException");
1167         } catch (MathIllegalArgumentException ex) {
1168             // expected
1169         }
1170         try {
1171             MathArrays.verifyValues(testArray, 0, -1);  // length negative
1172             Assert.fail("Expecting MathIllegalArgumentException");
1173         } catch (MathIllegalArgumentException ex) {
1174             // expected
1175         }
1176         try {
1177             MathArrays.verifyValues(nullArray, 0, 1);  // null array
1178             Assert.fail("Expecting NullArgumentException");
1179         } catch (NullArgumentException ex) {
1180             // expected
1181         }
1182         try {
1183             MathArrays.verifyValues(testArray, nullArray, 0, 1);  // null weights array
1184             Assert.fail("Expecting NullArgumentException");
1185         } catch (NullArgumentException ex) {
1186             // expected
1187         }
1188         try {
1189             MathArrays.verifyValues(singletonArray, testWeightsArray, 0, 1);  // weights.length != value.length
1190             Assert.fail("Expecting MathIllegalArgumentException");
1191         } catch (MathIllegalArgumentException ex) {
1192             // expected
1193         }
1194         try {
1195             MathArrays.verifyValues(testArray, testNegativeWeightsArray, 0, 6);  // can't have negative weights
1196             Assert.fail("Expecting MathIllegalArgumentException");
1197         } catch (MathIllegalArgumentException ex) {
1198             // expected
1199         }
1200     }
1201 
1202     @Test
1203     public void testConcatenate() {
1204         final double[] u = new double[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
1205         final double[] x = new double[] {0, 1, 2};
1206         final double[] y = new double[] {3, 4, 5, 6, 7, 8};
1207         final double[] z = new double[] {9};
1208         Assert.assertArrayEquals(u, MathArrays.concatenate(x, y, z), 0);
1209     }
1210 
1211     @Test
1212     public void testConcatentateSingle() {
1213         final double[] x = new double[] {0, 1, 2};
1214         Assert.assertArrayEquals(x, MathArrays.concatenate(x), 0);
1215     }
1216 
1217     public void testConcatenateEmptyArguments() {
1218         final double[] x = new double[] {0, 1, 2};
1219         final double[] y = new double[] {3};
1220         final double[] z = new double[] {};
1221         final double[] u = new double[] {0, 1, 2, 3};
1222         Assert.assertArrayEquals(u,  MathArrays.concatenate(x, z, y), 0);
1223         Assert.assertArrayEquals(u,  MathArrays.concatenate(x, y, z), 0);
1224         Assert.assertArrayEquals(u,  MathArrays.concatenate(z, x, y), 0);
1225         Assert.assertEquals(0,  MathArrays.concatenate(z, z, z).length);
1226     }
1227 
1228     @Test(expected=NullPointerException.class)
1229     public void testConcatenateNullArguments() {
1230         final double[] x = new double[] {0, 1, 2};
1231         MathArrays.concatenate(x, null);
1232     }
1233 
1234     @Test
1235     public void testUnique() {
1236         final double[] x = {0, 9, 3, 0, 11, 7, 3, 5, -1, -2};
1237         final double[] values = {11, 9, 7, 5, 3, 0, -1, -2};
1238         Assert.assertArrayEquals(values, MathArrays.unique(x), 0);
1239     }
1240 
1241     @Test
1242     public void testUniqueInfiniteValues() {
1243         final double [] x = {0, Double.NEGATIVE_INFINITY, 3, Double.NEGATIVE_INFINITY,
1244             3, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY};
1245         final double[] u = {Double.POSITIVE_INFINITY, 3, 0, Double.NEGATIVE_INFINITY};
1246         Assert.assertArrayEquals(u , MathArrays.unique(x), 0);
1247     }
1248 
1249     @Test
1250     public void testUniqueNaNValues() {
1251         final double[] x = new double[] {10, 2, Double.NaN, Double.NaN, Double.NaN,
1252             Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY};
1253         final double[] u = MathArrays.unique(x);
1254         Assert.assertEquals(5, u.length);
1255         Assert.assertTrue(Double.isNaN(u[0]));
1256         Assert.assertEquals(Double.POSITIVE_INFINITY, u[1], 0);
1257         Assert.assertEquals(10, u[2], 0);
1258         Assert.assertEquals(2, u[3], 0);
1259         Assert.assertEquals(Double.NEGATIVE_INFINITY, u[4], 0);
1260     }
1261 
1262     @Test(expected=NullPointerException.class)
1263     public void testUniqueNullArgument() {
1264         MathArrays.unique(null);
1265     }
1266 
1267     @Test
1268     public void testBuildArray1() {
1269         Binary64Field field = Binary64Field.getInstance();
1270         Binary64[] array = MathArrays.buildArray(field, 3);
1271         Assert.assertEquals(3, array.length);
1272         for (Binary64 d : array) {
1273             Assert.assertSame(field.getZero(), d);
1274         }
1275     }
1276 
1277     @Test
1278     public void testBuildArray2AllIndices() {
1279         Binary64Field field = Binary64Field.getInstance();
1280         Binary64[][] array = MathArrays.buildArray(field, 3, 2);
1281         Assert.assertEquals(3, array.length);
1282         for (Binary64[] a1 : array) {
1283             Assert.assertEquals(2, a1.length);
1284             for (Binary64 d : a1) {
1285                 Assert.assertSame(field.getZero(), d);
1286             }
1287         }
1288     }
1289 
1290     @Test
1291     public void testBuildArray2MissingLastIndex() {
1292         Binary64Field field = Binary64Field.getInstance();
1293         Binary64[][] array = MathArrays.buildArray(field, 3, -1);
1294         Assert.assertEquals(3, array.length);
1295         for (Binary64[] a1 : array) {
1296             Assert.assertNull(a1);
1297         }
1298     }
1299 
1300     @Test
1301     public void testBuildArray3AllIndices() {
1302         Binary64Field field = Binary64Field.getInstance();
1303         Binary64[][][] array = MathArrays.buildArray(field, 3, 2, 4);
1304         Assert.assertEquals(3, array.length);
1305         for (Binary64[][] a1 : array) {
1306             Assert.assertEquals(2, a1.length);
1307             for (Binary64[] a2 : a1) {
1308                 Assert.assertEquals(4, a2.length);
1309                 for (Binary64 d : a2) {
1310                     Assert.assertSame(field.getZero(), d);
1311                 }
1312             }
1313         }
1314     }
1315 
1316     @Test
1317     public void testBuildArray3MissingLastIndex() {
1318         Binary64Field field = Binary64Field.getInstance();
1319         Binary64[][][] array = MathArrays.buildArray(field, 3, 2, -1);
1320         Assert.assertEquals(3, array.length);
1321         for (Binary64[][] a1 : array) {
1322             Assert.assertEquals(2, a1.length);
1323             for (Binary64[] a2 : a1) {
1324                 Assert.assertNull(a2);
1325             }
1326         }
1327     }
1328 
1329 }