001/*
002        AUTOMATICALLY GENERATED BY jTemp FROM
003        /Users/jon/Work/openimaj/tags/openimaj-1.3.1/core/core/src/main/jtemp/org/openimaj/util/array/ArrayUtils.jtemp
004*/
005/**
006 * Copyright (c) 2011, The University of Southampton and the individual contributors.
007 * All rights reserved.
008 *
009 * Redistribution and use in source and binary forms, with or without modification,
010 * are permitted provided that the following conditions are met:
011 *
012 *   *  Redistributions of source code must retain the above copyright notice,
013 *      this list of conditions and the following disclaimer.
014 *
015 *   *  Redistributions in binary form must reproduce the above copyright notice,
016 *      this list of conditions and the following disclaimer in the documentation
017 *      and/or other materials provided with the distribution.
018 *
019 *   *  Neither the name of the University of Southampton nor the names of its
020 *      contributors may be used to endorse or promote products derived from this
021 *      software without specific prior written permission.
022 *
023 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
024 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
025 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
026 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
027 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
028 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
029 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
030 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
031 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
032 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
033 */
034package org.openimaj.util.array;
035
036import java.lang.reflect.Array;
037
038/**
039 * Collection of utilities for primitive arrays.
040 * 
041 * @author Jonathan Hare
042 * @author Sina Samangooei
043 * 
044 */
045public class ArrayUtils {
046    private ArrayUtils () {
047        
048    }
049    
050    
051        /**
052         * Returns the largest value in the array.
053         * 
054         * @param arr
055         *            array of double
056         * @return the value
057         */
058        public static double maxValue(final double[] arr) {
059                if (arr.length < 0)
060                        return 0;
061
062                double max = arr[0];
063                for (int i = 1; i < arr.length; i++) {
064                        if (arr[i] > max) {
065                                max = arr[i];
066                        }
067                }
068
069                return max;
070        }
071
072    
073        /**
074         * Returns the largest value in the array.
075         * 
076         * @param arr
077         *            array of float
078         * @return the value
079         */
080        public static float maxValue(final float[] arr) {
081                if (arr.length < 0)
082                        return 0;
083
084                float max = arr[0];
085                for (int i = 1; i < arr.length; i++) {
086                        if (arr[i] > max) {
087                                max = arr[i];
088                        }
089                }
090
091                return max;
092        }
093
094    
095        /**
096         * Returns the largest value in the array.
097         * 
098         * @param arr
099         *            array of int
100         * @return the value
101         */
102        public static int maxValue(final int[] arr) {
103                if (arr.length < 0)
104                        return 0;
105
106                int max = arr[0];
107                for (int i = 1; i < arr.length; i++) {
108                        if (arr[i] > max) {
109                                max = arr[i];
110                        }
111                }
112
113                return max;
114        }
115
116    
117        /**
118         * Returns the largest value in the array.
119         * 
120         * @param arr
121         *            array of long
122         * @return the value
123         */
124        public static long maxValue(final long[] arr) {
125                if (arr.length < 0)
126                        return 0;
127
128                long max = arr[0];
129                for (int i = 1; i < arr.length; i++) {
130                        if (arr[i] > max) {
131                                max = arr[i];
132                        }
133                }
134
135                return max;
136        }
137
138    
139        /**
140         * Returns the largest value in the array.
141         * 
142         * @param arr
143         *            array of byte
144         * @return the value
145         */
146        public static byte maxValue(final byte[] arr) {
147                if (arr.length < 0)
148                        return 0;
149
150                byte max = arr[0];
151                for (int i = 1; i < arr.length; i++) {
152                        if (arr[i] > max) {
153                                max = arr[i];
154                        }
155                }
156
157                return max;
158        }
159
160    
161        /**
162         * Returns the largest value in the array.
163         * 
164         * @param arr
165         *            array of short
166         * @return the value
167         */
168        public static short maxValue(final short[] arr) {
169                if (arr.length < 0)
170                        return 0;
171
172                short max = arr[0];
173                for (int i = 1; i < arr.length; i++) {
174                        if (arr[i] > max) {
175                                max = arr[i];
176                        }
177                }
178
179                return max;
180        }
181
182    
183        /**
184         * Returns the smallest value in the array.
185         * 
186         * @param arr
187         *            array of double
188         * @return the value
189         */
190        public static double minValue(final double[] arr) {
191                if (arr.length < 0)
192                        return 0;
193
194                double min = arr[0];
195                for (int i = 1; i < arr.length; i++) {
196                        if (arr[i] < min) {
197                                min = arr[i];
198                        }
199                }
200
201                return min;
202        }
203
204    
205        /**
206         * Returns the smallest value in the array.
207         * 
208         * @param arr
209         *            array of float
210         * @return the value
211         */
212        public static float minValue(final float[] arr) {
213                if (arr.length < 0)
214                        return 0;
215
216                float min = arr[0];
217                for (int i = 1; i < arr.length; i++) {
218                        if (arr[i] < min) {
219                                min = arr[i];
220                        }
221                }
222
223                return min;
224        }
225
226    
227        /**
228         * Returns the smallest value in the array.
229         * 
230         * @param arr
231         *            array of int
232         * @return the value
233         */
234        public static int minValue(final int[] arr) {
235                if (arr.length < 0)
236                        return 0;
237
238                int min = arr[0];
239                for (int i = 1; i < arr.length; i++) {
240                        if (arr[i] < min) {
241                                min = arr[i];
242                        }
243                }
244
245                return min;
246        }
247
248    
249        /**
250         * Returns the smallest value in the array.
251         * 
252         * @param arr
253         *            array of long
254         * @return the value
255         */
256        public static long minValue(final long[] arr) {
257                if (arr.length < 0)
258                        return 0;
259
260                long min = arr[0];
261                for (int i = 1; i < arr.length; i++) {
262                        if (arr[i] < min) {
263                                min = arr[i];
264                        }
265                }
266
267                return min;
268        }
269
270    
271        /**
272         * Returns the smallest value in the array.
273         * 
274         * @param arr
275         *            array of byte
276         * @return the value
277         */
278        public static byte minValue(final byte[] arr) {
279                if (arr.length < 0)
280                        return 0;
281
282                byte min = arr[0];
283                for (int i = 1; i < arr.length; i++) {
284                        if (arr[i] < min) {
285                                min = arr[i];
286                        }
287                }
288
289                return min;
290        }
291
292    
293        /**
294         * Returns the smallest value in the array.
295         * 
296         * @param arr
297         *            array of short
298         * @return the value
299         */
300        public static short minValue(final short[] arr) {
301                if (arr.length < 0)
302                        return 0;
303
304                short min = arr[0];
305                for (int i = 1; i < arr.length; i++) {
306                        if (arr[i] < min) {
307                                min = arr[i];
308                        }
309                }
310
311                return min;
312        }
313
314    
315        /**
316         * Returns the index to the biggest value in the array.
317         * 
318         * @param arr
319         *            array of double
320         * @return the index
321         */
322        public static int maxIndex(final double[] arr) {
323                double max = Double.MIN_VALUE;
324                int index = 0;
325                for (int i = 0; i < arr.length; i++) {
326                        if (arr[i] > max) {
327                                max = arr[i];
328                                index = i;
329                        }
330                }
331
332                return index;
333        }
334
335    
336        /**
337         * Returns the index to the biggest value in the array.
338         * 
339         * @param arr
340         *            array of float
341         * @return the index
342         */
343        public static int maxIndex(final float[] arr) {
344                float max = Float.MIN_VALUE;
345                int index = 0;
346                for (int i = 0; i < arr.length; i++) {
347                        if (arr[i] > max) {
348                                max = arr[i];
349                                index = i;
350                        }
351                }
352
353                return index;
354        }
355
356    
357        /**
358         * Returns the index to the biggest value in the array.
359         * 
360         * @param arr
361         *            array of int
362         * @return the index
363         */
364        public static int maxIndex(final int[] arr) {
365                int max = Integer.MIN_VALUE;
366                int index = 0;
367                for (int i = 0; i < arr.length; i++) {
368                        if (arr[i] > max) {
369                                max = arr[i];
370                                index = i;
371                        }
372                }
373
374                return index;
375        }
376
377    
378        /**
379         * Returns the index to the biggest value in the array.
380         * 
381         * @param arr
382         *            array of long
383         * @return the index
384         */
385        public static int maxIndex(final long[] arr) {
386                long max = Long.MIN_VALUE;
387                int index = 0;
388                for (int i = 0; i < arr.length; i++) {
389                        if (arr[i] > max) {
390                                max = arr[i];
391                                index = i;
392                        }
393                }
394
395                return index;
396        }
397
398    
399        /**
400         * Returns the index to the biggest value in the array.
401         * 
402         * @param arr
403         *            array of byte
404         * @return the index
405         */
406        public static int maxIndex(final byte[] arr) {
407                byte max = Byte.MIN_VALUE;
408                int index = 0;
409                for (int i = 0; i < arr.length; i++) {
410                        if (arr[i] > max) {
411                                max = arr[i];
412                                index = i;
413                        }
414                }
415
416                return index;
417        }
418
419    
420        /**
421         * Returns the index to the biggest value in the array.
422         * 
423         * @param arr
424         *            array of short
425         * @return the index
426         */
427        public static int maxIndex(final short[] arr) {
428                short max = Short.MIN_VALUE;
429                int index = 0;
430                for (int i = 0; i < arr.length; i++) {
431                        if (arr[i] > max) {
432                                max = arr[i];
433                                index = i;
434                        }
435                }
436
437                return index;
438        }
439
440    
441        /**
442         * Returns the index to the smallest value in the array.
443         * 
444         * @param arr
445         *            array of double
446         * @return the index
447         */
448        public static int minIndex(final double[] arr) {
449                double min = Double.MAX_VALUE;
450                int index = 0;
451                for (int i = 0; i < arr.length; i++) {
452                        if (arr[i] < min) {
453                                min = arr[i];
454                                index = i;
455                        }
456                }
457
458                return index;
459        }
460
461    
462        /**
463         * Returns the index to the smallest value in the array.
464         * 
465         * @param arr
466         *            array of float
467         * @return the index
468         */
469        public static int minIndex(final float[] arr) {
470                float min = Float.MAX_VALUE;
471                int index = 0;
472                for (int i = 0; i < arr.length; i++) {
473                        if (arr[i] < min) {
474                                min = arr[i];
475                                index = i;
476                        }
477                }
478
479                return index;
480        }
481
482    
483        /**
484         * Returns the index to the smallest value in the array.
485         * 
486         * @param arr
487         *            array of int
488         * @return the index
489         */
490        public static int minIndex(final int[] arr) {
491                int min = Integer.MAX_VALUE;
492                int index = 0;
493                for (int i = 0; i < arr.length; i++) {
494                        if (arr[i] < min) {
495                                min = arr[i];
496                                index = i;
497                        }
498                }
499
500                return index;
501        }
502
503    
504        /**
505         * Returns the index to the smallest value in the array.
506         * 
507         * @param arr
508         *            array of long
509         * @return the index
510         */
511        public static int minIndex(final long[] arr) {
512                long min = Long.MAX_VALUE;
513                int index = 0;
514                for (int i = 0; i < arr.length; i++) {
515                        if (arr[i] < min) {
516                                min = arr[i];
517                                index = i;
518                        }
519                }
520
521                return index;
522        }
523
524    
525        /**
526         * Returns the index to the smallest value in the array.
527         * 
528         * @param arr
529         *            array of byte
530         * @return the index
531         */
532        public static int minIndex(final byte[] arr) {
533                byte min = Byte.MAX_VALUE;
534                int index = 0;
535                for (int i = 0; i < arr.length; i++) {
536                        if (arr[i] < min) {
537                                min = arr[i];
538                                index = i;
539                        }
540                }
541
542                return index;
543        }
544
545    
546        /**
547         * Returns the index to the smallest value in the array.
548         * 
549         * @param arr
550         *            array of short
551         * @return the index
552         */
553        public static int minIndex(final short[] arr) {
554                short min = Short.MAX_VALUE;
555                int index = 0;
556                for (int i = 0; i < arr.length; i++) {
557                        if (arr[i] < min) {
558                                min = arr[i];
559                                index = i;
560                        }
561                }
562
563                return index;
564        }
565
566    
567        /**
568         * Element-wise summation of two arrays, output writes over first array
569         * 
570         * @param a1
571         *            first array
572         * @param a2
573         *            second array
574         * @return the first array
575         */
576        public static double[][] sum(final double[][] a1, final double[][] a2) {
577                for (int j = 0; j < a1.length; j++) {
578                        sum(a1[j], a2[j]);
579                }
580                return a1;
581        }
582
583        /**
584         * Element-wise summation of two arrays, output writes over first array
585         * 
586         * @param a1
587         *            first array
588         * @param a2
589         *            second array
590         * @return the first array
591         */
592        public static double[] sum(final double[] a1, final double[] a2) {
593                for (int j = 0; j < a1.length; j++) {
594                        a1[j] += a2[j];
595                }
596                return a1;
597        }
598
599    
600        /**
601         * Element-wise summation of two arrays, output writes over first array
602         * 
603         * @param a1
604         *            first array
605         * @param a2
606         *            second array
607         * @return the first array
608         */
609        public static float[][] sum(final float[][] a1, final float[][] a2) {
610                for (int j = 0; j < a1.length; j++) {
611                        sum(a1[j], a2[j]);
612                }
613                return a1;
614        }
615
616        /**
617         * Element-wise summation of two arrays, output writes over first array
618         * 
619         * @param a1
620         *            first array
621         * @param a2
622         *            second array
623         * @return the first array
624         */
625        public static float[] sum(final float[] a1, final float[] a2) {
626                for (int j = 0; j < a1.length; j++) {
627                        a1[j] += a2[j];
628                }
629                return a1;
630        }
631
632    
633        /**
634         * Element-wise summation of two arrays, output writes over first array
635         * 
636         * @param a1
637         *            first array
638         * @param a2
639         *            second array
640         * @return the first array
641         */
642        public static int[][] sum(final int[][] a1, final int[][] a2) {
643                for (int j = 0; j < a1.length; j++) {
644                        sum(a1[j], a2[j]);
645                }
646                return a1;
647        }
648
649        /**
650         * Element-wise summation of two arrays, output writes over first array
651         * 
652         * @param a1
653         *            first array
654         * @param a2
655         *            second array
656         * @return the first array
657         */
658        public static int[] sum(final int[] a1, final int[] a2) {
659                for (int j = 0; j < a1.length; j++) {
660                        a1[j] += a2[j];
661                }
662                return a1;
663        }
664
665    
666        /**
667         * Element-wise summation of two arrays, output writes over first array
668         * 
669         * @param a1
670         *            first array
671         * @param a2
672         *            second array
673         * @return the first array
674         */
675        public static long[][] sum(final long[][] a1, final long[][] a2) {
676                for (int j = 0; j < a1.length; j++) {
677                        sum(a1[j], a2[j]);
678                }
679                return a1;
680        }
681
682        /**
683         * Element-wise summation of two arrays, output writes over first array
684         * 
685         * @param a1
686         *            first array
687         * @param a2
688         *            second array
689         * @return the first array
690         */
691        public static long[] sum(final long[] a1, final long[] a2) {
692                for (int j = 0; j < a1.length; j++) {
693                        a1[j] += a2[j];
694                }
695                return a1;
696        }
697
698    
699        /**
700         * Element-wise summation of two arrays, output writes over first array
701         * 
702         * @param a1
703         *            first array
704         * @param a2
705         *            second array
706         * @return the first array
707         */
708        public static byte[][] sum(final byte[][] a1, final byte[][] a2) {
709                for (int j = 0; j < a1.length; j++) {
710                        sum(a1[j], a2[j]);
711                }
712                return a1;
713        }
714
715        /**
716         * Element-wise summation of two arrays, output writes over first array
717         * 
718         * @param a1
719         *            first array
720         * @param a2
721         *            second array
722         * @return the first array
723         */
724        public static byte[] sum(final byte[] a1, final byte[] a2) {
725                for (int j = 0; j < a1.length; j++) {
726                        a1[j] += a2[j];
727                }
728                return a1;
729        }
730
731    
732        /**
733         * Element-wise summation of two arrays, output writes over first array
734         * 
735         * @param a1
736         *            first array
737         * @param a2
738         *            second array
739         * @return the first array
740         */
741        public static short[][] sum(final short[][] a1, final short[][] a2) {
742                for (int j = 0; j < a1.length; j++) {
743                        sum(a1[j], a2[j]);
744                }
745                return a1;
746        }
747
748        /**
749         * Element-wise summation of two arrays, output writes over first array
750         * 
751         * @param a1
752         *            first array
753         * @param a2
754         *            second array
755         * @return the first array
756         */
757        public static short[] sum(final short[] a1, final short[] a2) {
758                for (int j = 0; j < a1.length; j++) {
759                        a1[j] += a2[j];
760                }
761                return a1;
762        }
763
764    
765        /**
766         * Element-wise subtraction of two arrays. Second array is subtracted from
767         * first, overwriting the first array
768         * 
769         * @param a1
770         *            first array
771         * @param a2
772         *            second array
773         * @return the first array
774         */
775        public static double[][] subtract(final double[][] a1, final double[][] a2) {
776                for (int j = 0; j < a1.length; j++) {
777                        subtract(a1[j], a2[j]);
778                }
779                return a1;
780        }
781
782        /**
783         * Element-wise subtraction of two arrays. Second array is subtracted from
784         * first, overwriting the first array
785         * 
786         * @param a1
787         *            first array
788         * @param a2
789         *            second array
790         * @return the first array
791         */
792        public static double[] subtract(final double[] a1, final double[] a2) {
793                for (int j = 0; j < a1.length; j++) {
794                        a1[j] -= a2[j];
795                }
796                return a1;
797        }
798
799        
800        /**
801         * Element-wise subtraction of two arrays. Second array is subtracted from
802         * first, overwriting the first array
803         * 
804         * @param a1
805         *            first array
806         * @param a2
807         *            second array
808         * @return the first array
809         */
810        public static float[][] subtract(final float[][] a1, final float[][] a2) {
811                for (int j = 0; j < a1.length; j++) {
812                        subtract(a1[j], a2[j]);
813                }
814                return a1;
815        }
816
817        /**
818         * Element-wise subtraction of two arrays. Second array is subtracted from
819         * first, overwriting the first array
820         * 
821         * @param a1
822         *            first array
823         * @param a2
824         *            second array
825         * @return the first array
826         */
827        public static float[] subtract(final float[] a1, final float[] a2) {
828                for (int j = 0; j < a1.length; j++) {
829                        a1[j] -= a2[j];
830                }
831                return a1;
832        }
833
834        
835        /**
836         * Element-wise subtraction of two arrays. Second array is subtracted from
837         * first, overwriting the first array
838         * 
839         * @param a1
840         *            first array
841         * @param a2
842         *            second array
843         * @return the first array
844         */
845        public static int[][] subtract(final int[][] a1, final int[][] a2) {
846                for (int j = 0; j < a1.length; j++) {
847                        subtract(a1[j], a2[j]);
848                }
849                return a1;
850        }
851
852        /**
853         * Element-wise subtraction of two arrays. Second array is subtracted from
854         * first, overwriting the first array
855         * 
856         * @param a1
857         *            first array
858         * @param a2
859         *            second array
860         * @return the first array
861         */
862        public static int[] subtract(final int[] a1, final int[] a2) {
863                for (int j = 0; j < a1.length; j++) {
864                        a1[j] -= a2[j];
865                }
866                return a1;
867        }
868
869        
870        /**
871         * Element-wise subtraction of two arrays. Second array is subtracted from
872         * first, overwriting the first array
873         * 
874         * @param a1
875         *            first array
876         * @param a2
877         *            second array
878         * @return the first array
879         */
880        public static long[][] subtract(final long[][] a1, final long[][] a2) {
881                for (int j = 0; j < a1.length; j++) {
882                        subtract(a1[j], a2[j]);
883                }
884                return a1;
885        }
886
887        /**
888         * Element-wise subtraction of two arrays. Second array is subtracted from
889         * first, overwriting the first array
890         * 
891         * @param a1
892         *            first array
893         * @param a2
894         *            second array
895         * @return the first array
896         */
897        public static long[] subtract(final long[] a1, final long[] a2) {
898                for (int j = 0; j < a1.length; j++) {
899                        a1[j] -= a2[j];
900                }
901                return a1;
902        }
903
904        
905        /**
906         * Element-wise subtraction of two arrays. Second array is subtracted from
907         * first, overwriting the first array
908         * 
909         * @param a1
910         *            first array
911         * @param a2
912         *            second array
913         * @return the first array
914         */
915        public static byte[][] subtract(final byte[][] a1, final byte[][] a2) {
916                for (int j = 0; j < a1.length; j++) {
917                        subtract(a1[j], a2[j]);
918                }
919                return a1;
920        }
921
922        /**
923         * Element-wise subtraction of two arrays. Second array is subtracted from
924         * first, overwriting the first array
925         * 
926         * @param a1
927         *            first array
928         * @param a2
929         *            second array
930         * @return the first array
931         */
932        public static byte[] subtract(final byte[] a1, final byte[] a2) {
933                for (int j = 0; j < a1.length; j++) {
934                        a1[j] -= a2[j];
935                }
936                return a1;
937        }
938
939        
940        /**
941         * Element-wise subtraction of two arrays. Second array is subtracted from
942         * first, overwriting the first array
943         * 
944         * @param a1
945         *            first array
946         * @param a2
947         *            second array
948         * @return the first array
949         */
950        public static short[][] subtract(final short[][] a1, final short[][] a2) {
951                for (int j = 0; j < a1.length; j++) {
952                        subtract(a1[j], a2[j]);
953                }
954                return a1;
955        }
956
957        /**
958         * Element-wise subtraction of two arrays. Second array is subtracted from
959         * first, overwriting the first array
960         * 
961         * @param a1
962         *            first array
963         * @param a2
964         *            second array
965         * @return the first array
966         */
967        public static short[] subtract(final short[] a1, final short[] a2) {
968                for (int j = 0; j < a1.length; j++) {
969                        a1[j] -= a2[j];
970                }
971                return a1;
972        }
973
974        
975        /**
976         * Subtracts <code>s</code> from all elements in <code>a1</code> overwriting
977         * the array. This is syntactic sugar for <code>add( a1, -s )</code>.
978         * 
979         * @param a1
980         *            The array
981         * @param s
982         *            The scalar
983         * @return the array
984         */
985        public static double[] subtract(final double[] a1, final double s)
986        {
987                return add(a1, (double)(-s));
988        }
989
990    
991        /**
992         * Subtracts <code>s</code> from all elements in <code>a1</code> overwriting
993         * the array. This is syntactic sugar for <code>add( a1, -s )</code>.
994         * 
995         * @param a1
996         *            The array
997         * @param s
998         *            The scalar
999         * @return the array
1000         */
1001        public static float[] subtract(final float[] a1, final float s)
1002        {
1003                return add(a1, (float)(-s));
1004        }
1005
1006    
1007        /**
1008         * Subtracts <code>s</code> from all elements in <code>a1</code> overwriting
1009         * the array. This is syntactic sugar for <code>add( a1, -s )</code>.
1010         * 
1011         * @param a1
1012         *            The array
1013         * @param s
1014         *            The scalar
1015         * @return the array
1016         */
1017        public static int[] subtract(final int[] a1, final int s)
1018        {
1019                return add(a1, (int)(-s));
1020        }
1021
1022    
1023        /**
1024         * Subtracts <code>s</code> from all elements in <code>a1</code> overwriting
1025         * the array. This is syntactic sugar for <code>add( a1, -s )</code>.
1026         * 
1027         * @param a1
1028         *            The array
1029         * @param s
1030         *            The scalar
1031         * @return the array
1032         */
1033        public static long[] subtract(final long[] a1, final long s)
1034        {
1035                return add(a1, (long)(-s));
1036        }
1037
1038    
1039        /**
1040         * Subtracts <code>s</code> from all elements in <code>a1</code> overwriting
1041         * the array. This is syntactic sugar for <code>add( a1, -s )</code>.
1042         * 
1043         * @param a1
1044         *            The array
1045         * @param s
1046         *            The scalar
1047         * @return the array
1048         */
1049        public static byte[] subtract(final byte[] a1, final byte s)
1050        {
1051                return add(a1, (byte)(-s));
1052        }
1053
1054    
1055        /**
1056         * Subtracts <code>s</code> from all elements in <code>a1</code> overwriting
1057         * the array. This is syntactic sugar for <code>add( a1, -s )</code>.
1058         * 
1059         * @param a1
1060         *            The array
1061         * @param s
1062         *            The scalar
1063         * @return the array
1064         */
1065        public static short[] subtract(final short[] a1, final short s)
1066        {
1067                return add(a1, (short)(-s));
1068        }
1069
1070    
1071        /**
1072         * Add a constant to all elements and return the input
1073         * 
1074         * @param ds
1075         *            input array
1076         * @param x
1077         *            constant to add
1078         * @return the input array
1079         */
1080        public static double[] add(final double[] ds, final double x) {
1081                for (int i = 0; i < ds.length; i++) {
1082                        ds[i] += x;
1083                }
1084                return ds;
1085        }
1086
1087    
1088        /**
1089         * Add a constant to all elements and return the input
1090         * 
1091         * @param ds
1092         *            input array
1093         * @param x
1094         *            constant to add
1095         * @return the input array
1096         */
1097        public static float[] add(final float[] ds, final float x) {
1098                for (int i = 0; i < ds.length; i++) {
1099                        ds[i] += x;
1100                }
1101                return ds;
1102        }
1103
1104    
1105        /**
1106         * Add a constant to all elements and return the input
1107         * 
1108         * @param ds
1109         *            input array
1110         * @param x
1111         *            constant to add
1112         * @return the input array
1113         */
1114        public static int[] add(final int[] ds, final int x) {
1115                for (int i = 0; i < ds.length; i++) {
1116                        ds[i] += x;
1117                }
1118                return ds;
1119        }
1120
1121    
1122        /**
1123         * Add a constant to all elements and return the input
1124         * 
1125         * @param ds
1126         *            input array
1127         * @param x
1128         *            constant to add
1129         * @return the input array
1130         */
1131        public static long[] add(final long[] ds, final long x) {
1132                for (int i = 0; i < ds.length; i++) {
1133                        ds[i] += x;
1134                }
1135                return ds;
1136        }
1137
1138    
1139        /**
1140         * Add a constant to all elements and return the input
1141         * 
1142         * @param ds
1143         *            input array
1144         * @param x
1145         *            constant to add
1146         * @return the input array
1147         */
1148        public static byte[] add(final byte[] ds, final byte x) {
1149                for (int i = 0; i < ds.length; i++) {
1150                        ds[i] += x;
1151                }
1152                return ds;
1153        }
1154
1155    
1156        /**
1157         * Add a constant to all elements and return the input
1158         * 
1159         * @param ds
1160         *            input array
1161         * @param x
1162         *            constant to add
1163         * @return the input array
1164         */
1165        public static short[] add(final short[] ds, final short x) {
1166                for (int i = 0; i < ds.length; i++) {
1167                        ds[i] += x;
1168                }
1169                return ds;
1170        }
1171
1172    
1173    /**
1174         * Multiply by a constant all elements and return the input
1175         * 
1176         * @param ds
1177         *            input array
1178         * @param x
1179         *            constant to multiply by
1180         * @return input
1181         */
1182        public static double[] multiply(final double[] ds, final double x) {
1183                for (int i = 0; i < ds.length; i++) {
1184                        ds[i] *= x;
1185                }
1186                return ds;
1187        }
1188        
1189        /**
1190         * Multiply by a constant all elements and return the input
1191         * 
1192         * @param ds
1193         *            input array
1194         * @param x
1195         *            constant to multiply by
1196         * @return input
1197         */
1198        public static double[][] multiply(final double[][] ds, final double x) {
1199                for (int i = 0; i < ds.length; i++) {
1200                        multiply(ds[i], x);
1201                }
1202                return ds;
1203        }
1204
1205    
1206    /**
1207         * Multiply by a constant all elements and return the input
1208         * 
1209         * @param ds
1210         *            input array
1211         * @param x
1212         *            constant to multiply by
1213         * @return input
1214         */
1215        public static float[] multiply(final float[] ds, final float x) {
1216                for (int i = 0; i < ds.length; i++) {
1217                        ds[i] *= x;
1218                }
1219                return ds;
1220        }
1221        
1222        /**
1223         * Multiply by a constant all elements and return the input
1224         * 
1225         * @param ds
1226         *            input array
1227         * @param x
1228         *            constant to multiply by
1229         * @return input
1230         */
1231        public static float[][] multiply(final float[][] ds, final float x) {
1232                for (int i = 0; i < ds.length; i++) {
1233                        multiply(ds[i], x);
1234                }
1235                return ds;
1236        }
1237
1238    
1239    /**
1240         * Multiply by a constant all elements and return the input
1241         * 
1242         * @param ds
1243         *            input array
1244         * @param x
1245         *            constant to multiply by
1246         * @return input
1247         */
1248        public static int[] multiply(final int[] ds, final int x) {
1249                for (int i = 0; i < ds.length; i++) {
1250                        ds[i] *= x;
1251                }
1252                return ds;
1253        }
1254        
1255        /**
1256         * Multiply by a constant all elements and return the input
1257         * 
1258         * @param ds
1259         *            input array
1260         * @param x
1261         *            constant to multiply by
1262         * @return input
1263         */
1264        public static int[][] multiply(final int[][] ds, final int x) {
1265                for (int i = 0; i < ds.length; i++) {
1266                        multiply(ds[i], x);
1267                }
1268                return ds;
1269        }
1270
1271    
1272    /**
1273         * Multiply by a constant all elements and return the input
1274         * 
1275         * @param ds
1276         *            input array
1277         * @param x
1278         *            constant to multiply by
1279         * @return input
1280         */
1281        public static long[] multiply(final long[] ds, final long x) {
1282                for (int i = 0; i < ds.length; i++) {
1283                        ds[i] *= x;
1284                }
1285                return ds;
1286        }
1287        
1288        /**
1289         * Multiply by a constant all elements and return the input
1290         * 
1291         * @param ds
1292         *            input array
1293         * @param x
1294         *            constant to multiply by
1295         * @return input
1296         */
1297        public static long[][] multiply(final long[][] ds, final long x) {
1298                for (int i = 0; i < ds.length; i++) {
1299                        multiply(ds[i], x);
1300                }
1301                return ds;
1302        }
1303
1304    
1305    /**
1306         * Multiply by a constant all elements and return the input
1307         * 
1308         * @param ds
1309         *            input array
1310         * @param x
1311         *            constant to multiply by
1312         * @return input
1313         */
1314        public static byte[] multiply(final byte[] ds, final byte x) {
1315                for (int i = 0; i < ds.length; i++) {
1316                        ds[i] *= x;
1317                }
1318                return ds;
1319        }
1320        
1321        /**
1322         * Multiply by a constant all elements and return the input
1323         * 
1324         * @param ds
1325         *            input array
1326         * @param x
1327         *            constant to multiply by
1328         * @return input
1329         */
1330        public static byte[][] multiply(final byte[][] ds, final byte x) {
1331                for (int i = 0; i < ds.length; i++) {
1332                        multiply(ds[i], x);
1333                }
1334                return ds;
1335        }
1336
1337    
1338    /**
1339         * Multiply by a constant all elements and return the input
1340         * 
1341         * @param ds
1342         *            input array
1343         * @param x
1344         *            constant to multiply by
1345         * @return input
1346         */
1347        public static short[] multiply(final short[] ds, final short x) {
1348                for (int i = 0; i < ds.length; i++) {
1349                        ds[i] *= x;
1350                }
1351                return ds;
1352        }
1353        
1354        /**
1355         * Multiply by a constant all elements and return the input
1356         * 
1357         * @param ds
1358         *            input array
1359         * @param x
1360         *            constant to multiply by
1361         * @return input
1362         */
1363        public static short[][] multiply(final short[][] ds, final short x) {
1364                for (int i = 0; i < ds.length; i++) {
1365                        multiply(ds[i], x);
1366                }
1367                return ds;
1368        }
1369
1370    
1371        /**
1372         * Element-wise multiplication, overwriting a1
1373         * 
1374         * @param a1
1375         *            The first array
1376         * @param a2
1377         *            the second array
1378         * @return The first array
1379         */
1380        public static double[] multiply(final double[] a1, final double[] a2)
1381        {
1382                for (int j = 0; j < a1.length; j++)
1383                        a1[j] *= a2[j];
1384                return a1;
1385        }
1386
1387        /**
1388         * Element-wise multiplication, overwriting a1.
1389         * 
1390         * @param a1
1391         *            First array
1392         * @param a2
1393         *            second array
1394         * @return Updated first array
1395         */
1396        public static double[][] multiply(final double[][] a1, final double[][] a2)
1397        {
1398                for (int j = 0; j < a1.length; j++)
1399                        multiply(a1[j], a2[j]);
1400                return a1;
1401        }
1402
1403    
1404        /**
1405         * Element-wise multiplication, overwriting a1
1406         * 
1407         * @param a1
1408         *            The first array
1409         * @param a2
1410         *            the second array
1411         * @return The first array
1412         */
1413        public static float[] multiply(final float[] a1, final float[] a2)
1414        {
1415                for (int j = 0; j < a1.length; j++)
1416                        a1[j] *= a2[j];
1417                return a1;
1418        }
1419
1420        /**
1421         * Element-wise multiplication, overwriting a1.
1422         * 
1423         * @param a1
1424         *            First array
1425         * @param a2
1426         *            second array
1427         * @return Updated first array
1428         */
1429        public static float[][] multiply(final float[][] a1, final float[][] a2)
1430        {
1431                for (int j = 0; j < a1.length; j++)
1432                        multiply(a1[j], a2[j]);
1433                return a1;
1434        }
1435
1436    
1437        /**
1438         * Element-wise multiplication, overwriting a1
1439         * 
1440         * @param a1
1441         *            The first array
1442         * @param a2
1443         *            the second array
1444         * @return The first array
1445         */
1446        public static int[] multiply(final int[] a1, final int[] a2)
1447        {
1448                for (int j = 0; j < a1.length; j++)
1449                        a1[j] *= a2[j];
1450                return a1;
1451        }
1452
1453        /**
1454         * Element-wise multiplication, overwriting a1.
1455         * 
1456         * @param a1
1457         *            First array
1458         * @param a2
1459         *            second array
1460         * @return Updated first array
1461         */
1462        public static int[][] multiply(final int[][] a1, final int[][] a2)
1463        {
1464                for (int j = 0; j < a1.length; j++)
1465                        multiply(a1[j], a2[j]);
1466                return a1;
1467        }
1468
1469    
1470        /**
1471         * Element-wise multiplication, overwriting a1
1472         * 
1473         * @param a1
1474         *            The first array
1475         * @param a2
1476         *            the second array
1477         * @return The first array
1478         */
1479        public static long[] multiply(final long[] a1, final long[] a2)
1480        {
1481                for (int j = 0; j < a1.length; j++)
1482                        a1[j] *= a2[j];
1483                return a1;
1484        }
1485
1486        /**
1487         * Element-wise multiplication, overwriting a1.
1488         * 
1489         * @param a1
1490         *            First array
1491         * @param a2
1492         *            second array
1493         * @return Updated first array
1494         */
1495        public static long[][] multiply(final long[][] a1, final long[][] a2)
1496        {
1497                for (int j = 0; j < a1.length; j++)
1498                        multiply(a1[j], a2[j]);
1499                return a1;
1500        }
1501
1502    
1503        /**
1504         * Element-wise multiplication, overwriting a1
1505         * 
1506         * @param a1
1507         *            The first array
1508         * @param a2
1509         *            the second array
1510         * @return The first array
1511         */
1512        public static byte[] multiply(final byte[] a1, final byte[] a2)
1513        {
1514                for (int j = 0; j < a1.length; j++)
1515                        a1[j] *= a2[j];
1516                return a1;
1517        }
1518
1519        /**
1520         * Element-wise multiplication, overwriting a1.
1521         * 
1522         * @param a1
1523         *            First array
1524         * @param a2
1525         *            second array
1526         * @return Updated first array
1527         */
1528        public static byte[][] multiply(final byte[][] a1, final byte[][] a2)
1529        {
1530                for (int j = 0; j < a1.length; j++)
1531                        multiply(a1[j], a2[j]);
1532                return a1;
1533        }
1534
1535    
1536        /**
1537         * Element-wise multiplication, overwriting a1
1538         * 
1539         * @param a1
1540         *            The first array
1541         * @param a2
1542         *            the second array
1543         * @return The first array
1544         */
1545        public static short[] multiply(final short[] a1, final short[] a2)
1546        {
1547                for (int j = 0; j < a1.length; j++)
1548                        a1[j] *= a2[j];
1549                return a1;
1550        }
1551
1552        /**
1553         * Element-wise multiplication, overwriting a1.
1554         * 
1555         * @param a1
1556         *            First array
1557         * @param a2
1558         *            second array
1559         * @return Updated first array
1560         */
1561        public static short[][] multiply(final short[][] a1, final short[][] a2)
1562        {
1563                for (int j = 0; j < a1.length; j++)
1564                        multiply(a1[j], a2[j]);
1565                return a1;
1566        }
1567
1568    
1569        /**
1570         * Divide by a constant, all elements and return the input
1571         * 
1572         * @param fs
1573         *            The input array
1574         * @param x
1575         *            the constant to divide by
1576         * @return THe input
1577         */
1578        public static double[] divide(final double[] fs, final double x)
1579        {
1580                for (int i = 0; i < fs.length; i++)
1581                        fs[i] /= x;
1582                return fs;
1583        }
1584
1585    
1586        /**
1587         * Divide by a constant, all elements and return the input
1588         * 
1589         * @param fs
1590         *            The input array
1591         * @param x
1592         *            the constant to divide by
1593         * @return THe input
1594         */
1595        public static float[] divide(final float[] fs, final float x)
1596        {
1597                for (int i = 0; i < fs.length; i++)
1598                        fs[i] /= x;
1599                return fs;
1600        }
1601
1602    
1603        /**
1604         * Divide by a constant, all elements and return the input
1605         * 
1606         * @param fs
1607         *            The input array
1608         * @param x
1609         *            the constant to divide by
1610         * @return THe input
1611         */
1612        public static int[] divide(final int[] fs, final int x)
1613        {
1614                for (int i = 0; i < fs.length; i++)
1615                        fs[i] /= x;
1616                return fs;
1617        }
1618
1619    
1620        /**
1621         * Divide by a constant, all elements and return the input
1622         * 
1623         * @param fs
1624         *            The input array
1625         * @param x
1626         *            the constant to divide by
1627         * @return THe input
1628         */
1629        public static long[] divide(final long[] fs, final long x)
1630        {
1631                for (int i = 0; i < fs.length; i++)
1632                        fs[i] /= x;
1633                return fs;
1634        }
1635
1636    
1637        /**
1638         * Divide by a constant, all elements and return the input
1639         * 
1640         * @param fs
1641         *            The input array
1642         * @param x
1643         *            the constant to divide by
1644         * @return THe input
1645         */
1646        public static byte[] divide(final byte[] fs, final byte x)
1647        {
1648                for (int i = 0; i < fs.length; i++)
1649                        fs[i] /= x;
1650                return fs;
1651        }
1652
1653    
1654        /**
1655         * Divide by a constant, all elements and return the input
1656         * 
1657         * @param fs
1658         *            The input array
1659         * @param x
1660         *            the constant to divide by
1661         * @return THe input
1662         */
1663        public static short[] divide(final short[] fs, final short x)
1664        {
1665                for (int i = 0; i < fs.length; i++)
1666                        fs[i] /= x;
1667                return fs;
1668        }
1669
1670    
1671        /**
1672         * Normalise length of array to 1.0. Writes over array. If the array is all
1673         * zeros, it will be unchanged.
1674         * 
1675         * @param array
1676         *            the array
1677         * @return the array
1678         */
1679        public static float[] normalise(final float[] array) {
1680                float sumsq = 0.0f;
1681                for (int i = 0; i < array.length; i++)
1682                        sumsq += array[i] * array[i];
1683
1684                if (sumsq == 0)
1685                        return array;
1686
1687                final float weight = 1.0f / (float) Math.sqrt(sumsq);
1688                for (int i = 0; i < array.length; i++)
1689                        array[i] *= weight;
1690                return array;
1691        }
1692
1693        /**
1694         * Normalise length of array to 1.0. Writes over array. If the array is all
1695         * zeros, it will be unchanged.
1696         * 
1697         * @param array
1698         *            the array
1699         * @return the array
1700         */
1701        public static double[] normalise(final double[] array) {
1702                double sumsq = 0.0f;
1703                for (int i = 0; i < array.length; i++)
1704                        sumsq += array[i] * array[i];
1705
1706                if (sumsq == 0)
1707                        return array;
1708
1709                final double weight = 1.0f / Math.sqrt(sumsq);
1710                for (int i = 0; i < array.length; i++)
1711                        array[i] *= weight;
1712                return array;
1713        }
1714
1715    
1716        /**
1717         * Reverse the elements in the input and return the input.
1718         * 
1719         * @param ds
1720         *            input array
1721         * @return input
1722         */
1723        public static double[] reverse(final double[] ds) {
1724                final int len = ds.length;
1725                final int hlen = len / 2;
1726
1727                for (int i = 0; i < hlen; i++) {
1728                        final double tmp = ds[i];
1729                        ds[i] = ds[len - i - 1];
1730                        ds[len - i - 1] = tmp;
1731                }
1732                return ds;
1733        }
1734
1735    
1736        /**
1737         * Reverse the elements in the input and return the input.
1738         * 
1739         * @param ds
1740         *            input array
1741         * @return input
1742         */
1743        public static float[] reverse(final float[] ds) {
1744                final int len = ds.length;
1745                final int hlen = len / 2;
1746
1747                for (int i = 0; i < hlen; i++) {
1748                        final float tmp = ds[i];
1749                        ds[i] = ds[len - i - 1];
1750                        ds[len - i - 1] = tmp;
1751                }
1752                return ds;
1753        }
1754
1755    
1756        /**
1757         * Reverse the elements in the input and return the input.
1758         * 
1759         * @param ds
1760         *            input array
1761         * @return input
1762         */
1763        public static int[] reverse(final int[] ds) {
1764                final int len = ds.length;
1765                final int hlen = len / 2;
1766
1767                for (int i = 0; i < hlen; i++) {
1768                        final int tmp = ds[i];
1769                        ds[i] = ds[len - i - 1];
1770                        ds[len - i - 1] = tmp;
1771                }
1772                return ds;
1773        }
1774
1775    
1776        /**
1777         * Reverse the elements in the input and return the input.
1778         * 
1779         * @param ds
1780         *            input array
1781         * @return input
1782         */
1783        public static long[] reverse(final long[] ds) {
1784                final int len = ds.length;
1785                final int hlen = len / 2;
1786
1787                for (int i = 0; i < hlen; i++) {
1788                        final long tmp = ds[i];
1789                        ds[i] = ds[len - i - 1];
1790                        ds[len - i - 1] = tmp;
1791                }
1792                return ds;
1793        }
1794
1795    
1796        /**
1797         * Reverse the elements in the input and return the input.
1798         * 
1799         * @param ds
1800         *            input array
1801         * @return input
1802         */
1803        public static byte[] reverse(final byte[] ds) {
1804                final int len = ds.length;
1805                final int hlen = len / 2;
1806
1807                for (int i = 0; i < hlen; i++) {
1808                        final byte tmp = ds[i];
1809                        ds[i] = ds[len - i - 1];
1810                        ds[len - i - 1] = tmp;
1811                }
1812                return ds;
1813        }
1814
1815    
1816        /**
1817         * Reverse the elements in the input and return the input.
1818         * 
1819         * @param ds
1820         *            input array
1821         * @return input
1822         */
1823        public static short[] reverse(final short[] ds) {
1824                final int len = ds.length;
1825                final int hlen = len / 2;
1826
1827                for (int i = 0; i < hlen; i++) {
1828                        final short tmp = ds[i];
1829                        ds[i] = ds[len - i - 1];
1830                        ds[len - i - 1] = tmp;
1831                }
1832                return ds;
1833        }
1834
1835    
1836        /**
1837         * Convert a double array to a double array.
1838         * 
1839         * @param array
1840         *            array of doubles to convert
1841         * @return array of doubles
1842         */
1843        public static double[] convertToDouble(final double[] array) {
1844                final double[] darr = new double[array.length];
1845
1846                for (int i = 0; i < array.length; i++) {
1847                        darr[i] = array[i];
1848                }
1849                return darr;
1850        }
1851
1852        /**
1853         * Convert a double array to a double array.
1854         * 
1855         * @param array
1856         *            array of doubles to convert
1857         * @return array of doubles
1858         */
1859        public static double[][] convertToDouble(final double[][] array)
1860        {
1861                final double[][] darr = new double[array.length][];
1862                for (int i = 0; i < array.length; i++)
1863                        darr[i] = convertToDouble(array[i]);
1864                return darr;
1865        }
1866
1867    
1868        /**
1869         * Convert a float array to a double array.
1870         * 
1871         * @param array
1872         *            array of floats to convert
1873         * @return array of doubles
1874         */
1875        public static double[] convertToDouble(final float[] array) {
1876                final double[] darr = new double[array.length];
1877
1878                for (int i = 0; i < array.length; i++) {
1879                        darr[i] = array[i];
1880                }
1881                return darr;
1882        }
1883
1884        /**
1885         * Convert a float array to a double array.
1886         * 
1887         * @param array
1888         *            array of floats to convert
1889         * @return array of doubles
1890         */
1891        public static double[][] convertToDouble(final float[][] array)
1892        {
1893                final double[][] darr = new double[array.length][];
1894                for (int i = 0; i < array.length; i++)
1895                        darr[i] = convertToDouble(array[i]);
1896                return darr;
1897        }
1898
1899    
1900        /**
1901         * Convert a int array to a double array.
1902         * 
1903         * @param array
1904         *            array of ints to convert
1905         * @return array of doubles
1906         */
1907        public static double[] convertToDouble(final int[] array) {
1908                final double[] darr = new double[array.length];
1909
1910                for (int i = 0; i < array.length; i++) {
1911                        darr[i] = array[i];
1912                }
1913                return darr;
1914        }
1915
1916        /**
1917         * Convert a int array to a double array.
1918         * 
1919         * @param array
1920         *            array of ints to convert
1921         * @return array of doubles
1922         */
1923        public static double[][] convertToDouble(final int[][] array)
1924        {
1925                final double[][] darr = new double[array.length][];
1926                for (int i = 0; i < array.length; i++)
1927                        darr[i] = convertToDouble(array[i]);
1928                return darr;
1929        }
1930
1931    
1932        /**
1933         * Convert a long array to a double array.
1934         * 
1935         * @param array
1936         *            array of longs to convert
1937         * @return array of doubles
1938         */
1939        public static double[] convertToDouble(final long[] array) {
1940                final double[] darr = new double[array.length];
1941
1942                for (int i = 0; i < array.length; i++) {
1943                        darr[i] = array[i];
1944                }
1945                return darr;
1946        }
1947
1948        /**
1949         * Convert a long array to a double array.
1950         * 
1951         * @param array
1952         *            array of longs to convert
1953         * @return array of doubles
1954         */
1955        public static double[][] convertToDouble(final long[][] array)
1956        {
1957                final double[][] darr = new double[array.length][];
1958                for (int i = 0; i < array.length; i++)
1959                        darr[i] = convertToDouble(array[i]);
1960                return darr;
1961        }
1962
1963    
1964        /**
1965         * Convert a byte array to a double array.
1966         * 
1967         * @param array
1968         *            array of bytes to convert
1969         * @return array of doubles
1970         */
1971        public static double[] convertToDouble(final byte[] array) {
1972                final double[] darr = new double[array.length];
1973
1974                for (int i = 0; i < array.length; i++) {
1975                        darr[i] = array[i];
1976                }
1977                return darr;
1978        }
1979
1980        /**
1981         * Convert a byte array to a double array.
1982         * 
1983         * @param array
1984         *            array of bytes to convert
1985         * @return array of doubles
1986         */
1987        public static double[][] convertToDouble(final byte[][] array)
1988        {
1989                final double[][] darr = new double[array.length][];
1990                for (int i = 0; i < array.length; i++)
1991                        darr[i] = convertToDouble(array[i]);
1992                return darr;
1993        }
1994
1995    
1996        /**
1997         * Convert a short array to a double array.
1998         * 
1999         * @param array
2000         *            array of shorts to convert
2001         * @return array of doubles
2002         */
2003        public static double[] convertToDouble(final short[] array) {
2004                final double[] darr = new double[array.length];
2005
2006                for (int i = 0; i < array.length; i++) {
2007                        darr[i] = array[i];
2008                }
2009                return darr;
2010        }
2011
2012        /**
2013         * Convert a short array to a double array.
2014         * 
2015         * @param array
2016         *            array of shorts to convert
2017         * @return array of doubles
2018         */
2019        public static double[][] convertToDouble(final short[][] array)
2020        {
2021                final double[][] darr = new double[array.length][];
2022                for (int i = 0; i < array.length; i++)
2023                        darr[i] = convertToDouble(array[i]);
2024                return darr;
2025        }
2026
2027    
2028        /**
2029         * Convert a double array to a float array.
2030         * 
2031         * @param array
2032         *            array of doubles to convert
2033         * @return array of floats
2034         */
2035        public static float[] convertToFloat(final double[] array) {
2036                final float[] farr = new float[array.length];
2037
2038                for (int i = 0; i < array.length; i++) {
2039                        farr[i] = (float) array[i];
2040                }
2041                return farr;
2042        }
2043
2044    /**
2045         * Convert a double array to a float array.
2046         * 
2047         * @param array
2048         *            array of doubles to convert
2049         * @return array of doubles
2050         */
2051        public static float[][] convertToFloat(final double[][] array)
2052        {
2053                final float[][] darr = new float[array.length][];
2054                for (int i = 0; i < array.length; i++)
2055                        darr[i] = convertToFloat(array[i]);
2056                return darr;
2057        }
2058
2059    
2060        /**
2061         * Convert a float array to a float array.
2062         * 
2063         * @param array
2064         *            array of floats to convert
2065         * @return array of floats
2066         */
2067        public static float[] convertToFloat(final float[] array) {
2068                final float[] farr = new float[array.length];
2069
2070                for (int i = 0; i < array.length; i++) {
2071                        farr[i] = (float) array[i];
2072                }
2073                return farr;
2074        }
2075
2076    /**
2077         * Convert a float array to a float array.
2078         * 
2079         * @param array
2080         *            array of floats to convert
2081         * @return array of doubles
2082         */
2083        public static float[][] convertToFloat(final float[][] array)
2084        {
2085                final float[][] darr = new float[array.length][];
2086                for (int i = 0; i < array.length; i++)
2087                        darr[i] = convertToFloat(array[i]);
2088                return darr;
2089        }
2090
2091    
2092        /**
2093         * Convert a int array to a float array.
2094         * 
2095         * @param array
2096         *            array of ints to convert
2097         * @return array of floats
2098         */
2099        public static float[] convertToFloat(final int[] array) {
2100                final float[] farr = new float[array.length];
2101
2102                for (int i = 0; i < array.length; i++) {
2103                        farr[i] = (float) array[i];
2104                }
2105                return farr;
2106        }
2107
2108    /**
2109         * Convert a int array to a float array.
2110         * 
2111         * @param array
2112         *            array of ints to convert
2113         * @return array of doubles
2114         */
2115        public static float[][] convertToFloat(final int[][] array)
2116        {
2117                final float[][] darr = new float[array.length][];
2118                for (int i = 0; i < array.length; i++)
2119                        darr[i] = convertToFloat(array[i]);
2120                return darr;
2121        }
2122
2123    
2124        /**
2125         * Convert a long array to a float array.
2126         * 
2127         * @param array
2128         *            array of longs to convert
2129         * @return array of floats
2130         */
2131        public static float[] convertToFloat(final long[] array) {
2132                final float[] farr = new float[array.length];
2133
2134                for (int i = 0; i < array.length; i++) {
2135                        farr[i] = (float) array[i];
2136                }
2137                return farr;
2138        }
2139
2140    /**
2141         * Convert a long array to a float array.
2142         * 
2143         * @param array
2144         *            array of longs to convert
2145         * @return array of doubles
2146         */
2147        public static float[][] convertToFloat(final long[][] array)
2148        {
2149                final float[][] darr = new float[array.length][];
2150                for (int i = 0; i < array.length; i++)
2151                        darr[i] = convertToFloat(array[i]);
2152                return darr;
2153        }
2154
2155    
2156        /**
2157         * Convert a byte array to a float array.
2158         * 
2159         * @param array
2160         *            array of bytes to convert
2161         * @return array of floats
2162         */
2163        public static float[] convertToFloat(final byte[] array) {
2164                final float[] farr = new float[array.length];
2165
2166                for (int i = 0; i < array.length; i++) {
2167                        farr[i] = (float) array[i];
2168                }
2169                return farr;
2170        }
2171
2172    /**
2173         * Convert a byte array to a float array.
2174         * 
2175         * @param array
2176         *            array of bytes to convert
2177         * @return array of doubles
2178         */
2179        public static float[][] convertToFloat(final byte[][] array)
2180        {
2181                final float[][] darr = new float[array.length][];
2182                for (int i = 0; i < array.length; i++)
2183                        darr[i] = convertToFloat(array[i]);
2184                return darr;
2185        }
2186
2187    
2188        /**
2189         * Convert a short array to a float array.
2190         * 
2191         * @param array
2192         *            array of shorts to convert
2193         * @return array of floats
2194         */
2195        public static float[] convertToFloat(final short[] array) {
2196                final float[] farr = new float[array.length];
2197
2198                for (int i = 0; i < array.length; i++) {
2199                        farr[i] = (float) array[i];
2200                }
2201                return farr;
2202        }
2203
2204    /**
2205         * Convert a short array to a float array.
2206         * 
2207         * @param array
2208         *            array of shorts to convert
2209         * @return array of doubles
2210         */
2211        public static float[][] convertToFloat(final short[][] array)
2212        {
2213                final float[][] darr = new float[array.length][];
2214                for (int i = 0; i < array.length; i++)
2215                        darr[i] = convertToFloat(array[i]);
2216                return darr;
2217        }
2218
2219    
2220        /**
2221         * Return the first non-null item from an array.
2222         * 
2223         * @param <T>
2224         *            the type of the elements in the array
2225         * @param array
2226         *            the array
2227         * @return the first non-null object, or null if not found.
2228         */
2229        public static <T> T firstNonNull(final T[] array) {
2230                if (array == null)
2231                        return null;
2232
2233                for (final T obj : array) {
2234                        if (obj != null) {
2235                                return obj;
2236                        }
2237                }
2238
2239                return null;
2240        }
2241
2242    
2243        /**
2244         * Concatenate multiple arrays into a single new array.
2245         * 
2246         * @param <T>
2247         *            Type of elements in the array.
2248         * @param arrays
2249         *            the arrays to concatenate.
2250         * @return the new concatenated array
2251         */
2252        public static <T> T[] concatenate(final T[]... arrays) {
2253                int length = 0;
2254                Class<?> type = null;
2255
2256                for (final T[] arr : arrays) {
2257                        if (arr != null) {
2258                                length += arr.length;
2259
2260                                if (type == null) {
2261                                        type = arr.getClass().getComponentType();
2262                                }
2263                        }
2264                }
2265
2266                @SuppressWarnings("unchecked")
2267                final T[] concat = (T[]) Array.newInstance(type, length);
2268
2269                int current = 0;
2270                for (final T[] arr : arrays) {
2271                        System.arraycopy(arr, 0, concat, current, arr.length);
2272                        current += arr.length;
2273                }
2274
2275                return concat;
2276        }
2277
2278    
2279        /**
2280         * Concatenate multiple arrays into a single new array.
2281         * 
2282         * @param arrays
2283         *            the arrays to concatenate.
2284         * @return the new concatenated array
2285         */
2286        public static double[] concatenate(final double[]... arrays) {
2287                int length = 0;
2288                for (final double[] arr : arrays) {
2289                        length += (arr == null ? 0 : arr.length);
2290                }
2291
2292                final double[] concat = new double[length];
2293
2294                int current = 0;
2295                for (final double[] arr : arrays) {
2296                        System.arraycopy(arr, 0, concat, current, arr.length);
2297                        current += arr.length;
2298                }
2299
2300                return concat;
2301        }
2302        
2303         
2304        /**
2305         * Concatenate multiple arrays into a single new array.
2306         * 
2307         * @param arrays
2308         *            the arrays to concatenate.
2309         * @return the new concatenated array
2310         */
2311        public static float[] concatenate(final float[]... arrays) {
2312                int length = 0;
2313                for (final float[] arr : arrays) {
2314                        length += (arr == null ? 0 : arr.length);
2315                }
2316
2317                final float[] concat = new float[length];
2318
2319                int current = 0;
2320                for (final float[] arr : arrays) {
2321                        System.arraycopy(arr, 0, concat, current, arr.length);
2322                        current += arr.length;
2323                }
2324
2325                return concat;
2326        }
2327        
2328         
2329        /**
2330         * Concatenate multiple arrays into a single new array.
2331         * 
2332         * @param arrays
2333         *            the arrays to concatenate.
2334         * @return the new concatenated array
2335         */
2336        public static int[] concatenate(final int[]... arrays) {
2337                int length = 0;
2338                for (final int[] arr : arrays) {
2339                        length += (arr == null ? 0 : arr.length);
2340                }
2341
2342                final int[] concat = new int[length];
2343
2344                int current = 0;
2345                for (final int[] arr : arrays) {
2346                        System.arraycopy(arr, 0, concat, current, arr.length);
2347                        current += arr.length;
2348                }
2349
2350                return concat;
2351        }
2352        
2353         
2354        /**
2355         * Concatenate multiple arrays into a single new array.
2356         * 
2357         * @param arrays
2358         *            the arrays to concatenate.
2359         * @return the new concatenated array
2360         */
2361        public static long[] concatenate(final long[]... arrays) {
2362                int length = 0;
2363                for (final long[] arr : arrays) {
2364                        length += (arr == null ? 0 : arr.length);
2365                }
2366
2367                final long[] concat = new long[length];
2368
2369                int current = 0;
2370                for (final long[] arr : arrays) {
2371                        System.arraycopy(arr, 0, concat, current, arr.length);
2372                        current += arr.length;
2373                }
2374
2375                return concat;
2376        }
2377        
2378         
2379        /**
2380         * Concatenate multiple arrays into a single new array.
2381         * 
2382         * @param arrays
2383         *            the arrays to concatenate.
2384         * @return the new concatenated array
2385         */
2386        public static byte[] concatenate(final byte[]... arrays) {
2387                int length = 0;
2388                for (final byte[] arr : arrays) {
2389                        length += (arr == null ? 0 : arr.length);
2390                }
2391
2392                final byte[] concat = new byte[length];
2393
2394                int current = 0;
2395                for (final byte[] arr : arrays) {
2396                        System.arraycopy(arr, 0, concat, current, arr.length);
2397                        current += arr.length;
2398                }
2399
2400                return concat;
2401        }
2402        
2403         
2404        /**
2405         * Concatenate multiple arrays into a single new array.
2406         * 
2407         * @param arrays
2408         *            the arrays to concatenate.
2409         * @return the new concatenated array
2410         */
2411        public static short[] concatenate(final short[]... arrays) {
2412                int length = 0;
2413                for (final short[] arr : arrays) {
2414                        length += (arr == null ? 0 : arr.length);
2415                }
2416
2417                final short[] concat = new short[length];
2418
2419                int current = 0;
2420                for (final short[] arr : arrays) {
2421                        System.arraycopy(arr, 0, concat, current, arr.length);
2422                        current += arr.length;
2423                }
2424
2425                return concat;
2426        }
2427        
2428         
2429        /**
2430         * Concatenate multiple arrays into a single new array.
2431         * 
2432         * @param arrays
2433         *            the arrays to concatenate.
2434         * @return the new concatenated array
2435         */
2436        public static double[][] concatenate(final double[][]... arrays) {
2437                final double[][] concat = new double[arrays[0].length][];
2438                for(int i = 0; i < concat.length; i++){
2439                        final double[][] row = new double[arrays.length][];
2440                        for(int j = 0; j < row.length; j++){
2441                                row[j] = arrays[j][i];
2442                        } 
2443                        concat[i] = concatenate(row);
2444                }
2445                
2446                return concat;
2447        }
2448
2449        
2450        /**
2451         * Concatenate multiple arrays into a single new array.
2452         * 
2453         * @param arrays
2454         *            the arrays to concatenate.
2455         * @return the new concatenated array
2456         */
2457        public static float[][] concatenate(final float[][]... arrays) {
2458                final float[][] concat = new float[arrays[0].length][];
2459                for(int i = 0; i < concat.length; i++){
2460                        final float[][] row = new float[arrays.length][];
2461                        for(int j = 0; j < row.length; j++){
2462                                row[j] = arrays[j][i];
2463                        } 
2464                        concat[i] = concatenate(row);
2465                }
2466                
2467                return concat;
2468        }
2469
2470        
2471        /**
2472         * Concatenate multiple arrays into a single new array.
2473         * 
2474         * @param arrays
2475         *            the arrays to concatenate.
2476         * @return the new concatenated array
2477         */
2478        public static int[][] concatenate(final int[][]... arrays) {
2479                final int[][] concat = new int[arrays[0].length][];
2480                for(int i = 0; i < concat.length; i++){
2481                        final int[][] row = new int[arrays.length][];
2482                        for(int j = 0; j < row.length; j++){
2483                                row[j] = arrays[j][i];
2484                        } 
2485                        concat[i] = concatenate(row);
2486                }
2487                
2488                return concat;
2489        }
2490
2491        
2492        /**
2493         * Concatenate multiple arrays into a single new array.
2494         * 
2495         * @param arrays
2496         *            the arrays to concatenate.
2497         * @return the new concatenated array
2498         */
2499        public static long[][] concatenate(final long[][]... arrays) {
2500                final long[][] concat = new long[arrays[0].length][];
2501                for(int i = 0; i < concat.length; i++){
2502                        final long[][] row = new long[arrays.length][];
2503                        for(int j = 0; j < row.length; j++){
2504                                row[j] = arrays[j][i];
2505                        } 
2506                        concat[i] = concatenate(row);
2507                }
2508                
2509                return concat;
2510        }
2511
2512        
2513        /**
2514         * Concatenate multiple arrays into a single new array.
2515         * 
2516         * @param arrays
2517         *            the arrays to concatenate.
2518         * @return the new concatenated array
2519         */
2520        public static byte[][] concatenate(final byte[][]... arrays) {
2521                final byte[][] concat = new byte[arrays[0].length][];
2522                for(int i = 0; i < concat.length; i++){
2523                        final byte[][] row = new byte[arrays.length][];
2524                        for(int j = 0; j < row.length; j++){
2525                                row[j] = arrays[j][i];
2526                        } 
2527                        concat[i] = concatenate(row);
2528                }
2529                
2530                return concat;
2531        }
2532
2533        
2534        /**
2535         * Concatenate multiple arrays into a single new array.
2536         * 
2537         * @param arrays
2538         *            the arrays to concatenate.
2539         * @return the new concatenated array
2540         */
2541        public static short[][] concatenate(final short[][]... arrays) {
2542                final short[][] concat = new short[arrays[0].length][];
2543                for(int i = 0; i < concat.length; i++){
2544                        final short[][] row = new short[arrays.length][];
2545                        for(int j = 0; j < row.length; j++){
2546                                row[j] = arrays[j][i];
2547                        } 
2548                        concat[i] = concatenate(row);
2549                }
2550                
2551                return concat;
2552        }
2553
2554        
2555        /*** 
2556        { m -> 
2557                if (m['T'] == DOUBLE) {
2558                        return (m['R'] == DOUBLE);              
2559                }
2560                if (m['T'] == LONG) {
2561                        return (m['R'] == LONG);
2562                }
2563                if (m['T'] == INT) {
2564                        return (m['R'] == LONG);
2565                }
2566                if (m['T'] == SHORT) {
2567                        return (m['R'] == INT);
2568                }
2569                if (m['T'] == BYTE) {
2570                        return (m['R'] == INT);
2571                }
2572                return (m['R'] == FLOAT);
2573        }
2574    ***/
2575        /**
2576         * Compute the sum of values in an array
2577         * 
2578         * @param vector
2579         * @return the sum of all values
2580         */
2581        public static double sumValues(final double[] vector) {
2582                double sum = 0;
2583
2584                for (final double v : vector)
2585                        sum += v;
2586
2587                return sum;
2588        }
2589        
2590        
2591        /*** 
2592        { m -> 
2593                if (m['T'] == DOUBLE) {
2594                        return (m['R'] == DOUBLE);              
2595                }
2596                if (m['T'] == LONG) {
2597                        return (m['R'] == LONG);
2598                }
2599                if (m['T'] == INT) {
2600                        return (m['R'] == LONG);
2601                }
2602                if (m['T'] == SHORT) {
2603                        return (m['R'] == INT);
2604                }
2605                if (m['T'] == BYTE) {
2606                        return (m['R'] == INT);
2607                }
2608                return (m['R'] == FLOAT);
2609        }
2610    ***/
2611        /**
2612         * Compute the sum of values in an array
2613         * 
2614         * @param vector
2615         * @return the sum of all values
2616         */
2617        public static float sumValues(final float[] vector) {
2618                float sum = 0;
2619
2620                for (final float v : vector)
2621                        sum += v;
2622
2623                return sum;
2624        }
2625        
2626        
2627        /*** 
2628        { m -> 
2629                if (m['T'] == DOUBLE) {
2630                        return (m['R'] == DOUBLE);              
2631                }
2632                if (m['T'] == LONG) {
2633                        return (m['R'] == LONG);
2634                }
2635                if (m['T'] == INT) {
2636                        return (m['R'] == LONG);
2637                }
2638                if (m['T'] == SHORT) {
2639                        return (m['R'] == INT);
2640                }
2641                if (m['T'] == BYTE) {
2642                        return (m['R'] == INT);
2643                }
2644                return (m['R'] == FLOAT);
2645        }
2646    ***/
2647        /**
2648         * Compute the sum of values in an array
2649         * 
2650         * @param vector
2651         * @return the sum of all values
2652         */
2653        public static int sumValues(final byte[] vector) {
2654                int sum = 0;
2655
2656                for (final byte v : vector)
2657                        sum += v;
2658
2659                return sum;
2660        }
2661        
2662        
2663        /*** 
2664        { m -> 
2665                if (m['T'] == DOUBLE) {
2666                        return (m['R'] == DOUBLE);              
2667                }
2668                if (m['T'] == LONG) {
2669                        return (m['R'] == LONG);
2670                }
2671                if (m['T'] == INT) {
2672                        return (m['R'] == LONG);
2673                }
2674                if (m['T'] == SHORT) {
2675                        return (m['R'] == INT);
2676                }
2677                if (m['T'] == BYTE) {
2678                        return (m['R'] == INT);
2679                }
2680                return (m['R'] == FLOAT);
2681        }
2682    ***/
2683        /**
2684         * Compute the sum of values in an array
2685         * 
2686         * @param vector
2687         * @return the sum of all values
2688         */
2689        public static int sumValues(final short[] vector) {
2690                int sum = 0;
2691
2692                for (final short v : vector)
2693                        sum += v;
2694
2695                return sum;
2696        }
2697        
2698        
2699        /*** 
2700        { m -> 
2701                if (m['T'] == DOUBLE) {
2702                        return (m['R'] == DOUBLE);              
2703                }
2704                if (m['T'] == LONG) {
2705                        return (m['R'] == LONG);
2706                }
2707                if (m['T'] == INT) {
2708                        return (m['R'] == LONG);
2709                }
2710                if (m['T'] == SHORT) {
2711                        return (m['R'] == INT);
2712                }
2713                if (m['T'] == BYTE) {
2714                        return (m['R'] == INT);
2715                }
2716                return (m['R'] == FLOAT);
2717        }
2718    ***/
2719        /**
2720         * Compute the sum of values in an array
2721         * 
2722         * @param vector
2723         * @return the sum of all values
2724         */
2725        public static long sumValues(final int[] vector) {
2726                long sum = 0;
2727
2728                for (final int v : vector)
2729                        sum += v;
2730
2731                return sum;
2732        }
2733        
2734        
2735        /*** 
2736        { m -> 
2737                if (m['T'] == DOUBLE) {
2738                        return (m['R'] == DOUBLE);              
2739                }
2740                if (m['T'] == LONG) {
2741                        return (m['R'] == LONG);
2742                }
2743                if (m['T'] == INT) {
2744                        return (m['R'] == LONG);
2745                }
2746                if (m['T'] == SHORT) {
2747                        return (m['R'] == INT);
2748                }
2749                if (m['T'] == BYTE) {
2750                        return (m['R'] == INT);
2751                }
2752                return (m['R'] == FLOAT);
2753        }
2754    ***/
2755        /**
2756         * Compute the sum of values in an array
2757         * 
2758         * @param vector
2759         * @return the sum of all values
2760         */
2761        public static long sumValues(final long[] vector) {
2762                long sum = 0;
2763
2764                for (final long v : vector)
2765                        sum += v;
2766
2767                return sum;
2768        }
2769        
2770        
2771        /*** 
2772        { m -> 
2773                if (m['T'] == DOUBLE) {
2774                        return (m['R'] == DOUBLE);              
2775                }
2776                if (m['T'] == LONG) {
2777                        return (m['R'] == LONG);
2778                }
2779                if (m['T'] == INT) {
2780                        return (m['R'] == LONG);
2781                }
2782                if (m['T'] == SHORT) {
2783                        return (m['R'] == INT);
2784                }
2785                if (m['T'] == BYTE) {
2786                        return (m['R'] == INT);
2787                }
2788                return (m['R'] == FLOAT);
2789        }
2790    ***/
2791        /**
2792         * Compute the sum of values in a 2d array
2793         * 
2794         * @param array
2795         * @return the sum of all values
2796         */
2797        public static double sumValues(final double[][] array) {
2798                double sum = 0;
2799
2800                for (int i=0; i<array.length; i++)
2801                        for (int j=0; j<array[i].length; j++)
2802                                sum += array[i][j];
2803
2804                return sum;
2805        }
2806
2807    
2808        /*** 
2809        { m -> 
2810                if (m['T'] == DOUBLE) {
2811                        return (m['R'] == DOUBLE);              
2812                }
2813                if (m['T'] == LONG) {
2814                        return (m['R'] == LONG);
2815                }
2816                if (m['T'] == INT) {
2817                        return (m['R'] == LONG);
2818                }
2819                if (m['T'] == SHORT) {
2820                        return (m['R'] == INT);
2821                }
2822                if (m['T'] == BYTE) {
2823                        return (m['R'] == INT);
2824                }
2825                return (m['R'] == FLOAT);
2826        }
2827    ***/
2828        /**
2829         * Compute the sum of values in a 2d array
2830         * 
2831         * @param array
2832         * @return the sum of all values
2833         */
2834        public static float sumValues(final float[][] array) {
2835                float sum = 0;
2836
2837                for (int i=0; i<array.length; i++)
2838                        for (int j=0; j<array[i].length; j++)
2839                                sum += array[i][j];
2840
2841                return sum;
2842        }
2843
2844    
2845        /*** 
2846        { m -> 
2847                if (m['T'] == DOUBLE) {
2848                        return (m['R'] == DOUBLE);              
2849                }
2850                if (m['T'] == LONG) {
2851                        return (m['R'] == LONG);
2852                }
2853                if (m['T'] == INT) {
2854                        return (m['R'] == LONG);
2855                }
2856                if (m['T'] == SHORT) {
2857                        return (m['R'] == INT);
2858                }
2859                if (m['T'] == BYTE) {
2860                        return (m['R'] == INT);
2861                }
2862                return (m['R'] == FLOAT);
2863        }
2864    ***/
2865        /**
2866         * Compute the sum of values in a 2d array
2867         * 
2868         * @param array
2869         * @return the sum of all values
2870         */
2871        public static int sumValues(final byte[][] array) {
2872                int sum = 0;
2873
2874                for (int i=0; i<array.length; i++)
2875                        for (int j=0; j<array[i].length; j++)
2876                                sum += array[i][j];
2877
2878                return sum;
2879        }
2880
2881    
2882        /*** 
2883        { m -> 
2884                if (m['T'] == DOUBLE) {
2885                        return (m['R'] == DOUBLE);              
2886                }
2887                if (m['T'] == LONG) {
2888                        return (m['R'] == LONG);
2889                }
2890                if (m['T'] == INT) {
2891                        return (m['R'] == LONG);
2892                }
2893                if (m['T'] == SHORT) {
2894                        return (m['R'] == INT);
2895                }
2896                if (m['T'] == BYTE) {
2897                        return (m['R'] == INT);
2898                }
2899                return (m['R'] == FLOAT);
2900        }
2901    ***/
2902        /**
2903         * Compute the sum of values in a 2d array
2904         * 
2905         * @param array
2906         * @return the sum of all values
2907         */
2908        public static int sumValues(final short[][] array) {
2909                int sum = 0;
2910
2911                for (int i=0; i<array.length; i++)
2912                        for (int j=0; j<array[i].length; j++)
2913                                sum += array[i][j];
2914
2915                return sum;
2916        }
2917
2918    
2919        /*** 
2920        { m -> 
2921                if (m['T'] == DOUBLE) {
2922                        return (m['R'] == DOUBLE);              
2923                }
2924                if (m['T'] == LONG) {
2925                        return (m['R'] == LONG);
2926                }
2927                if (m['T'] == INT) {
2928                        return (m['R'] == LONG);
2929                }
2930                if (m['T'] == SHORT) {
2931                        return (m['R'] == INT);
2932                }
2933                if (m['T'] == BYTE) {
2934                        return (m['R'] == INT);
2935                }
2936                return (m['R'] == FLOAT);
2937        }
2938    ***/
2939        /**
2940         * Compute the sum of values in a 2d array
2941         * 
2942         * @param array
2943         * @return the sum of all values
2944         */
2945        public static long sumValues(final int[][] array) {
2946                long sum = 0;
2947
2948                for (int i=0; i<array.length; i++)
2949                        for (int j=0; j<array[i].length; j++)
2950                                sum += array[i][j];
2951
2952                return sum;
2953        }
2954
2955    
2956        /*** 
2957        { m -> 
2958                if (m['T'] == DOUBLE) {
2959                        return (m['R'] == DOUBLE);              
2960                }
2961                if (m['T'] == LONG) {
2962                        return (m['R'] == LONG);
2963                }
2964                if (m['T'] == INT) {
2965                        return (m['R'] == LONG);
2966                }
2967                if (m['T'] == SHORT) {
2968                        return (m['R'] == INT);
2969                }
2970                if (m['T'] == BYTE) {
2971                        return (m['R'] == INT);
2972                }
2973                return (m['R'] == FLOAT);
2974        }
2975    ***/
2976        /**
2977         * Compute the sum of values in a 2d array
2978         * 
2979         * @param array
2980         * @return the sum of all values
2981         */
2982        public static long sumValues(final long[][] array) {
2983                long sum = 0;
2984
2985                for (int i=0; i<array.length; i++)
2986                        for (int j=0; j<array[i].length; j++)
2987                                sum += array[i][j];
2988
2989                return sum;
2990        }
2991
2992    
2993        /*** 
2994        { m -> 
2995                if (m['T'] == DOUBLE) {
2996                        return (m['R'] == DOUBLE);              
2997                }
2998                if (m['T'] == LONG) {
2999                        return (m['R'] == LONG);
3000                }
3001                if (m['T'] == INT) {
3002                        return (m['R'] == LONG);
3003                }
3004                if (m['T'] == SHORT) {
3005                        return (m['R'] == INT);
3006                }
3007                if (m['T'] == BYTE) {
3008                        return (m['R'] == INT);
3009                }
3010                return (m['R'] == FLOAT);
3011        }
3012    ***/
3013        /**
3014         * Compute the sum of values squared in an array
3015         * 
3016         * @param vector
3017         * @return the sum of all values
3018         */
3019        public static double sumValuesSquared(final double[] vector) {
3020                double sum = 0;
3021
3022                for (final double v : vector)
3023                        sum += v * v;
3024
3025                return sum;
3026        }
3027
3028        
3029        /*** 
3030        { m -> 
3031                if (m['T'] == DOUBLE) {
3032                        return (m['R'] == DOUBLE);              
3033                }
3034                if (m['T'] == LONG) {
3035                        return (m['R'] == LONG);
3036                }
3037                if (m['T'] == INT) {
3038                        return (m['R'] == LONG);
3039                }
3040                if (m['T'] == SHORT) {
3041                        return (m['R'] == INT);
3042                }
3043                if (m['T'] == BYTE) {
3044                        return (m['R'] == INT);
3045                }
3046                return (m['R'] == FLOAT);
3047        }
3048    ***/
3049        /**
3050         * Compute the sum of values squared in an array
3051         * 
3052         * @param vector
3053         * @return the sum of all values
3054         */
3055        public static float sumValuesSquared(final float[] vector) {
3056                float sum = 0;
3057
3058                for (final float v : vector)
3059                        sum += v * v;
3060
3061                return sum;
3062        }
3063
3064        
3065        /*** 
3066        { m -> 
3067                if (m['T'] == DOUBLE) {
3068                        return (m['R'] == DOUBLE);              
3069                }
3070                if (m['T'] == LONG) {
3071                        return (m['R'] == LONG);
3072                }
3073                if (m['T'] == INT) {
3074                        return (m['R'] == LONG);
3075                }
3076                if (m['T'] == SHORT) {
3077                        return (m['R'] == INT);
3078                }
3079                if (m['T'] == BYTE) {
3080                        return (m['R'] == INT);
3081                }
3082                return (m['R'] == FLOAT);
3083        }
3084    ***/
3085        /**
3086         * Compute the sum of values squared in an array
3087         * 
3088         * @param vector
3089         * @return the sum of all values
3090         */
3091        public static int sumValuesSquared(final byte[] vector) {
3092                int sum = 0;
3093
3094                for (final byte v : vector)
3095                        sum += v * v;
3096
3097                return sum;
3098        }
3099
3100        
3101        /*** 
3102        { m -> 
3103                if (m['T'] == DOUBLE) {
3104                        return (m['R'] == DOUBLE);              
3105                }
3106                if (m['T'] == LONG) {
3107                        return (m['R'] == LONG);
3108                }
3109                if (m['T'] == INT) {
3110                        return (m['R'] == LONG);
3111                }
3112                if (m['T'] == SHORT) {
3113                        return (m['R'] == INT);
3114                }
3115                if (m['T'] == BYTE) {
3116                        return (m['R'] == INT);
3117                }
3118                return (m['R'] == FLOAT);
3119        }
3120    ***/
3121        /**
3122         * Compute the sum of values squared in an array
3123         * 
3124         * @param vector
3125         * @return the sum of all values
3126         */
3127        public static int sumValuesSquared(final short[] vector) {
3128                int sum = 0;
3129
3130                for (final short v : vector)
3131                        sum += v * v;
3132
3133                return sum;
3134        }
3135
3136        
3137        /*** 
3138        { m -> 
3139                if (m['T'] == DOUBLE) {
3140                        return (m['R'] == DOUBLE);              
3141                }
3142                if (m['T'] == LONG) {
3143                        return (m['R'] == LONG);
3144                }
3145                if (m['T'] == INT) {
3146                        return (m['R'] == LONG);
3147                }
3148                if (m['T'] == SHORT) {
3149                        return (m['R'] == INT);
3150                }
3151                if (m['T'] == BYTE) {
3152                        return (m['R'] == INT);
3153                }
3154                return (m['R'] == FLOAT);
3155        }
3156    ***/
3157        /**
3158         * Compute the sum of values squared in an array
3159         * 
3160         * @param vector
3161         * @return the sum of all values
3162         */
3163        public static long sumValuesSquared(final int[] vector) {
3164                long sum = 0;
3165
3166                for (final int v : vector)
3167                        sum += v * v;
3168
3169                return sum;
3170        }
3171
3172        
3173        /*** 
3174        { m -> 
3175                if (m['T'] == DOUBLE) {
3176                        return (m['R'] == DOUBLE);              
3177                }
3178                if (m['T'] == LONG) {
3179                        return (m['R'] == LONG);
3180                }
3181                if (m['T'] == INT) {
3182                        return (m['R'] == LONG);
3183                }
3184                if (m['T'] == SHORT) {
3185                        return (m['R'] == INT);
3186                }
3187                if (m['T'] == BYTE) {
3188                        return (m['R'] == INT);
3189                }
3190                return (m['R'] == FLOAT);
3191        }
3192    ***/
3193        /**
3194         * Compute the sum of values squared in an array
3195         * 
3196         * @param vector
3197         * @return the sum of all values
3198         */
3199        public static long sumValuesSquared(final long[] vector) {
3200                long sum = 0;
3201
3202                for (final long v : vector)
3203                        sum += v * v;
3204
3205                return sum;
3206        }
3207
3208        
3209        /*** 
3210        { m -> 
3211                if (m['T'] == DOUBLE) {
3212                        return (m['R'] == DOUBLE);              
3213                }
3214                if (m['T'] == LONG) {
3215                        return (m['R'] == LONG);
3216                }
3217                if (m['T'] == INT) {
3218                        return (m['R'] == LONG);
3219                }
3220                if (m['T'] == SHORT) {
3221                        return (m['R'] == INT);
3222                }
3223                if (m['T'] == BYTE) {
3224                        return (m['R'] == INT);
3225                }
3226                return (m['R'] == FLOAT);
3227        }
3228    ***/
3229        /**
3230         * Compute the cumulative sum of values in an array
3231         * 
3232         * @param vector
3233         * @return the sum of all values
3234         */
3235        public static double[] cumulativeSum(final double[] vector) {
3236                double[] sum = new double[vector.length];
3237
3238                if (vector.length == 0) return sum;
3239
3240                sum[0] = vector[0];
3241                for (int i=1; i<vector.length; i++)
3242                        sum[i] = vector[i] + sum[i-1];
3243
3244                return sum;
3245        }
3246        
3247        
3248        /*** 
3249        { m -> 
3250                if (m['T'] == DOUBLE) {
3251                        return (m['R'] == DOUBLE);              
3252                }
3253                if (m['T'] == LONG) {
3254                        return (m['R'] == LONG);
3255                }
3256                if (m['T'] == INT) {
3257                        return (m['R'] == LONG);
3258                }
3259                if (m['T'] == SHORT) {
3260                        return (m['R'] == INT);
3261                }
3262                if (m['T'] == BYTE) {
3263                        return (m['R'] == INT);
3264                }
3265                return (m['R'] == FLOAT);
3266        }
3267    ***/
3268        /**
3269         * Compute the cumulative sum of values in an array
3270         * 
3271         * @param vector
3272         * @return the sum of all values
3273         */
3274        public static float[] cumulativeSum(final float[] vector) {
3275                float[] sum = new float[vector.length];
3276
3277                if (vector.length == 0) return sum;
3278
3279                sum[0] = vector[0];
3280                for (int i=1; i<vector.length; i++)
3281                        sum[i] = vector[i] + sum[i-1];
3282
3283                return sum;
3284        }
3285        
3286        
3287        /*** 
3288        { m -> 
3289                if (m['T'] == DOUBLE) {
3290                        return (m['R'] == DOUBLE);              
3291                }
3292                if (m['T'] == LONG) {
3293                        return (m['R'] == LONG);
3294                }
3295                if (m['T'] == INT) {
3296                        return (m['R'] == LONG);
3297                }
3298                if (m['T'] == SHORT) {
3299                        return (m['R'] == INT);
3300                }
3301                if (m['T'] == BYTE) {
3302                        return (m['R'] == INT);
3303                }
3304                return (m['R'] == FLOAT);
3305        }
3306    ***/
3307        /**
3308         * Compute the cumulative sum of values in an array
3309         * 
3310         * @param vector
3311         * @return the sum of all values
3312         */
3313        public static int[] cumulativeSum(final byte[] vector) {
3314                int[] sum = new int[vector.length];
3315
3316                if (vector.length == 0) return sum;
3317
3318                sum[0] = vector[0];
3319                for (int i=1; i<vector.length; i++)
3320                        sum[i] = vector[i] + sum[i-1];
3321
3322                return sum;
3323        }
3324        
3325        
3326        /*** 
3327        { m -> 
3328                if (m['T'] == DOUBLE) {
3329                        return (m['R'] == DOUBLE);              
3330                }
3331                if (m['T'] == LONG) {
3332                        return (m['R'] == LONG);
3333                }
3334                if (m['T'] == INT) {
3335                        return (m['R'] == LONG);
3336                }
3337                if (m['T'] == SHORT) {
3338                        return (m['R'] == INT);
3339                }
3340                if (m['T'] == BYTE) {
3341                        return (m['R'] == INT);
3342                }
3343                return (m['R'] == FLOAT);
3344        }
3345    ***/
3346        /**
3347         * Compute the cumulative sum of values in an array
3348         * 
3349         * @param vector
3350         * @return the sum of all values
3351         */
3352        public static int[] cumulativeSum(final short[] vector) {
3353                int[] sum = new int[vector.length];
3354
3355                if (vector.length == 0) return sum;
3356
3357                sum[0] = vector[0];
3358                for (int i=1; i<vector.length; i++)
3359                        sum[i] = vector[i] + sum[i-1];
3360
3361                return sum;
3362        }
3363        
3364        
3365        /*** 
3366        { m -> 
3367                if (m['T'] == DOUBLE) {
3368                        return (m['R'] == DOUBLE);              
3369                }
3370                if (m['T'] == LONG) {
3371                        return (m['R'] == LONG);
3372                }
3373                if (m['T'] == INT) {
3374                        return (m['R'] == LONG);
3375                }
3376                if (m['T'] == SHORT) {
3377                        return (m['R'] == INT);
3378                }
3379                if (m['T'] == BYTE) {
3380                        return (m['R'] == INT);
3381                }
3382                return (m['R'] == FLOAT);
3383        }
3384    ***/
3385        /**
3386         * Compute the cumulative sum of values in an array
3387         * 
3388         * @param vector
3389         * @return the sum of all values
3390         */
3391        public static long[] cumulativeSum(final int[] vector) {
3392                long[] sum = new long[vector.length];
3393
3394                if (vector.length == 0) return sum;
3395
3396                sum[0] = vector[0];
3397                for (int i=1; i<vector.length; i++)
3398                        sum[i] = vector[i] + sum[i-1];
3399
3400                return sum;
3401        }
3402        
3403        
3404        /*** 
3405        { m -> 
3406                if (m['T'] == DOUBLE) {
3407                        return (m['R'] == DOUBLE);              
3408                }
3409                if (m['T'] == LONG) {
3410                        return (m['R'] == LONG);
3411                }
3412                if (m['T'] == INT) {
3413                        return (m['R'] == LONG);
3414                }
3415                if (m['T'] == SHORT) {
3416                        return (m['R'] == INT);
3417                }
3418                if (m['T'] == BYTE) {
3419                        return (m['R'] == INT);
3420                }
3421                return (m['R'] == FLOAT);
3422        }
3423    ***/
3424        /**
3425         * Compute the cumulative sum of values in an array
3426         * 
3427         * @param vector
3428         * @return the sum of all values
3429         */
3430        public static long[] cumulativeSum(final long[] vector) {
3431                long[] sum = new long[vector.length];
3432
3433                if (vector.length == 0) return sum;
3434
3435                sum[0] = vector[0];
3436                for (int i=1; i<vector.length; i++)
3437                        sum[i] = vector[i] + sum[i-1];
3438
3439                return sum;
3440        }
3441        
3442        
3443        /*** 
3444        { m -> 
3445                if (m['T'] == DOUBLE) {
3446                        return (m['R'] == DOUBLE);              
3447                }
3448                if (m['T'] == LONG) {
3449                        return (m['R'] == LONG);
3450                }
3451                if (m['T'] == INT) {
3452                        return (m['R'] == LONG);
3453                }
3454                if (m['T'] == SHORT) {
3455                        return (m['R'] == INT);
3456                }
3457                if (m['T'] == BYTE) {
3458                        return (m['R'] == INT);
3459                }
3460                return (m['R'] == FLOAT);
3461        }
3462    ***/
3463        /**
3464         * Compute the sum of values in each row of a 2d array
3465         * 
3466         * @param array the array 
3467         * @return the sum of each row
3468         */
3469        public static double[] rowSum(final double[][] array) {
3470                double[] sum = new double[array.length];
3471
3472                for (int i=0; i<array.length; i++)
3473                        for (int j=0; j<array[i].length; j++)
3474                                sum[i] += array[i][j];
3475
3476                return sum;
3477        }
3478        
3479        
3480        /*** 
3481        { m -> 
3482                if (m['T'] == DOUBLE) {
3483                        return (m['R'] == DOUBLE);              
3484                }
3485                if (m['T'] == LONG) {
3486                        return (m['R'] == LONG);
3487                }
3488                if (m['T'] == INT) {
3489                        return (m['R'] == LONG);
3490                }
3491                if (m['T'] == SHORT) {
3492                        return (m['R'] == INT);
3493                }
3494                if (m['T'] == BYTE) {
3495                        return (m['R'] == INT);
3496                }
3497                return (m['R'] == FLOAT);
3498        }
3499    ***/
3500        /**
3501         * Compute the sum of values in each row of a 2d array
3502         * 
3503         * @param array the array 
3504         * @return the sum of each row
3505         */
3506        public static float[] rowSum(final float[][] array) {
3507                float[] sum = new float[array.length];
3508
3509                for (int i=0; i<array.length; i++)
3510                        for (int j=0; j<array[i].length; j++)
3511                                sum[i] += array[i][j];
3512
3513                return sum;
3514        }
3515        
3516        
3517        /*** 
3518        { m -> 
3519                if (m['T'] == DOUBLE) {
3520                        return (m['R'] == DOUBLE);              
3521                }
3522                if (m['T'] == LONG) {
3523                        return (m['R'] == LONG);
3524                }
3525                if (m['T'] == INT) {
3526                        return (m['R'] == LONG);
3527                }
3528                if (m['T'] == SHORT) {
3529                        return (m['R'] == INT);
3530                }
3531                if (m['T'] == BYTE) {
3532                        return (m['R'] == INT);
3533                }
3534                return (m['R'] == FLOAT);
3535        }
3536    ***/
3537        /**
3538         * Compute the sum of values in each row of a 2d array
3539         * 
3540         * @param array the array 
3541         * @return the sum of each row
3542         */
3543        public static int[] rowSum(final byte[][] array) {
3544                int[] sum = new int[array.length];
3545
3546                for (int i=0; i<array.length; i++)
3547                        for (int j=0; j<array[i].length; j++)
3548                                sum[i] += array[i][j];
3549
3550                return sum;
3551        }
3552        
3553        
3554        /*** 
3555        { m -> 
3556                if (m['T'] == DOUBLE) {
3557                        return (m['R'] == DOUBLE);              
3558                }
3559                if (m['T'] == LONG) {
3560                        return (m['R'] == LONG);
3561                }
3562                if (m['T'] == INT) {
3563                        return (m['R'] == LONG);
3564                }
3565                if (m['T'] == SHORT) {
3566                        return (m['R'] == INT);
3567                }
3568                if (m['T'] == BYTE) {
3569                        return (m['R'] == INT);
3570                }
3571                return (m['R'] == FLOAT);
3572        }
3573    ***/
3574        /**
3575         * Compute the sum of values in each row of a 2d array
3576         * 
3577         * @param array the array 
3578         * @return the sum of each row
3579         */
3580        public static int[] rowSum(final short[][] array) {
3581                int[] sum = new int[array.length];
3582
3583                for (int i=0; i<array.length; i++)
3584                        for (int j=0; j<array[i].length; j++)
3585                                sum[i] += array[i][j];
3586
3587                return sum;
3588        }
3589        
3590        
3591        /*** 
3592        { m -> 
3593                if (m['T'] == DOUBLE) {
3594                        return (m['R'] == DOUBLE);              
3595                }
3596                if (m['T'] == LONG) {
3597                        return (m['R'] == LONG);
3598                }
3599                if (m['T'] == INT) {
3600                        return (m['R'] == LONG);
3601                }
3602                if (m['T'] == SHORT) {
3603                        return (m['R'] == INT);
3604                }
3605                if (m['T'] == BYTE) {
3606                        return (m['R'] == INT);
3607                }
3608                return (m['R'] == FLOAT);
3609        }
3610    ***/
3611        /**
3612         * Compute the sum of values in each row of a 2d array
3613         * 
3614         * @param array the array 
3615         * @return the sum of each row
3616         */
3617        public static long[] rowSum(final int[][] array) {
3618                long[] sum = new long[array.length];
3619
3620                for (int i=0; i<array.length; i++)
3621                        for (int j=0; j<array[i].length; j++)
3622                                sum[i] += array[i][j];
3623
3624                return sum;
3625        }
3626        
3627        
3628        /*** 
3629        { m -> 
3630                if (m['T'] == DOUBLE) {
3631                        return (m['R'] == DOUBLE);              
3632                }
3633                if (m['T'] == LONG) {
3634                        return (m['R'] == LONG);
3635                }
3636                if (m['T'] == INT) {
3637                        return (m['R'] == LONG);
3638                }
3639                if (m['T'] == SHORT) {
3640                        return (m['R'] == INT);
3641                }
3642                if (m['T'] == BYTE) {
3643                        return (m['R'] == INT);
3644                }
3645                return (m['R'] == FLOAT);
3646        }
3647    ***/
3648        /**
3649         * Compute the sum of values in each row of a 2d array
3650         * 
3651         * @param array the array 
3652         * @return the sum of each row
3653         */
3654        public static long[] rowSum(final long[][] array) {
3655                long[] sum = new long[array.length];
3656
3657                for (int i=0; i<array.length; i++)
3658                        for (int j=0; j<array[i].length; j++)
3659                                sum[i] += array[i][j];
3660
3661                return sum;
3662        }
3663        
3664        
3665        /*** 
3666        { m -> 
3667                if (m['T'] == DOUBLE) {
3668                        return (m['R'] == DOUBLE);              
3669                }
3670                if (m['T'] == LONG) {
3671                        return (m['R'] == LONG);
3672                }
3673                if (m['T'] == INT) {
3674                        return (m['R'] == LONG);
3675                }
3676                if (m['T'] == SHORT) {
3677                        return (m['R'] == INT);
3678                }
3679                if (m['T'] == BYTE) {
3680                        return (m['R'] == INT);
3681                }
3682                return (m['R'] == FLOAT);
3683        }
3684    ***/
3685        /**
3686         * Compute the sum of values in each column of a 2d array
3687         * 
3688         * @param array the array 
3689         * @return the sum of each column
3690         */
3691        public static double[] colSum(final double[][] array) {
3692                double[] sum = new double[array[0].length];
3693
3694                for (int i=0; i<array.length; i++)
3695                        for (int j=0; j<array[0].length; j++)
3696                                sum[j] += array[i][j];
3697
3698                return sum;
3699        }
3700
3701    
3702        /*** 
3703        { m -> 
3704                if (m['T'] == DOUBLE) {
3705                        return (m['R'] == DOUBLE);              
3706                }
3707                if (m['T'] == LONG) {
3708                        return (m['R'] == LONG);
3709                }
3710                if (m['T'] == INT) {
3711                        return (m['R'] == LONG);
3712                }
3713                if (m['T'] == SHORT) {
3714                        return (m['R'] == INT);
3715                }
3716                if (m['T'] == BYTE) {
3717                        return (m['R'] == INT);
3718                }
3719                return (m['R'] == FLOAT);
3720        }
3721    ***/
3722        /**
3723         * Compute the sum of values in each column of a 2d array
3724         * 
3725         * @param array the array 
3726         * @return the sum of each column
3727         */
3728        public static float[] colSum(final float[][] array) {
3729                float[] sum = new float[array[0].length];
3730
3731                for (int i=0; i<array.length; i++)
3732                        for (int j=0; j<array[0].length; j++)
3733                                sum[j] += array[i][j];
3734
3735                return sum;
3736        }
3737
3738    
3739        /*** 
3740        { m -> 
3741                if (m['T'] == DOUBLE) {
3742                        return (m['R'] == DOUBLE);              
3743                }
3744                if (m['T'] == LONG) {
3745                        return (m['R'] == LONG);
3746                }
3747                if (m['T'] == INT) {
3748                        return (m['R'] == LONG);
3749                }
3750                if (m['T'] == SHORT) {
3751                        return (m['R'] == INT);
3752                }
3753                if (m['T'] == BYTE) {
3754                        return (m['R'] == INT);
3755                }
3756                return (m['R'] == FLOAT);
3757        }
3758    ***/
3759        /**
3760         * Compute the sum of values in each column of a 2d array
3761         * 
3762         * @param array the array 
3763         * @return the sum of each column
3764         */
3765        public static int[] colSum(final byte[][] array) {
3766                int[] sum = new int[array[0].length];
3767
3768                for (int i=0; i<array.length; i++)
3769                        for (int j=0; j<array[0].length; j++)
3770                                sum[j] += array[i][j];
3771
3772                return sum;
3773        }
3774
3775    
3776        /*** 
3777        { m -> 
3778                if (m['T'] == DOUBLE) {
3779                        return (m['R'] == DOUBLE);              
3780                }
3781                if (m['T'] == LONG) {
3782                        return (m['R'] == LONG);
3783                }
3784                if (m['T'] == INT) {
3785                        return (m['R'] == LONG);
3786                }
3787                if (m['T'] == SHORT) {
3788                        return (m['R'] == INT);
3789                }
3790                if (m['T'] == BYTE) {
3791                        return (m['R'] == INT);
3792                }
3793                return (m['R'] == FLOAT);
3794        }
3795    ***/
3796        /**
3797         * Compute the sum of values in each column of a 2d array
3798         * 
3799         * @param array the array 
3800         * @return the sum of each column
3801         */
3802        public static int[] colSum(final short[][] array) {
3803                int[] sum = new int[array[0].length];
3804
3805                for (int i=0; i<array.length; i++)
3806                        for (int j=0; j<array[0].length; j++)
3807                                sum[j] += array[i][j];
3808
3809                return sum;
3810        }
3811
3812    
3813        /*** 
3814        { m -> 
3815                if (m['T'] == DOUBLE) {
3816                        return (m['R'] == DOUBLE);              
3817                }
3818                if (m['T'] == LONG) {
3819                        return (m['R'] == LONG);
3820                }
3821                if (m['T'] == INT) {
3822                        return (m['R'] == LONG);
3823                }
3824                if (m['T'] == SHORT) {
3825                        return (m['R'] == INT);
3826                }
3827                if (m['T'] == BYTE) {
3828                        return (m['R'] == INT);
3829                }
3830                return (m['R'] == FLOAT);
3831        }
3832    ***/
3833        /**
3834         * Compute the sum of values in each column of a 2d array
3835         * 
3836         * @param array the array 
3837         * @return the sum of each column
3838         */
3839        public static long[] colSum(final int[][] array) {
3840                long[] sum = new long[array[0].length];
3841
3842                for (int i=0; i<array.length; i++)
3843                        for (int j=0; j<array[0].length; j++)
3844                                sum[j] += array[i][j];
3845
3846                return sum;
3847        }
3848
3849    
3850        /*** 
3851        { m -> 
3852                if (m['T'] == DOUBLE) {
3853                        return (m['R'] == DOUBLE);              
3854                }
3855                if (m['T'] == LONG) {
3856                        return (m['R'] == LONG);
3857                }
3858                if (m['T'] == INT) {
3859                        return (m['R'] == LONG);
3860                }
3861                if (m['T'] == SHORT) {
3862                        return (m['R'] == INT);
3863                }
3864                if (m['T'] == BYTE) {
3865                        return (m['R'] == INT);
3866                }
3867                return (m['R'] == FLOAT);
3868        }
3869    ***/
3870        /**
3871         * Compute the sum of values in each column of a 2d array
3872         * 
3873         * @param array the array 
3874         * @return the sum of each column
3875         */
3876        public static long[] colSum(final long[][] array) {
3877                long[] sum = new long[array[0].length];
3878
3879                for (int i=0; i<array.length; i++)
3880                        for (int j=0; j<array[0].length; j++)
3881                                sum[j] += array[i][j];
3882
3883                return sum;
3884        }
3885
3886    
3887        /**
3888         * Extract a range
3889         * 
3890         * @param start
3891         * @param length
3892         * @return [start...length] (inclusive)
3893         */
3894        public static int[] range(final int start, final int length) {
3895                final int[] range = new int[length - start + 1];
3896                for (int i = start; i <= length; i++) {
3897                        range[i - start] = i;
3898                }
3899                return range;
3900        }
3901
3902    
3903        /**
3904         * Find the given value in the array, and return all indices at which it occurs.
3905         * 
3906         * @param a
3907         *            array to search
3908         * @param value
3909         *                        value to search for
3910         * @return the found values
3911         */
3912        public static int[] search(final double[] a, double value) {
3913                int count = 0;
3914
3915                for (int i = 0; i < a.length; i++)
3916                        if (a[i] == value) 
3917                                count++;
3918                
3919                int [] ret = new int[count];
3920                for (int i = 0, j=0; i < a.length; i++)
3921                        if (a[i] == value) ret[j++] = i;
3922                
3923                return ret;
3924        }
3925
3926    
3927        /**
3928         * Find the given value in the array, and return all indices at which it occurs.
3929         * 
3930         * @param a
3931         *            array to search
3932         * @param value
3933         *                        value to search for
3934         * @return the found values
3935         */
3936        public static int[] search(final float[] a, float value) {
3937                int count = 0;
3938
3939                for (int i = 0; i < a.length; i++)
3940                        if (a[i] == value) 
3941                                count++;
3942                
3943                int [] ret = new int[count];
3944                for (int i = 0, j=0; i < a.length; i++)
3945                        if (a[i] == value) ret[j++] = i;
3946                
3947                return ret;
3948        }
3949
3950    
3951        /**
3952         * Find the given value in the array, and return all indices at which it occurs.
3953         * 
3954         * @param a
3955         *            array to search
3956         * @param value
3957         *                        value to search for
3958         * @return the found values
3959         */
3960        public static int[] search(final int[] a, int value) {
3961                int count = 0;
3962
3963                for (int i = 0; i < a.length; i++)
3964                        if (a[i] == value) 
3965                                count++;
3966                
3967                int [] ret = new int[count];
3968                for (int i = 0, j=0; i < a.length; i++)
3969                        if (a[i] == value) ret[j++] = i;
3970                
3971                return ret;
3972        }
3973
3974    
3975        /**
3976         * Find the given value in the array, and return all indices at which it occurs.
3977         * 
3978         * @param a
3979         *            array to search
3980         * @param value
3981         *                        value to search for
3982         * @return the found values
3983         */
3984        public static int[] search(final long[] a, long value) {
3985                int count = 0;
3986
3987                for (int i = 0; i < a.length; i++)
3988                        if (a[i] == value) 
3989                                count++;
3990                
3991                int [] ret = new int[count];
3992                for (int i = 0, j=0; i < a.length; i++)
3993                        if (a[i] == value) ret[j++] = i;
3994                
3995                return ret;
3996        }
3997
3998    
3999        /**
4000         * Find the given value in the array, and return all indices at which it occurs.
4001         * 
4002         * @param a
4003         *            array to search
4004         * @param value
4005         *                        value to search for
4006         * @return the found values
4007         */
4008        public static int[] search(final byte[] a, byte value) {
4009                int count = 0;
4010
4011                for (int i = 0; i < a.length; i++)
4012                        if (a[i] == value) 
4013                                count++;
4014                
4015                int [] ret = new int[count];
4016                for (int i = 0, j=0; i < a.length; i++)
4017                        if (a[i] == value) ret[j++] = i;
4018                
4019                return ret;
4020        }
4021
4022    
4023        /**
4024         * Find the given value in the array, and return all indices at which it occurs.
4025         * 
4026         * @param a
4027         *            array to search
4028         * @param value
4029         *                        value to search for
4030         * @return the found values
4031         */
4032        public static int[] search(final short[] a, short value) {
4033                int count = 0;
4034
4035                for (int i = 0; i < a.length; i++)
4036                        if (a[i] == value) 
4037                                count++;
4038                
4039                int [] ret = new int[count];
4040                for (int i = 0, j=0; i < a.length; i++)
4041                        if (a[i] == value) ret[j++] = i;
4042                
4043                return ret;
4044        }
4045
4046    
4047        /**
4048         * Reshape a 2D array into a 1D array
4049         * 
4050         * @param a
4051         *            array to reshape
4052         * @return the reshaped array
4053         */
4054        public static double[] reshape(final double[][] a) {
4055                final double[] ret = new double[a.length * a[0].length];
4056
4057                for (int r = 0, i = 0; r < a.length; r++)
4058                        for (int c = 0; c < a[0].length; c++, i++)
4059                                ret[i] = a[r][c];
4060
4061                return ret;
4062        }
4063
4064    
4065        /**
4066         * Reshape a 2D array into a 1D array
4067         * 
4068         * @param a
4069         *            array to reshape
4070         * @return the reshaped array
4071         */
4072        public static float[] reshape(final float[][] a) {
4073                final float[] ret = new float[a.length * a[0].length];
4074
4075                for (int r = 0, i = 0; r < a.length; r++)
4076                        for (int c = 0; c < a[0].length; c++, i++)
4077                                ret[i] = a[r][c];
4078
4079                return ret;
4080        }
4081
4082    
4083        /**
4084         * Reshape a 2D array into a 1D array
4085         * 
4086         * @param a
4087         *            array to reshape
4088         * @return the reshaped array
4089         */
4090        public static int[] reshape(final int[][] a) {
4091                final int[] ret = new int[a.length * a[0].length];
4092
4093                for (int r = 0, i = 0; r < a.length; r++)
4094                        for (int c = 0; c < a[0].length; c++, i++)
4095                                ret[i] = a[r][c];
4096
4097                return ret;
4098        }
4099
4100    
4101        /**
4102         * Reshape a 2D array into a 1D array
4103         * 
4104         * @param a
4105         *            array to reshape
4106         * @return the reshaped array
4107         */
4108        public static long[] reshape(final long[][] a) {
4109                final long[] ret = new long[a.length * a[0].length];
4110
4111                for (int r = 0, i = 0; r < a.length; r++)
4112                        for (int c = 0; c < a[0].length; c++, i++)
4113                                ret[i] = a[r][c];
4114
4115                return ret;
4116        }
4117
4118    
4119        /**
4120         * Reshape a 2D array into a 1D array
4121         * 
4122         * @param a
4123         *            array to reshape
4124         * @return the reshaped array
4125         */
4126        public static byte[] reshape(final byte[][] a) {
4127                final byte[] ret = new byte[a.length * a[0].length];
4128
4129                for (int r = 0, i = 0; r < a.length; r++)
4130                        for (int c = 0; c < a[0].length; c++, i++)
4131                                ret[i] = a[r][c];
4132
4133                return ret;
4134        }
4135
4136    
4137        /**
4138         * Reshape a 2D array into a 1D array
4139         * 
4140         * @param a
4141         *            array to reshape
4142         * @return the reshaped array
4143         */
4144        public static short[] reshape(final short[][] a) {
4145                final short[] ret = new short[a.length * a[0].length];
4146
4147                for (int r = 0, i = 0; r < a.length; r++)
4148                        for (int c = 0; c < a[0].length; c++, i++)
4149                                ret[i] = a[r][c];
4150
4151                return ret;
4152        }
4153
4154    
4155        /**
4156         * Reshape a 2D array into a 1D array of doubles
4157         * 
4158         * @param a
4159         *            array to reshape
4160         * @return the reshaped array
4161         */
4162        public static double[] reshapeDouble(final double[][] a) {
4163                final double[] ret = new double[a.length * a[0].length];
4164
4165                for (int r = 0, i = 0; r < a.length; r++)
4166                        for (int c = 0; c < a[0].length; c++, i++)
4167                                ret[i] = a[r][c];
4168
4169                return ret;
4170        }
4171
4172    
4173        /**
4174         * Reshape a 2D array into a 1D array of doubles
4175         * 
4176         * @param a
4177         *            array to reshape
4178         * @return the reshaped array
4179         */
4180        public static double[] reshapeDouble(final float[][] a) {
4181                final double[] ret = new double[a.length * a[0].length];
4182
4183                for (int r = 0, i = 0; r < a.length; r++)
4184                        for (int c = 0; c < a[0].length; c++, i++)
4185                                ret[i] = a[r][c];
4186
4187                return ret;
4188        }
4189
4190    
4191        /**
4192         * Reshape a 2D array into a 1D array of doubles
4193         * 
4194         * @param a
4195         *            array to reshape
4196         * @return the reshaped array
4197         */
4198        public static double[] reshapeDouble(final int[][] a) {
4199                final double[] ret = new double[a.length * a[0].length];
4200
4201                for (int r = 0, i = 0; r < a.length; r++)
4202                        for (int c = 0; c < a[0].length; c++, i++)
4203                                ret[i] = a[r][c];
4204
4205                return ret;
4206        }
4207
4208    
4209        /**
4210         * Reshape a 2D array into a 1D array of doubles
4211         * 
4212         * @param a
4213         *            array to reshape
4214         * @return the reshaped array
4215         */
4216        public static double[] reshapeDouble(final long[][] a) {
4217                final double[] ret = new double[a.length * a[0].length];
4218
4219                for (int r = 0, i = 0; r < a.length; r++)
4220                        for (int c = 0; c < a[0].length; c++, i++)
4221                                ret[i] = a[r][c];
4222
4223                return ret;
4224        }
4225
4226    
4227        /**
4228         * Reshape a 2D array into a 1D array of doubles
4229         * 
4230         * @param a
4231         *            array to reshape
4232         * @return the reshaped array
4233         */
4234        public static double[] reshapeDouble(final byte[][] a) {
4235                final double[] ret = new double[a.length * a[0].length];
4236
4237                for (int r = 0, i = 0; r < a.length; r++)
4238                        for (int c = 0; c < a[0].length; c++, i++)
4239                                ret[i] = a[r][c];
4240
4241                return ret;
4242        }
4243
4244    
4245        /**
4246         * Reshape a 2D array into a 1D array of doubles
4247         * 
4248         * @param a
4249         *            array to reshape
4250         * @return the reshaped array
4251         */
4252        public static double[] reshapeDouble(final short[][] a) {
4253                final double[] ret = new double[a.length * a[0].length];
4254
4255                for (int r = 0, i = 0; r < a.length; r++)
4256                        for (int c = 0; c < a[0].length; c++, i++)
4257                                ret[i] = a[r][c];
4258
4259                return ret;
4260        }
4261
4262    
4263        /**
4264         * Reshape a 1D array into a 2D array
4265         * 
4266         * @param a
4267         *            array to reshape
4268         * @param out
4269         *            the return array, correctly sized
4270         * @return the reshaped array
4271         */
4272        public static double[][] reshape(final double[] a, final double[][] out) {
4273                for (int r = 0, i = 0; r < out.length; r++)
4274                        for (int c = 0; c < out[0].length; c++, i++)
4275                                out[r][c] = a[i];
4276
4277                return out;
4278        }
4279
4280        /**
4281         * Reshape a 1D array into a 2D array
4282         * 
4283         * @param a
4284         *            array to reshape
4285         * @param width
4286         *            the width of the return array
4287         * @param height
4288         *            the height of the return array
4289         * @return the reshaped array
4290         */
4291        public static double[][] reshape(final double[] a, final int width, final int height) {
4292                final double[][] ret = new double[height][width];
4293                return reshape(a, ret);
4294        }
4295
4296    
4297        /**
4298         * Reshape a 1D array into a 2D array
4299         * 
4300         * @param a
4301         *            array to reshape
4302         * @param out
4303         *            the return array, correctly sized
4304         * @return the reshaped array
4305         */
4306        public static float[][] reshape(final float[] a, final float[][] out) {
4307                for (int r = 0, i = 0; r < out.length; r++)
4308                        for (int c = 0; c < out[0].length; c++, i++)
4309                                out[r][c] = a[i];
4310
4311                return out;
4312        }
4313
4314        /**
4315         * Reshape a 1D array into a 2D array
4316         * 
4317         * @param a
4318         *            array to reshape
4319         * @param width
4320         *            the width of the return array
4321         * @param height
4322         *            the height of the return array
4323         * @return the reshaped array
4324         */
4325        public static float[][] reshape(final float[] a, final int width, final int height) {
4326                final float[][] ret = new float[height][width];
4327                return reshape(a, ret);
4328        }
4329
4330    
4331        /**
4332         * Reshape a 1D array into a 2D array
4333         * 
4334         * @param a
4335         *            array to reshape
4336         * @param out
4337         *            the return array, correctly sized
4338         * @return the reshaped array
4339         */
4340        public static int[][] reshape(final int[] a, final int[][] out) {
4341                for (int r = 0, i = 0; r < out.length; r++)
4342                        for (int c = 0; c < out[0].length; c++, i++)
4343                                out[r][c] = a[i];
4344
4345                return out;
4346        }
4347
4348        /**
4349         * Reshape a 1D array into a 2D array
4350         * 
4351         * @param a
4352         *            array to reshape
4353         * @param width
4354         *            the width of the return array
4355         * @param height
4356         *            the height of the return array
4357         * @return the reshaped array
4358         */
4359        public static int[][] reshape(final int[] a, final int width, final int height) {
4360                final int[][] ret = new int[height][width];
4361                return reshape(a, ret);
4362        }
4363
4364    
4365        /**
4366         * Reshape a 1D array into a 2D array
4367         * 
4368         * @param a
4369         *            array to reshape
4370         * @param out
4371         *            the return array, correctly sized
4372         * @return the reshaped array
4373         */
4374        public static long[][] reshape(final long[] a, final long[][] out) {
4375                for (int r = 0, i = 0; r < out.length; r++)
4376                        for (int c = 0; c < out[0].length; c++, i++)
4377                                out[r][c] = a[i];
4378
4379                return out;
4380        }
4381
4382        /**
4383         * Reshape a 1D array into a 2D array
4384         * 
4385         * @param a
4386         *            array to reshape
4387         * @param width
4388         *            the width of the return array
4389         * @param height
4390         *            the height of the return array
4391         * @return the reshaped array
4392         */
4393        public static long[][] reshape(final long[] a, final int width, final int height) {
4394                final long[][] ret = new long[height][width];
4395                return reshape(a, ret);
4396        }
4397
4398    
4399        /**
4400         * Reshape a 1D array into a 2D array
4401         * 
4402         * @param a
4403         *            array to reshape
4404         * @param out
4405         *            the return array, correctly sized
4406         * @return the reshaped array
4407         */
4408        public static byte[][] reshape(final byte[] a, final byte[][] out) {
4409                for (int r = 0, i = 0; r < out.length; r++)
4410                        for (int c = 0; c < out[0].length; c++, i++)
4411                                out[r][c] = a[i];
4412
4413                return out;
4414        }
4415
4416        /**
4417         * Reshape a 1D array into a 2D array
4418         * 
4419         * @param a
4420         *            array to reshape
4421         * @param width
4422         *            the width of the return array
4423         * @param height
4424         *            the height of the return array
4425         * @return the reshaped array
4426         */
4427        public static byte[][] reshape(final byte[] a, final int width, final int height) {
4428                final byte[][] ret = new byte[height][width];
4429                return reshape(a, ret);
4430        }
4431
4432    
4433        /**
4434         * Reshape a 1D array into a 2D array
4435         * 
4436         * @param a
4437         *            array to reshape
4438         * @param out
4439         *            the return array, correctly sized
4440         * @return the reshaped array
4441         */
4442        public static short[][] reshape(final short[] a, final short[][] out) {
4443                for (int r = 0, i = 0; r < out.length; r++)
4444                        for (int c = 0; c < out[0].length; c++, i++)
4445                                out[r][c] = a[i];
4446
4447                return out;
4448        }
4449
4450        /**
4451         * Reshape a 1D array into a 2D array
4452         * 
4453         * @param a
4454         *            array to reshape
4455         * @param width
4456         *            the width of the return array
4457         * @param height
4458         *            the height of the return array
4459         * @return the reshaped array
4460         */
4461        public static short[][] reshape(final short[] a, final int width, final int height) {
4462                final short[][] ret = new short[height][width];
4463                return reshape(a, ret);
4464        }
4465
4466    
4467        /**
4468         * Reshape a 1D array into a 2D array
4469         * 
4470         * @param a
4471         *            array to reshape
4472         * @param out
4473         *            the return array, correctly sized
4474         * @return the reshaped array
4475         */
4476        public static float[][] reshapeFloat(final double[] a, final float[][] out) {
4477                for (int r = 0, i = 0; r < out.length; r++)
4478                        for (int c = 0; c < out[0].length; c++, i++)
4479                                out[r][c] = (float) a[i];
4480
4481                return out;
4482        }
4483
4484        /**
4485         * Reshape a 1D array into a 2D array
4486         * 
4487         * @param a
4488         *            array to reshape
4489         * @param width
4490         *            the width of the return array
4491         * @param height
4492         *            the height of the return array
4493         * @return the reshaped array
4494         */
4495        public static float[][] reshapeFloat(final double[] a, final int width, final int height) {
4496                final float[][] ret = new float[height][width];
4497                return reshapeFloat(a, ret);
4498        }
4499
4500    
4501        /**
4502         * Sort parallel arrays. Arrays are sorted in-place. The first array
4503         * determines the order, and is sorted into descending order.
4504         * <p>
4505         * Implementation inspired by this stackoverflow page: <a href=
4506         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
4507         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
4508         * get-a-sorted-list-of-indices-of-an-array </a>
4509         * 
4510         * @param main
4511         *            the values to use for determining the order
4512         * @param indices
4513         *            the second array
4514         */
4515        public static void parallelQuicksortDescending(final double[] main, final double[] indices) {
4516                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
4517        }
4518
4519        /**
4520         * Sort parallel arrays. Arrays are sorted in-place. The first array
4521         * determines the order, and is sorted into descending order.
4522         * <p>
4523         * Implementation inspired by this stackoverflow page: <a href=
4524         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
4525         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
4526         * get-a-sorted-list-of-indices-of-an-array </a>
4527         * 
4528         * @param main
4529         *            the values to use for determining the order
4530         * @param indices
4531         *            the second array
4532         * @param left
4533         *            the starting index
4534         * @param right
4535         *            the ending index
4536         */
4537        public static void parallelQuicksortDescending(final double[] main, final double[] indices, final int left,
4538                        final int right)
4539        {
4540                if (right <= left)
4541                        return;
4542
4543                final int i = partitionDesc(main, indices, left, right);
4544
4545                parallelQuicksortDescending(main, indices, left, i - 1);
4546                parallelQuicksortDescending(main, indices, i + 1, right);
4547        }
4548
4549        // partition a[left] to a[right], assumes left < right
4550        private static int partitionDesc(final double[] a, final double[] index, final int left, final int right) {
4551                int i = left - 1;
4552                int j = right;
4553                while (true) {
4554                        while (a[++i] > a[right])
4555                                // find item on left to swap
4556                                ; // a[right] acts as sentinel
4557                        while (a[right] > a[--j])
4558                                // find item on right to swap
4559                                if (j == left)
4560                                        break; // don't go out-of-bounds
4561                        if (i >= j)
4562                                break; // check if pointers cross
4563                        exch(a, index, i, j); // swap two elements into place
4564                }
4565                exch(a, index, i, right); // swap with partition element
4566                return i;
4567        }
4568        
4569        
4570        /**
4571         * Sort parallel arrays. Arrays are sorted in-place. The first array
4572         * determines the order, and is sorted into descending order.
4573         * <p>
4574         * Implementation inspired by this stackoverflow page: <a href=
4575         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
4576         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
4577         * get-a-sorted-list-of-indices-of-an-array </a>
4578         * 
4579         * @param main
4580         *            the values to use for determining the order
4581         * @param indices
4582         *            the second array
4583         */
4584        public static void parallelQuicksortDescending(final float[] main, final double[] indices) {
4585                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
4586        }
4587
4588        /**
4589         * Sort parallel arrays. Arrays are sorted in-place. The first array
4590         * determines the order, and is sorted into descending order.
4591         * <p>
4592         * Implementation inspired by this stackoverflow page: <a href=
4593         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
4594         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
4595         * get-a-sorted-list-of-indices-of-an-array </a>
4596         * 
4597         * @param main
4598         *            the values to use for determining the order
4599         * @param indices
4600         *            the second array
4601         * @param left
4602         *            the starting index
4603         * @param right
4604         *            the ending index
4605         */
4606        public static void parallelQuicksortDescending(final float[] main, final double[] indices, final int left,
4607                        final int right)
4608        {
4609                if (right <= left)
4610                        return;
4611
4612                final int i = partitionDesc(main, indices, left, right);
4613
4614                parallelQuicksortDescending(main, indices, left, i - 1);
4615                parallelQuicksortDescending(main, indices, i + 1, right);
4616        }
4617
4618        // partition a[left] to a[right], assumes left < right
4619        private static int partitionDesc(final float[] a, final double[] index, final int left, final int right) {
4620                int i = left - 1;
4621                int j = right;
4622                while (true) {
4623                        while (a[++i] > a[right])
4624                                // find item on left to swap
4625                                ; // a[right] acts as sentinel
4626                        while (a[right] > a[--j])
4627                                // find item on right to swap
4628                                if (j == left)
4629                                        break; // don't go out-of-bounds
4630                        if (i >= j)
4631                                break; // check if pointers cross
4632                        exch(a, index, i, j); // swap two elements into place
4633                }
4634                exch(a, index, i, right); // swap with partition element
4635                return i;
4636        }
4637        
4638        
4639        /**
4640         * Sort parallel arrays. Arrays are sorted in-place. The first array
4641         * determines the order, and is sorted into descending order.
4642         * <p>
4643         * Implementation inspired by this stackoverflow page: <a href=
4644         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
4645         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
4646         * get-a-sorted-list-of-indices-of-an-array </a>
4647         * 
4648         * @param main
4649         *            the values to use for determining the order
4650         * @param indices
4651         *            the second array
4652         */
4653        public static void parallelQuicksortDescending(final int[] main, final double[] indices) {
4654                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
4655        }
4656
4657        /**
4658         * Sort parallel arrays. Arrays are sorted in-place. The first array
4659         * determines the order, and is sorted into descending order.
4660         * <p>
4661         * Implementation inspired by this stackoverflow page: <a href=
4662         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
4663         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
4664         * get-a-sorted-list-of-indices-of-an-array </a>
4665         * 
4666         * @param main
4667         *            the values to use for determining the order
4668         * @param indices
4669         *            the second array
4670         * @param left
4671         *            the starting index
4672         * @param right
4673         *            the ending index
4674         */
4675        public static void parallelQuicksortDescending(final int[] main, final double[] indices, final int left,
4676                        final int right)
4677        {
4678                if (right <= left)
4679                        return;
4680
4681                final int i = partitionDesc(main, indices, left, right);
4682
4683                parallelQuicksortDescending(main, indices, left, i - 1);
4684                parallelQuicksortDescending(main, indices, i + 1, right);
4685        }
4686
4687        // partition a[left] to a[right], assumes left < right
4688        private static int partitionDesc(final int[] a, final double[] index, final int left, final int right) {
4689                int i = left - 1;
4690                int j = right;
4691                while (true) {
4692                        while (a[++i] > a[right])
4693                                // find item on left to swap
4694                                ; // a[right] acts as sentinel
4695                        while (a[right] > a[--j])
4696                                // find item on right to swap
4697                                if (j == left)
4698                                        break; // don't go out-of-bounds
4699                        if (i >= j)
4700                                break; // check if pointers cross
4701                        exch(a, index, i, j); // swap two elements into place
4702                }
4703                exch(a, index, i, right); // swap with partition element
4704                return i;
4705        }
4706        
4707        
4708        /**
4709         * Sort parallel arrays. Arrays are sorted in-place. The first array
4710         * determines the order, and is sorted into descending order.
4711         * <p>
4712         * Implementation inspired by this stackoverflow page: <a href=
4713         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
4714         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
4715         * get-a-sorted-list-of-indices-of-an-array </a>
4716         * 
4717         * @param main
4718         *            the values to use for determining the order
4719         * @param indices
4720         *            the second array
4721         */
4722        public static void parallelQuicksortDescending(final long[] main, final double[] indices) {
4723                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
4724        }
4725
4726        /**
4727         * Sort parallel arrays. Arrays are sorted in-place. The first array
4728         * determines the order, and is sorted into descending order.
4729         * <p>
4730         * Implementation inspired by this stackoverflow page: <a href=
4731         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
4732         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
4733         * get-a-sorted-list-of-indices-of-an-array </a>
4734         * 
4735         * @param main
4736         *            the values to use for determining the order
4737         * @param indices
4738         *            the second array
4739         * @param left
4740         *            the starting index
4741         * @param right
4742         *            the ending index
4743         */
4744        public static void parallelQuicksortDescending(final long[] main, final double[] indices, final int left,
4745                        final int right)
4746        {
4747                if (right <= left)
4748                        return;
4749
4750                final int i = partitionDesc(main, indices, left, right);
4751
4752                parallelQuicksortDescending(main, indices, left, i - 1);
4753                parallelQuicksortDescending(main, indices, i + 1, right);
4754        }
4755
4756        // partition a[left] to a[right], assumes left < right
4757        private static int partitionDesc(final long[] a, final double[] index, final int left, final int right) {
4758                int i = left - 1;
4759                int j = right;
4760                while (true) {
4761                        while (a[++i] > a[right])
4762                                // find item on left to swap
4763                                ; // a[right] acts as sentinel
4764                        while (a[right] > a[--j])
4765                                // find item on right to swap
4766                                if (j == left)
4767                                        break; // don't go out-of-bounds
4768                        if (i >= j)
4769                                break; // check if pointers cross
4770                        exch(a, index, i, j); // swap two elements into place
4771                }
4772                exch(a, index, i, right); // swap with partition element
4773                return i;
4774        }
4775        
4776        
4777        /**
4778         * Sort parallel arrays. Arrays are sorted in-place. The first array
4779         * determines the order, and is sorted into descending order.
4780         * <p>
4781         * Implementation inspired by this stackoverflow page: <a href=
4782         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
4783         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
4784         * get-a-sorted-list-of-indices-of-an-array </a>
4785         * 
4786         * @param main
4787         *            the values to use for determining the order
4788         * @param indices
4789         *            the second array
4790         */
4791        public static void parallelQuicksortDescending(final byte[] main, final double[] indices) {
4792                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
4793        }
4794
4795        /**
4796         * Sort parallel arrays. Arrays are sorted in-place. The first array
4797         * determines the order, and is sorted into descending order.
4798         * <p>
4799         * Implementation inspired by this stackoverflow page: <a href=
4800         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
4801         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
4802         * get-a-sorted-list-of-indices-of-an-array </a>
4803         * 
4804         * @param main
4805         *            the values to use for determining the order
4806         * @param indices
4807         *            the second array
4808         * @param left
4809         *            the starting index
4810         * @param right
4811         *            the ending index
4812         */
4813        public static void parallelQuicksortDescending(final byte[] main, final double[] indices, final int left,
4814                        final int right)
4815        {
4816                if (right <= left)
4817                        return;
4818
4819                final int i = partitionDesc(main, indices, left, right);
4820
4821                parallelQuicksortDescending(main, indices, left, i - 1);
4822                parallelQuicksortDescending(main, indices, i + 1, right);
4823        }
4824
4825        // partition a[left] to a[right], assumes left < right
4826        private static int partitionDesc(final byte[] a, final double[] index, final int left, final int right) {
4827                int i = left - 1;
4828                int j = right;
4829                while (true) {
4830                        while (a[++i] > a[right])
4831                                // find item on left to swap
4832                                ; // a[right] acts as sentinel
4833                        while (a[right] > a[--j])
4834                                // find item on right to swap
4835                                if (j == left)
4836                                        break; // don't go out-of-bounds
4837                        if (i >= j)
4838                                break; // check if pointers cross
4839                        exch(a, index, i, j); // swap two elements into place
4840                }
4841                exch(a, index, i, right); // swap with partition element
4842                return i;
4843        }
4844        
4845        
4846        /**
4847         * Sort parallel arrays. Arrays are sorted in-place. The first array
4848         * determines the order, and is sorted into descending order.
4849         * <p>
4850         * Implementation inspired by this stackoverflow page: <a href=
4851         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
4852         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
4853         * get-a-sorted-list-of-indices-of-an-array </a>
4854         * 
4855         * @param main
4856         *            the values to use for determining the order
4857         * @param indices
4858         *            the second array
4859         */
4860        public static void parallelQuicksortDescending(final short[] main, final double[] indices) {
4861                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
4862        }
4863
4864        /**
4865         * Sort parallel arrays. Arrays are sorted in-place. The first array
4866         * determines the order, and is sorted into descending order.
4867         * <p>
4868         * Implementation inspired by this stackoverflow page: <a href=
4869         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
4870         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
4871         * get-a-sorted-list-of-indices-of-an-array </a>
4872         * 
4873         * @param main
4874         *            the values to use for determining the order
4875         * @param indices
4876         *            the second array
4877         * @param left
4878         *            the starting index
4879         * @param right
4880         *            the ending index
4881         */
4882        public static void parallelQuicksortDescending(final short[] main, final double[] indices, final int left,
4883                        final int right)
4884        {
4885                if (right <= left)
4886                        return;
4887
4888                final int i = partitionDesc(main, indices, left, right);
4889
4890                parallelQuicksortDescending(main, indices, left, i - 1);
4891                parallelQuicksortDescending(main, indices, i + 1, right);
4892        }
4893
4894        // partition a[left] to a[right], assumes left < right
4895        private static int partitionDesc(final short[] a, final double[] index, final int left, final int right) {
4896                int i = left - 1;
4897                int j = right;
4898                while (true) {
4899                        while (a[++i] > a[right])
4900                                // find item on left to swap
4901                                ; // a[right] acts as sentinel
4902                        while (a[right] > a[--j])
4903                                // find item on right to swap
4904                                if (j == left)
4905                                        break; // don't go out-of-bounds
4906                        if (i >= j)
4907                                break; // check if pointers cross
4908                        exch(a, index, i, j); // swap two elements into place
4909                }
4910                exch(a, index, i, right); // swap with partition element
4911                return i;
4912        }
4913        
4914        
4915        /**
4916         * Sort parallel arrays. Arrays are sorted in-place. The first array
4917         * determines the order, and is sorted into descending order.
4918         * <p>
4919         * Implementation inspired by this stackoverflow page: <a href=
4920         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
4921         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
4922         * get-a-sorted-list-of-indices-of-an-array </a>
4923         * 
4924         * @param main
4925         *            the values to use for determining the order
4926         * @param indices
4927         *            the second array
4928         */
4929        public static void parallelQuicksortDescending(final double[] main, final float[] indices) {
4930                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
4931        }
4932
4933        /**
4934         * Sort parallel arrays. Arrays are sorted in-place. The first array
4935         * determines the order, and is sorted into descending order.
4936         * <p>
4937         * Implementation inspired by this stackoverflow page: <a href=
4938         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
4939         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
4940         * get-a-sorted-list-of-indices-of-an-array </a>
4941         * 
4942         * @param main
4943         *            the values to use for determining the order
4944         * @param indices
4945         *            the second array
4946         * @param left
4947         *            the starting index
4948         * @param right
4949         *            the ending index
4950         */
4951        public static void parallelQuicksortDescending(final double[] main, final float[] indices, final int left,
4952                        final int right)
4953        {
4954                if (right <= left)
4955                        return;
4956
4957                final int i = partitionDesc(main, indices, left, right);
4958
4959                parallelQuicksortDescending(main, indices, left, i - 1);
4960                parallelQuicksortDescending(main, indices, i + 1, right);
4961        }
4962
4963        // partition a[left] to a[right], assumes left < right
4964        private static int partitionDesc(final double[] a, final float[] index, final int left, final int right) {
4965                int i = left - 1;
4966                int j = right;
4967                while (true) {
4968                        while (a[++i] > a[right])
4969                                // find item on left to swap
4970                                ; // a[right] acts as sentinel
4971                        while (a[right] > a[--j])
4972                                // find item on right to swap
4973                                if (j == left)
4974                                        break; // don't go out-of-bounds
4975                        if (i >= j)
4976                                break; // check if pointers cross
4977                        exch(a, index, i, j); // swap two elements into place
4978                }
4979                exch(a, index, i, right); // swap with partition element
4980                return i;
4981        }
4982        
4983        
4984        /**
4985         * Sort parallel arrays. Arrays are sorted in-place. The first array
4986         * determines the order, and is sorted into descending order.
4987         * <p>
4988         * Implementation inspired by this stackoverflow page: <a href=
4989         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
4990         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
4991         * get-a-sorted-list-of-indices-of-an-array </a>
4992         * 
4993         * @param main
4994         *            the values to use for determining the order
4995         * @param indices
4996         *            the second array
4997         */
4998        public static void parallelQuicksortDescending(final float[] main, final float[] indices) {
4999                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
5000        }
5001
5002        /**
5003         * Sort parallel arrays. Arrays are sorted in-place. The first array
5004         * determines the order, and is sorted into descending order.
5005         * <p>
5006         * Implementation inspired by this stackoverflow page: <a href=
5007         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5008         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5009         * get-a-sorted-list-of-indices-of-an-array </a>
5010         * 
5011         * @param main
5012         *            the values to use for determining the order
5013         * @param indices
5014         *            the second array
5015         * @param left
5016         *            the starting index
5017         * @param right
5018         *            the ending index
5019         */
5020        public static void parallelQuicksortDescending(final float[] main, final float[] indices, final int left,
5021                        final int right)
5022        {
5023                if (right <= left)
5024                        return;
5025
5026                final int i = partitionDesc(main, indices, left, right);
5027
5028                parallelQuicksortDescending(main, indices, left, i - 1);
5029                parallelQuicksortDescending(main, indices, i + 1, right);
5030        }
5031
5032        // partition a[left] to a[right], assumes left < right
5033        private static int partitionDesc(final float[] a, final float[] index, final int left, final int right) {
5034                int i = left - 1;
5035                int j = right;
5036                while (true) {
5037                        while (a[++i] > a[right])
5038                                // find item on left to swap
5039                                ; // a[right] acts as sentinel
5040                        while (a[right] > a[--j])
5041                                // find item on right to swap
5042                                if (j == left)
5043                                        break; // don't go out-of-bounds
5044                        if (i >= j)
5045                                break; // check if pointers cross
5046                        exch(a, index, i, j); // swap two elements into place
5047                }
5048                exch(a, index, i, right); // swap with partition element
5049                return i;
5050        }
5051        
5052        
5053        /**
5054         * Sort parallel arrays. Arrays are sorted in-place. The first array
5055         * determines the order, and is sorted into descending order.
5056         * <p>
5057         * Implementation inspired by this stackoverflow page: <a href=
5058         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5059         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5060         * get-a-sorted-list-of-indices-of-an-array </a>
5061         * 
5062         * @param main
5063         *            the values to use for determining the order
5064         * @param indices
5065         *            the second array
5066         */
5067        public static void parallelQuicksortDescending(final int[] main, final float[] indices) {
5068                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
5069        }
5070
5071        /**
5072         * Sort parallel arrays. Arrays are sorted in-place. The first array
5073         * determines the order, and is sorted into descending order.
5074         * <p>
5075         * Implementation inspired by this stackoverflow page: <a href=
5076         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5077         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5078         * get-a-sorted-list-of-indices-of-an-array </a>
5079         * 
5080         * @param main
5081         *            the values to use for determining the order
5082         * @param indices
5083         *            the second array
5084         * @param left
5085         *            the starting index
5086         * @param right
5087         *            the ending index
5088         */
5089        public static void parallelQuicksortDescending(final int[] main, final float[] indices, final int left,
5090                        final int right)
5091        {
5092                if (right <= left)
5093                        return;
5094
5095                final int i = partitionDesc(main, indices, left, right);
5096
5097                parallelQuicksortDescending(main, indices, left, i - 1);
5098                parallelQuicksortDescending(main, indices, i + 1, right);
5099        }
5100
5101        // partition a[left] to a[right], assumes left < right
5102        private static int partitionDesc(final int[] a, final float[] index, final int left, final int right) {
5103                int i = left - 1;
5104                int j = right;
5105                while (true) {
5106                        while (a[++i] > a[right])
5107                                // find item on left to swap
5108                                ; // a[right] acts as sentinel
5109                        while (a[right] > a[--j])
5110                                // find item on right to swap
5111                                if (j == left)
5112                                        break; // don't go out-of-bounds
5113                        if (i >= j)
5114                                break; // check if pointers cross
5115                        exch(a, index, i, j); // swap two elements into place
5116                }
5117                exch(a, index, i, right); // swap with partition element
5118                return i;
5119        }
5120        
5121        
5122        /**
5123         * Sort parallel arrays. Arrays are sorted in-place. The first array
5124         * determines the order, and is sorted into descending order.
5125         * <p>
5126         * Implementation inspired by this stackoverflow page: <a href=
5127         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5128         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5129         * get-a-sorted-list-of-indices-of-an-array </a>
5130         * 
5131         * @param main
5132         *            the values to use for determining the order
5133         * @param indices
5134         *            the second array
5135         */
5136        public static void parallelQuicksortDescending(final long[] main, final float[] indices) {
5137                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
5138        }
5139
5140        /**
5141         * Sort parallel arrays. Arrays are sorted in-place. The first array
5142         * determines the order, and is sorted into descending order.
5143         * <p>
5144         * Implementation inspired by this stackoverflow page: <a href=
5145         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5146         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5147         * get-a-sorted-list-of-indices-of-an-array </a>
5148         * 
5149         * @param main
5150         *            the values to use for determining the order
5151         * @param indices
5152         *            the second array
5153         * @param left
5154         *            the starting index
5155         * @param right
5156         *            the ending index
5157         */
5158        public static void parallelQuicksortDescending(final long[] main, final float[] indices, final int left,
5159                        final int right)
5160        {
5161                if (right <= left)
5162                        return;
5163
5164                final int i = partitionDesc(main, indices, left, right);
5165
5166                parallelQuicksortDescending(main, indices, left, i - 1);
5167                parallelQuicksortDescending(main, indices, i + 1, right);
5168        }
5169
5170        // partition a[left] to a[right], assumes left < right
5171        private static int partitionDesc(final long[] a, final float[] index, final int left, final int right) {
5172                int i = left - 1;
5173                int j = right;
5174                while (true) {
5175                        while (a[++i] > a[right])
5176                                // find item on left to swap
5177                                ; // a[right] acts as sentinel
5178                        while (a[right] > a[--j])
5179                                // find item on right to swap
5180                                if (j == left)
5181                                        break; // don't go out-of-bounds
5182                        if (i >= j)
5183                                break; // check if pointers cross
5184                        exch(a, index, i, j); // swap two elements into place
5185                }
5186                exch(a, index, i, right); // swap with partition element
5187                return i;
5188        }
5189        
5190        
5191        /**
5192         * Sort parallel arrays. Arrays are sorted in-place. The first array
5193         * determines the order, and is sorted into descending order.
5194         * <p>
5195         * Implementation inspired by this stackoverflow page: <a href=
5196         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5197         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5198         * get-a-sorted-list-of-indices-of-an-array </a>
5199         * 
5200         * @param main
5201         *            the values to use for determining the order
5202         * @param indices
5203         *            the second array
5204         */
5205        public static void parallelQuicksortDescending(final byte[] main, final float[] indices) {
5206                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
5207        }
5208
5209        /**
5210         * Sort parallel arrays. Arrays are sorted in-place. The first array
5211         * determines the order, and is sorted into descending order.
5212         * <p>
5213         * Implementation inspired by this stackoverflow page: <a href=
5214         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5215         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5216         * get-a-sorted-list-of-indices-of-an-array </a>
5217         * 
5218         * @param main
5219         *            the values to use for determining the order
5220         * @param indices
5221         *            the second array
5222         * @param left
5223         *            the starting index
5224         * @param right
5225         *            the ending index
5226         */
5227        public static void parallelQuicksortDescending(final byte[] main, final float[] indices, final int left,
5228                        final int right)
5229        {
5230                if (right <= left)
5231                        return;
5232
5233                final int i = partitionDesc(main, indices, left, right);
5234
5235                parallelQuicksortDescending(main, indices, left, i - 1);
5236                parallelQuicksortDescending(main, indices, i + 1, right);
5237        }
5238
5239        // partition a[left] to a[right], assumes left < right
5240        private static int partitionDesc(final byte[] a, final float[] index, final int left, final int right) {
5241                int i = left - 1;
5242                int j = right;
5243                while (true) {
5244                        while (a[++i] > a[right])
5245                                // find item on left to swap
5246                                ; // a[right] acts as sentinel
5247                        while (a[right] > a[--j])
5248                                // find item on right to swap
5249                                if (j == left)
5250                                        break; // don't go out-of-bounds
5251                        if (i >= j)
5252                                break; // check if pointers cross
5253                        exch(a, index, i, j); // swap two elements into place
5254                }
5255                exch(a, index, i, right); // swap with partition element
5256                return i;
5257        }
5258        
5259        
5260        /**
5261         * Sort parallel arrays. Arrays are sorted in-place. The first array
5262         * determines the order, and is sorted into descending order.
5263         * <p>
5264         * Implementation inspired by this stackoverflow page: <a href=
5265         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5266         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5267         * get-a-sorted-list-of-indices-of-an-array </a>
5268         * 
5269         * @param main
5270         *            the values to use for determining the order
5271         * @param indices
5272         *            the second array
5273         */
5274        public static void parallelQuicksortDescending(final short[] main, final float[] indices) {
5275                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
5276        }
5277
5278        /**
5279         * Sort parallel arrays. Arrays are sorted in-place. The first array
5280         * determines the order, and is sorted into descending order.
5281         * <p>
5282         * Implementation inspired by this stackoverflow page: <a href=
5283         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5284         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5285         * get-a-sorted-list-of-indices-of-an-array </a>
5286         * 
5287         * @param main
5288         *            the values to use for determining the order
5289         * @param indices
5290         *            the second array
5291         * @param left
5292         *            the starting index
5293         * @param right
5294         *            the ending index
5295         */
5296        public static void parallelQuicksortDescending(final short[] main, final float[] indices, final int left,
5297                        final int right)
5298        {
5299                if (right <= left)
5300                        return;
5301
5302                final int i = partitionDesc(main, indices, left, right);
5303
5304                parallelQuicksortDescending(main, indices, left, i - 1);
5305                parallelQuicksortDescending(main, indices, i + 1, right);
5306        }
5307
5308        // partition a[left] to a[right], assumes left < right
5309        private static int partitionDesc(final short[] a, final float[] index, final int left, final int right) {
5310                int i = left - 1;
5311                int j = right;
5312                while (true) {
5313                        while (a[++i] > a[right])
5314                                // find item on left to swap
5315                                ; // a[right] acts as sentinel
5316                        while (a[right] > a[--j])
5317                                // find item on right to swap
5318                                if (j == left)
5319                                        break; // don't go out-of-bounds
5320                        if (i >= j)
5321                                break; // check if pointers cross
5322                        exch(a, index, i, j); // swap two elements into place
5323                }
5324                exch(a, index, i, right); // swap with partition element
5325                return i;
5326        }
5327        
5328        
5329        /**
5330         * Sort parallel arrays. Arrays are sorted in-place. The first array
5331         * determines the order, and is sorted into descending order.
5332         * <p>
5333         * Implementation inspired by this stackoverflow page: <a href=
5334         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5335         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5336         * get-a-sorted-list-of-indices-of-an-array </a>
5337         * 
5338         * @param main
5339         *            the values to use for determining the order
5340         * @param indices
5341         *            the second array
5342         */
5343        public static void parallelQuicksortDescending(final double[] main, final int[] indices) {
5344                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
5345        }
5346
5347        /**
5348         * Sort parallel arrays. Arrays are sorted in-place. The first array
5349         * determines the order, and is sorted into descending order.
5350         * <p>
5351         * Implementation inspired by this stackoverflow page: <a href=
5352         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5353         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5354         * get-a-sorted-list-of-indices-of-an-array </a>
5355         * 
5356         * @param main
5357         *            the values to use for determining the order
5358         * @param indices
5359         *            the second array
5360         * @param left
5361         *            the starting index
5362         * @param right
5363         *            the ending index
5364         */
5365        public static void parallelQuicksortDescending(final double[] main, final int[] indices, final int left,
5366                        final int right)
5367        {
5368                if (right <= left)
5369                        return;
5370
5371                final int i = partitionDesc(main, indices, left, right);
5372
5373                parallelQuicksortDescending(main, indices, left, i - 1);
5374                parallelQuicksortDescending(main, indices, i + 1, right);
5375        }
5376
5377        // partition a[left] to a[right], assumes left < right
5378        private static int partitionDesc(final double[] a, final int[] index, final int left, final int right) {
5379                int i = left - 1;
5380                int j = right;
5381                while (true) {
5382                        while (a[++i] > a[right])
5383                                // find item on left to swap
5384                                ; // a[right] acts as sentinel
5385                        while (a[right] > a[--j])
5386                                // find item on right to swap
5387                                if (j == left)
5388                                        break; // don't go out-of-bounds
5389                        if (i >= j)
5390                                break; // check if pointers cross
5391                        exch(a, index, i, j); // swap two elements into place
5392                }
5393                exch(a, index, i, right); // swap with partition element
5394                return i;
5395        }
5396        
5397        
5398        /**
5399         * Sort parallel arrays. Arrays are sorted in-place. The first array
5400         * determines the order, and is sorted into descending order.
5401         * <p>
5402         * Implementation inspired by this stackoverflow page: <a href=
5403         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5404         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5405         * get-a-sorted-list-of-indices-of-an-array </a>
5406         * 
5407         * @param main
5408         *            the values to use for determining the order
5409         * @param indices
5410         *            the second array
5411         */
5412        public static void parallelQuicksortDescending(final float[] main, final int[] indices) {
5413                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
5414        }
5415
5416        /**
5417         * Sort parallel arrays. Arrays are sorted in-place. The first array
5418         * determines the order, and is sorted into descending order.
5419         * <p>
5420         * Implementation inspired by this stackoverflow page: <a href=
5421         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5422         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5423         * get-a-sorted-list-of-indices-of-an-array </a>
5424         * 
5425         * @param main
5426         *            the values to use for determining the order
5427         * @param indices
5428         *            the second array
5429         * @param left
5430         *            the starting index
5431         * @param right
5432         *            the ending index
5433         */
5434        public static void parallelQuicksortDescending(final float[] main, final int[] indices, final int left,
5435                        final int right)
5436        {
5437                if (right <= left)
5438                        return;
5439
5440                final int i = partitionDesc(main, indices, left, right);
5441
5442                parallelQuicksortDescending(main, indices, left, i - 1);
5443                parallelQuicksortDescending(main, indices, i + 1, right);
5444        }
5445
5446        // partition a[left] to a[right], assumes left < right
5447        private static int partitionDesc(final float[] a, final int[] index, final int left, final int right) {
5448                int i = left - 1;
5449                int j = right;
5450                while (true) {
5451                        while (a[++i] > a[right])
5452                                // find item on left to swap
5453                                ; // a[right] acts as sentinel
5454                        while (a[right] > a[--j])
5455                                // find item on right to swap
5456                                if (j == left)
5457                                        break; // don't go out-of-bounds
5458                        if (i >= j)
5459                                break; // check if pointers cross
5460                        exch(a, index, i, j); // swap two elements into place
5461                }
5462                exch(a, index, i, right); // swap with partition element
5463                return i;
5464        }
5465        
5466        
5467        /**
5468         * Sort parallel arrays. Arrays are sorted in-place. The first array
5469         * determines the order, and is sorted into descending order.
5470         * <p>
5471         * Implementation inspired by this stackoverflow page: <a href=
5472         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5473         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5474         * get-a-sorted-list-of-indices-of-an-array </a>
5475         * 
5476         * @param main
5477         *            the values to use for determining the order
5478         * @param indices
5479         *            the second array
5480         */
5481        public static void parallelQuicksortDescending(final int[] main, final int[] indices) {
5482                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
5483        }
5484
5485        /**
5486         * Sort parallel arrays. Arrays are sorted in-place. The first array
5487         * determines the order, and is sorted into descending order.
5488         * <p>
5489         * Implementation inspired by this stackoverflow page: <a href=
5490         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5491         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5492         * get-a-sorted-list-of-indices-of-an-array </a>
5493         * 
5494         * @param main
5495         *            the values to use for determining the order
5496         * @param indices
5497         *            the second array
5498         * @param left
5499         *            the starting index
5500         * @param right
5501         *            the ending index
5502         */
5503        public static void parallelQuicksortDescending(final int[] main, final int[] indices, final int left,
5504                        final int right)
5505        {
5506                if (right <= left)
5507                        return;
5508
5509                final int i = partitionDesc(main, indices, left, right);
5510
5511                parallelQuicksortDescending(main, indices, left, i - 1);
5512                parallelQuicksortDescending(main, indices, i + 1, right);
5513        }
5514
5515        // partition a[left] to a[right], assumes left < right
5516        private static int partitionDesc(final int[] a, final int[] index, final int left, final int right) {
5517                int i = left - 1;
5518                int j = right;
5519                while (true) {
5520                        while (a[++i] > a[right])
5521                                // find item on left to swap
5522                                ; // a[right] acts as sentinel
5523                        while (a[right] > a[--j])
5524                                // find item on right to swap
5525                                if (j == left)
5526                                        break; // don't go out-of-bounds
5527                        if (i >= j)
5528                                break; // check if pointers cross
5529                        exch(a, index, i, j); // swap two elements into place
5530                }
5531                exch(a, index, i, right); // swap with partition element
5532                return i;
5533        }
5534        
5535        
5536        /**
5537         * Sort parallel arrays. Arrays are sorted in-place. The first array
5538         * determines the order, and is sorted into descending order.
5539         * <p>
5540         * Implementation inspired by this stackoverflow page: <a href=
5541         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5542         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5543         * get-a-sorted-list-of-indices-of-an-array </a>
5544         * 
5545         * @param main
5546         *            the values to use for determining the order
5547         * @param indices
5548         *            the second array
5549         */
5550        public static void parallelQuicksortDescending(final long[] main, final int[] indices) {
5551                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
5552        }
5553
5554        /**
5555         * Sort parallel arrays. Arrays are sorted in-place. The first array
5556         * determines the order, and is sorted into descending order.
5557         * <p>
5558         * Implementation inspired by this stackoverflow page: <a href=
5559         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5560         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5561         * get-a-sorted-list-of-indices-of-an-array </a>
5562         * 
5563         * @param main
5564         *            the values to use for determining the order
5565         * @param indices
5566         *            the second array
5567         * @param left
5568         *            the starting index
5569         * @param right
5570         *            the ending index
5571         */
5572        public static void parallelQuicksortDescending(final long[] main, final int[] indices, final int left,
5573                        final int right)
5574        {
5575                if (right <= left)
5576                        return;
5577
5578                final int i = partitionDesc(main, indices, left, right);
5579
5580                parallelQuicksortDescending(main, indices, left, i - 1);
5581                parallelQuicksortDescending(main, indices, i + 1, right);
5582        }
5583
5584        // partition a[left] to a[right], assumes left < right
5585        private static int partitionDesc(final long[] a, final int[] index, final int left, final int right) {
5586                int i = left - 1;
5587                int j = right;
5588                while (true) {
5589                        while (a[++i] > a[right])
5590                                // find item on left to swap
5591                                ; // a[right] acts as sentinel
5592                        while (a[right] > a[--j])
5593                                // find item on right to swap
5594                                if (j == left)
5595                                        break; // don't go out-of-bounds
5596                        if (i >= j)
5597                                break; // check if pointers cross
5598                        exch(a, index, i, j); // swap two elements into place
5599                }
5600                exch(a, index, i, right); // swap with partition element
5601                return i;
5602        }
5603        
5604        
5605        /**
5606         * Sort parallel arrays. Arrays are sorted in-place. The first array
5607         * determines the order, and is sorted into descending order.
5608         * <p>
5609         * Implementation inspired by this stackoverflow page: <a href=
5610         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5611         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5612         * get-a-sorted-list-of-indices-of-an-array </a>
5613         * 
5614         * @param main
5615         *            the values to use for determining the order
5616         * @param indices
5617         *            the second array
5618         */
5619        public static void parallelQuicksortDescending(final byte[] main, final int[] indices) {
5620                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
5621        }
5622
5623        /**
5624         * Sort parallel arrays. Arrays are sorted in-place. The first array
5625         * determines the order, and is sorted into descending order.
5626         * <p>
5627         * Implementation inspired by this stackoverflow page: <a href=
5628         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5629         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5630         * get-a-sorted-list-of-indices-of-an-array </a>
5631         * 
5632         * @param main
5633         *            the values to use for determining the order
5634         * @param indices
5635         *            the second array
5636         * @param left
5637         *            the starting index
5638         * @param right
5639         *            the ending index
5640         */
5641        public static void parallelQuicksortDescending(final byte[] main, final int[] indices, final int left,
5642                        final int right)
5643        {
5644                if (right <= left)
5645                        return;
5646
5647                final int i = partitionDesc(main, indices, left, right);
5648
5649                parallelQuicksortDescending(main, indices, left, i - 1);
5650                parallelQuicksortDescending(main, indices, i + 1, right);
5651        }
5652
5653        // partition a[left] to a[right], assumes left < right
5654        private static int partitionDesc(final byte[] a, final int[] index, final int left, final int right) {
5655                int i = left - 1;
5656                int j = right;
5657                while (true) {
5658                        while (a[++i] > a[right])
5659                                // find item on left to swap
5660                                ; // a[right] acts as sentinel
5661                        while (a[right] > a[--j])
5662                                // find item on right to swap
5663                                if (j == left)
5664                                        break; // don't go out-of-bounds
5665                        if (i >= j)
5666                                break; // check if pointers cross
5667                        exch(a, index, i, j); // swap two elements into place
5668                }
5669                exch(a, index, i, right); // swap with partition element
5670                return i;
5671        }
5672        
5673        
5674        /**
5675         * Sort parallel arrays. Arrays are sorted in-place. The first array
5676         * determines the order, and is sorted into descending order.
5677         * <p>
5678         * Implementation inspired by this stackoverflow page: <a href=
5679         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5680         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5681         * get-a-sorted-list-of-indices-of-an-array </a>
5682         * 
5683         * @param main
5684         *            the values to use for determining the order
5685         * @param indices
5686         *            the second array
5687         */
5688        public static void parallelQuicksortDescending(final short[] main, final int[] indices) {
5689                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
5690        }
5691
5692        /**
5693         * Sort parallel arrays. Arrays are sorted in-place. The first array
5694         * determines the order, and is sorted into descending order.
5695         * <p>
5696         * Implementation inspired by this stackoverflow page: <a href=
5697         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5698         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5699         * get-a-sorted-list-of-indices-of-an-array </a>
5700         * 
5701         * @param main
5702         *            the values to use for determining the order
5703         * @param indices
5704         *            the second array
5705         * @param left
5706         *            the starting index
5707         * @param right
5708         *            the ending index
5709         */
5710        public static void parallelQuicksortDescending(final short[] main, final int[] indices, final int left,
5711                        final int right)
5712        {
5713                if (right <= left)
5714                        return;
5715
5716                final int i = partitionDesc(main, indices, left, right);
5717
5718                parallelQuicksortDescending(main, indices, left, i - 1);
5719                parallelQuicksortDescending(main, indices, i + 1, right);
5720        }
5721
5722        // partition a[left] to a[right], assumes left < right
5723        private static int partitionDesc(final short[] a, final int[] index, final int left, final int right) {
5724                int i = left - 1;
5725                int j = right;
5726                while (true) {
5727                        while (a[++i] > a[right])
5728                                // find item on left to swap
5729                                ; // a[right] acts as sentinel
5730                        while (a[right] > a[--j])
5731                                // find item on right to swap
5732                                if (j == left)
5733                                        break; // don't go out-of-bounds
5734                        if (i >= j)
5735                                break; // check if pointers cross
5736                        exch(a, index, i, j); // swap two elements into place
5737                }
5738                exch(a, index, i, right); // swap with partition element
5739                return i;
5740        }
5741        
5742        
5743        /**
5744         * Sort parallel arrays. Arrays are sorted in-place. The first array
5745         * determines the order, and is sorted into descending order.
5746         * <p>
5747         * Implementation inspired by this stackoverflow page: <a href=
5748         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5749         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5750         * get-a-sorted-list-of-indices-of-an-array </a>
5751         * 
5752         * @param main
5753         *            the values to use for determining the order
5754         * @param indices
5755         *            the second array
5756         */
5757        public static void parallelQuicksortDescending(final double[] main, final long[] indices) {
5758                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
5759        }
5760
5761        /**
5762         * Sort parallel arrays. Arrays are sorted in-place. The first array
5763         * determines the order, and is sorted into descending order.
5764         * <p>
5765         * Implementation inspired by this stackoverflow page: <a href=
5766         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5767         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5768         * get-a-sorted-list-of-indices-of-an-array </a>
5769         * 
5770         * @param main
5771         *            the values to use for determining the order
5772         * @param indices
5773         *            the second array
5774         * @param left
5775         *            the starting index
5776         * @param right
5777         *            the ending index
5778         */
5779        public static void parallelQuicksortDescending(final double[] main, final long[] indices, final int left,
5780                        final int right)
5781        {
5782                if (right <= left)
5783                        return;
5784
5785                final int i = partitionDesc(main, indices, left, right);
5786
5787                parallelQuicksortDescending(main, indices, left, i - 1);
5788                parallelQuicksortDescending(main, indices, i + 1, right);
5789        }
5790
5791        // partition a[left] to a[right], assumes left < right
5792        private static int partitionDesc(final double[] a, final long[] index, final int left, final int right) {
5793                int i = left - 1;
5794                int j = right;
5795                while (true) {
5796                        while (a[++i] > a[right])
5797                                // find item on left to swap
5798                                ; // a[right] acts as sentinel
5799                        while (a[right] > a[--j])
5800                                // find item on right to swap
5801                                if (j == left)
5802                                        break; // don't go out-of-bounds
5803                        if (i >= j)
5804                                break; // check if pointers cross
5805                        exch(a, index, i, j); // swap two elements into place
5806                }
5807                exch(a, index, i, right); // swap with partition element
5808                return i;
5809        }
5810        
5811        
5812        /**
5813         * Sort parallel arrays. Arrays are sorted in-place. The first array
5814         * determines the order, and is sorted into descending order.
5815         * <p>
5816         * Implementation inspired by this stackoverflow page: <a href=
5817         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5818         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5819         * get-a-sorted-list-of-indices-of-an-array </a>
5820         * 
5821         * @param main
5822         *            the values to use for determining the order
5823         * @param indices
5824         *            the second array
5825         */
5826        public static void parallelQuicksortDescending(final float[] main, final long[] indices) {
5827                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
5828        }
5829
5830        /**
5831         * Sort parallel arrays. Arrays are sorted in-place. The first array
5832         * determines the order, and is sorted into descending order.
5833         * <p>
5834         * Implementation inspired by this stackoverflow page: <a href=
5835         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5836         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5837         * get-a-sorted-list-of-indices-of-an-array </a>
5838         * 
5839         * @param main
5840         *            the values to use for determining the order
5841         * @param indices
5842         *            the second array
5843         * @param left
5844         *            the starting index
5845         * @param right
5846         *            the ending index
5847         */
5848        public static void parallelQuicksortDescending(final float[] main, final long[] indices, final int left,
5849                        final int right)
5850        {
5851                if (right <= left)
5852                        return;
5853
5854                final int i = partitionDesc(main, indices, left, right);
5855
5856                parallelQuicksortDescending(main, indices, left, i - 1);
5857                parallelQuicksortDescending(main, indices, i + 1, right);
5858        }
5859
5860        // partition a[left] to a[right], assumes left < right
5861        private static int partitionDesc(final float[] a, final long[] index, final int left, final int right) {
5862                int i = left - 1;
5863                int j = right;
5864                while (true) {
5865                        while (a[++i] > a[right])
5866                                // find item on left to swap
5867                                ; // a[right] acts as sentinel
5868                        while (a[right] > a[--j])
5869                                // find item on right to swap
5870                                if (j == left)
5871                                        break; // don't go out-of-bounds
5872                        if (i >= j)
5873                                break; // check if pointers cross
5874                        exch(a, index, i, j); // swap two elements into place
5875                }
5876                exch(a, index, i, right); // swap with partition element
5877                return i;
5878        }
5879        
5880        
5881        /**
5882         * Sort parallel arrays. Arrays are sorted in-place. The first array
5883         * determines the order, and is sorted into descending order.
5884         * <p>
5885         * Implementation inspired by this stackoverflow page: <a href=
5886         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5887         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5888         * get-a-sorted-list-of-indices-of-an-array </a>
5889         * 
5890         * @param main
5891         *            the values to use for determining the order
5892         * @param indices
5893         *            the second array
5894         */
5895        public static void parallelQuicksortDescending(final int[] main, final long[] indices) {
5896                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
5897        }
5898
5899        /**
5900         * Sort parallel arrays. Arrays are sorted in-place. The first array
5901         * determines the order, and is sorted into descending order.
5902         * <p>
5903         * Implementation inspired by this stackoverflow page: <a href=
5904         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5905         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5906         * get-a-sorted-list-of-indices-of-an-array </a>
5907         * 
5908         * @param main
5909         *            the values to use for determining the order
5910         * @param indices
5911         *            the second array
5912         * @param left
5913         *            the starting index
5914         * @param right
5915         *            the ending index
5916         */
5917        public static void parallelQuicksortDescending(final int[] main, final long[] indices, final int left,
5918                        final int right)
5919        {
5920                if (right <= left)
5921                        return;
5922
5923                final int i = partitionDesc(main, indices, left, right);
5924
5925                parallelQuicksortDescending(main, indices, left, i - 1);
5926                parallelQuicksortDescending(main, indices, i + 1, right);
5927        }
5928
5929        // partition a[left] to a[right], assumes left < right
5930        private static int partitionDesc(final int[] a, final long[] index, final int left, final int right) {
5931                int i = left - 1;
5932                int j = right;
5933                while (true) {
5934                        while (a[++i] > a[right])
5935                                // find item on left to swap
5936                                ; // a[right] acts as sentinel
5937                        while (a[right] > a[--j])
5938                                // find item on right to swap
5939                                if (j == left)
5940                                        break; // don't go out-of-bounds
5941                        if (i >= j)
5942                                break; // check if pointers cross
5943                        exch(a, index, i, j); // swap two elements into place
5944                }
5945                exch(a, index, i, right); // swap with partition element
5946                return i;
5947        }
5948        
5949        
5950        /**
5951         * Sort parallel arrays. Arrays are sorted in-place. The first array
5952         * determines the order, and is sorted into descending order.
5953         * <p>
5954         * Implementation inspired by this stackoverflow page: <a href=
5955         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5956         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5957         * get-a-sorted-list-of-indices-of-an-array </a>
5958         * 
5959         * @param main
5960         *            the values to use for determining the order
5961         * @param indices
5962         *            the second array
5963         */
5964        public static void parallelQuicksortDescending(final long[] main, final long[] indices) {
5965                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
5966        }
5967
5968        /**
5969         * Sort parallel arrays. Arrays are sorted in-place. The first array
5970         * determines the order, and is sorted into descending order.
5971         * <p>
5972         * Implementation inspired by this stackoverflow page: <a href=
5973         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5974         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5975         * get-a-sorted-list-of-indices-of-an-array </a>
5976         * 
5977         * @param main
5978         *            the values to use for determining the order
5979         * @param indices
5980         *            the second array
5981         * @param left
5982         *            the starting index
5983         * @param right
5984         *            the ending index
5985         */
5986        public static void parallelQuicksortDescending(final long[] main, final long[] indices, final int left,
5987                        final int right)
5988        {
5989                if (right <= left)
5990                        return;
5991
5992                final int i = partitionDesc(main, indices, left, right);
5993
5994                parallelQuicksortDescending(main, indices, left, i - 1);
5995                parallelQuicksortDescending(main, indices, i + 1, right);
5996        }
5997
5998        // partition a[left] to a[right], assumes left < right
5999        private static int partitionDesc(final long[] a, final long[] index, final int left, final int right) {
6000                int i = left - 1;
6001                int j = right;
6002                while (true) {
6003                        while (a[++i] > a[right])
6004                                // find item on left to swap
6005                                ; // a[right] acts as sentinel
6006                        while (a[right] > a[--j])
6007                                // find item on right to swap
6008                                if (j == left)
6009                                        break; // don't go out-of-bounds
6010                        if (i >= j)
6011                                break; // check if pointers cross
6012                        exch(a, index, i, j); // swap two elements into place
6013                }
6014                exch(a, index, i, right); // swap with partition element
6015                return i;
6016        }
6017        
6018        
6019        /**
6020         * Sort parallel arrays. Arrays are sorted in-place. The first array
6021         * determines the order, and is sorted into descending order.
6022         * <p>
6023         * Implementation inspired by this stackoverflow page: <a href=
6024         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6025         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6026         * get-a-sorted-list-of-indices-of-an-array </a>
6027         * 
6028         * @param main
6029         *            the values to use for determining the order
6030         * @param indices
6031         *            the second array
6032         */
6033        public static void parallelQuicksortDescending(final byte[] main, final long[] indices) {
6034                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
6035        }
6036
6037        /**
6038         * Sort parallel arrays. Arrays are sorted in-place. The first array
6039         * determines the order, and is sorted into descending order.
6040         * <p>
6041         * Implementation inspired by this stackoverflow page: <a href=
6042         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6043         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6044         * get-a-sorted-list-of-indices-of-an-array </a>
6045         * 
6046         * @param main
6047         *            the values to use for determining the order
6048         * @param indices
6049         *            the second array
6050         * @param left
6051         *            the starting index
6052         * @param right
6053         *            the ending index
6054         */
6055        public static void parallelQuicksortDescending(final byte[] main, final long[] indices, final int left,
6056                        final int right)
6057        {
6058                if (right <= left)
6059                        return;
6060
6061                final int i = partitionDesc(main, indices, left, right);
6062
6063                parallelQuicksortDescending(main, indices, left, i - 1);
6064                parallelQuicksortDescending(main, indices, i + 1, right);
6065        }
6066
6067        // partition a[left] to a[right], assumes left < right
6068        private static int partitionDesc(final byte[] a, final long[] index, final int left, final int right) {
6069                int i = left - 1;
6070                int j = right;
6071                while (true) {
6072                        while (a[++i] > a[right])
6073                                // find item on left to swap
6074                                ; // a[right] acts as sentinel
6075                        while (a[right] > a[--j])
6076                                // find item on right to swap
6077                                if (j == left)
6078                                        break; // don't go out-of-bounds
6079                        if (i >= j)
6080                                break; // check if pointers cross
6081                        exch(a, index, i, j); // swap two elements into place
6082                }
6083                exch(a, index, i, right); // swap with partition element
6084                return i;
6085        }
6086        
6087        
6088        /**
6089         * Sort parallel arrays. Arrays are sorted in-place. The first array
6090         * determines the order, and is sorted into descending order.
6091         * <p>
6092         * Implementation inspired by this stackoverflow page: <a href=
6093         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6094         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6095         * get-a-sorted-list-of-indices-of-an-array </a>
6096         * 
6097         * @param main
6098         *            the values to use for determining the order
6099         * @param indices
6100         *            the second array
6101         */
6102        public static void parallelQuicksortDescending(final short[] main, final long[] indices) {
6103                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
6104        }
6105
6106        /**
6107         * Sort parallel arrays. Arrays are sorted in-place. The first array
6108         * determines the order, and is sorted into descending order.
6109         * <p>
6110         * Implementation inspired by this stackoverflow page: <a href=
6111         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6112         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6113         * get-a-sorted-list-of-indices-of-an-array </a>
6114         * 
6115         * @param main
6116         *            the values to use for determining the order
6117         * @param indices
6118         *            the second array
6119         * @param left
6120         *            the starting index
6121         * @param right
6122         *            the ending index
6123         */
6124        public static void parallelQuicksortDescending(final short[] main, final long[] indices, final int left,
6125                        final int right)
6126        {
6127                if (right <= left)
6128                        return;
6129
6130                final int i = partitionDesc(main, indices, left, right);
6131
6132                parallelQuicksortDescending(main, indices, left, i - 1);
6133                parallelQuicksortDescending(main, indices, i + 1, right);
6134        }
6135
6136        // partition a[left] to a[right], assumes left < right
6137        private static int partitionDesc(final short[] a, final long[] index, final int left, final int right) {
6138                int i = left - 1;
6139                int j = right;
6140                while (true) {
6141                        while (a[++i] > a[right])
6142                                // find item on left to swap
6143                                ; // a[right] acts as sentinel
6144                        while (a[right] > a[--j])
6145                                // find item on right to swap
6146                                if (j == left)
6147                                        break; // don't go out-of-bounds
6148                        if (i >= j)
6149                                break; // check if pointers cross
6150                        exch(a, index, i, j); // swap two elements into place
6151                }
6152                exch(a, index, i, right); // swap with partition element
6153                return i;
6154        }
6155        
6156        
6157        /**
6158         * Sort parallel arrays. Arrays are sorted in-place. The first array
6159         * determines the order, and is sorted into descending order.
6160         * <p>
6161         * Implementation inspired by this stackoverflow page: <a href=
6162         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6163         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6164         * get-a-sorted-list-of-indices-of-an-array </a>
6165         * 
6166         * @param main
6167         *            the values to use for determining the order
6168         * @param indices
6169         *            the second array
6170         */
6171        public static void parallelQuicksortDescending(final double[] main, final byte[] indices) {
6172                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
6173        }
6174
6175        /**
6176         * Sort parallel arrays. Arrays are sorted in-place. The first array
6177         * determines the order, and is sorted into descending order.
6178         * <p>
6179         * Implementation inspired by this stackoverflow page: <a href=
6180         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6181         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6182         * get-a-sorted-list-of-indices-of-an-array </a>
6183         * 
6184         * @param main
6185         *            the values to use for determining the order
6186         * @param indices
6187         *            the second array
6188         * @param left
6189         *            the starting index
6190         * @param right
6191         *            the ending index
6192         */
6193        public static void parallelQuicksortDescending(final double[] main, final byte[] indices, final int left,
6194                        final int right)
6195        {
6196                if (right <= left)
6197                        return;
6198
6199                final int i = partitionDesc(main, indices, left, right);
6200
6201                parallelQuicksortDescending(main, indices, left, i - 1);
6202                parallelQuicksortDescending(main, indices, i + 1, right);
6203        }
6204
6205        // partition a[left] to a[right], assumes left < right
6206        private static int partitionDesc(final double[] a, final byte[] index, final int left, final int right) {
6207                int i = left - 1;
6208                int j = right;
6209                while (true) {
6210                        while (a[++i] > a[right])
6211                                // find item on left to swap
6212                                ; // a[right] acts as sentinel
6213                        while (a[right] > a[--j])
6214                                // find item on right to swap
6215                                if (j == left)
6216                                        break; // don't go out-of-bounds
6217                        if (i >= j)
6218                                break; // check if pointers cross
6219                        exch(a, index, i, j); // swap two elements into place
6220                }
6221                exch(a, index, i, right); // swap with partition element
6222                return i;
6223        }
6224        
6225        
6226        /**
6227         * Sort parallel arrays. Arrays are sorted in-place. The first array
6228         * determines the order, and is sorted into descending order.
6229         * <p>
6230         * Implementation inspired by this stackoverflow page: <a href=
6231         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6232         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6233         * get-a-sorted-list-of-indices-of-an-array </a>
6234         * 
6235         * @param main
6236         *            the values to use for determining the order
6237         * @param indices
6238         *            the second array
6239         */
6240        public static void parallelQuicksortDescending(final float[] main, final byte[] indices) {
6241                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
6242        }
6243
6244        /**
6245         * Sort parallel arrays. Arrays are sorted in-place. The first array
6246         * determines the order, and is sorted into descending order.
6247         * <p>
6248         * Implementation inspired by this stackoverflow page: <a href=
6249         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6250         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6251         * get-a-sorted-list-of-indices-of-an-array </a>
6252         * 
6253         * @param main
6254         *            the values to use for determining the order
6255         * @param indices
6256         *            the second array
6257         * @param left
6258         *            the starting index
6259         * @param right
6260         *            the ending index
6261         */
6262        public static void parallelQuicksortDescending(final float[] main, final byte[] indices, final int left,
6263                        final int right)
6264        {
6265                if (right <= left)
6266                        return;
6267
6268                final int i = partitionDesc(main, indices, left, right);
6269
6270                parallelQuicksortDescending(main, indices, left, i - 1);
6271                parallelQuicksortDescending(main, indices, i + 1, right);
6272        }
6273
6274        // partition a[left] to a[right], assumes left < right
6275        private static int partitionDesc(final float[] a, final byte[] index, final int left, final int right) {
6276                int i = left - 1;
6277                int j = right;
6278                while (true) {
6279                        while (a[++i] > a[right])
6280                                // find item on left to swap
6281                                ; // a[right] acts as sentinel
6282                        while (a[right] > a[--j])
6283                                // find item on right to swap
6284                                if (j == left)
6285                                        break; // don't go out-of-bounds
6286                        if (i >= j)
6287                                break; // check if pointers cross
6288                        exch(a, index, i, j); // swap two elements into place
6289                }
6290                exch(a, index, i, right); // swap with partition element
6291                return i;
6292        }
6293        
6294        
6295        /**
6296         * Sort parallel arrays. Arrays are sorted in-place. The first array
6297         * determines the order, and is sorted into descending order.
6298         * <p>
6299         * Implementation inspired by this stackoverflow page: <a href=
6300         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6301         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6302         * get-a-sorted-list-of-indices-of-an-array </a>
6303         * 
6304         * @param main
6305         *            the values to use for determining the order
6306         * @param indices
6307         *            the second array
6308         */
6309        public static void parallelQuicksortDescending(final int[] main, final byte[] indices) {
6310                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
6311        }
6312
6313        /**
6314         * Sort parallel arrays. Arrays are sorted in-place. The first array
6315         * determines the order, and is sorted into descending order.
6316         * <p>
6317         * Implementation inspired by this stackoverflow page: <a href=
6318         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6319         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6320         * get-a-sorted-list-of-indices-of-an-array </a>
6321         * 
6322         * @param main
6323         *            the values to use for determining the order
6324         * @param indices
6325         *            the second array
6326         * @param left
6327         *            the starting index
6328         * @param right
6329         *            the ending index
6330         */
6331        public static void parallelQuicksortDescending(final int[] main, final byte[] indices, final int left,
6332                        final int right)
6333        {
6334                if (right <= left)
6335                        return;
6336
6337                final int i = partitionDesc(main, indices, left, right);
6338
6339                parallelQuicksortDescending(main, indices, left, i - 1);
6340                parallelQuicksortDescending(main, indices, i + 1, right);
6341        }
6342
6343        // partition a[left] to a[right], assumes left < right
6344        private static int partitionDesc(final int[] a, final byte[] index, final int left, final int right) {
6345                int i = left - 1;
6346                int j = right;
6347                while (true) {
6348                        while (a[++i] > a[right])
6349                                // find item on left to swap
6350                                ; // a[right] acts as sentinel
6351                        while (a[right] > a[--j])
6352                                // find item on right to swap
6353                                if (j == left)
6354                                        break; // don't go out-of-bounds
6355                        if (i >= j)
6356                                break; // check if pointers cross
6357                        exch(a, index, i, j); // swap two elements into place
6358                }
6359                exch(a, index, i, right); // swap with partition element
6360                return i;
6361        }
6362        
6363        
6364        /**
6365         * Sort parallel arrays. Arrays are sorted in-place. The first array
6366         * determines the order, and is sorted into descending order.
6367         * <p>
6368         * Implementation inspired by this stackoverflow page: <a href=
6369         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6370         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6371         * get-a-sorted-list-of-indices-of-an-array </a>
6372         * 
6373         * @param main
6374         *            the values to use for determining the order
6375         * @param indices
6376         *            the second array
6377         */
6378        public static void parallelQuicksortDescending(final long[] main, final byte[] indices) {
6379                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
6380        }
6381
6382        /**
6383         * Sort parallel arrays. Arrays are sorted in-place. The first array
6384         * determines the order, and is sorted into descending order.
6385         * <p>
6386         * Implementation inspired by this stackoverflow page: <a href=
6387         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6388         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6389         * get-a-sorted-list-of-indices-of-an-array </a>
6390         * 
6391         * @param main
6392         *            the values to use for determining the order
6393         * @param indices
6394         *            the second array
6395         * @param left
6396         *            the starting index
6397         * @param right
6398         *            the ending index
6399         */
6400        public static void parallelQuicksortDescending(final long[] main, final byte[] indices, final int left,
6401                        final int right)
6402        {
6403                if (right <= left)
6404                        return;
6405
6406                final int i = partitionDesc(main, indices, left, right);
6407
6408                parallelQuicksortDescending(main, indices, left, i - 1);
6409                parallelQuicksortDescending(main, indices, i + 1, right);
6410        }
6411
6412        // partition a[left] to a[right], assumes left < right
6413        private static int partitionDesc(final long[] a, final byte[] index, final int left, final int right) {
6414                int i = left - 1;
6415                int j = right;
6416                while (true) {
6417                        while (a[++i] > a[right])
6418                                // find item on left to swap
6419                                ; // a[right] acts as sentinel
6420                        while (a[right] > a[--j])
6421                                // find item on right to swap
6422                                if (j == left)
6423                                        break; // don't go out-of-bounds
6424                        if (i >= j)
6425                                break; // check if pointers cross
6426                        exch(a, index, i, j); // swap two elements into place
6427                }
6428                exch(a, index, i, right); // swap with partition element
6429                return i;
6430        }
6431        
6432        
6433        /**
6434         * Sort parallel arrays. Arrays are sorted in-place. The first array
6435         * determines the order, and is sorted into descending order.
6436         * <p>
6437         * Implementation inspired by this stackoverflow page: <a href=
6438         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6439         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6440         * get-a-sorted-list-of-indices-of-an-array </a>
6441         * 
6442         * @param main
6443         *            the values to use for determining the order
6444         * @param indices
6445         *            the second array
6446         */
6447        public static void parallelQuicksortDescending(final byte[] main, final byte[] indices) {
6448                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
6449        }
6450
6451        /**
6452         * Sort parallel arrays. Arrays are sorted in-place. The first array
6453         * determines the order, and is sorted into descending order.
6454         * <p>
6455         * Implementation inspired by this stackoverflow page: <a href=
6456         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6457         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6458         * get-a-sorted-list-of-indices-of-an-array </a>
6459         * 
6460         * @param main
6461         *            the values to use for determining the order
6462         * @param indices
6463         *            the second array
6464         * @param left
6465         *            the starting index
6466         * @param right
6467         *            the ending index
6468         */
6469        public static void parallelQuicksortDescending(final byte[] main, final byte[] indices, final int left,
6470                        final int right)
6471        {
6472                if (right <= left)
6473                        return;
6474
6475                final int i = partitionDesc(main, indices, left, right);
6476
6477                parallelQuicksortDescending(main, indices, left, i - 1);
6478                parallelQuicksortDescending(main, indices, i + 1, right);
6479        }
6480
6481        // partition a[left] to a[right], assumes left < right
6482        private static int partitionDesc(final byte[] a, final byte[] index, final int left, final int right) {
6483                int i = left - 1;
6484                int j = right;
6485                while (true) {
6486                        while (a[++i] > a[right])
6487                                // find item on left to swap
6488                                ; // a[right] acts as sentinel
6489                        while (a[right] > a[--j])
6490                                // find item on right to swap
6491                                if (j == left)
6492                                        break; // don't go out-of-bounds
6493                        if (i >= j)
6494                                break; // check if pointers cross
6495                        exch(a, index, i, j); // swap two elements into place
6496                }
6497                exch(a, index, i, right); // swap with partition element
6498                return i;
6499        }
6500        
6501        
6502        /**
6503         * Sort parallel arrays. Arrays are sorted in-place. The first array
6504         * determines the order, and is sorted into descending order.
6505         * <p>
6506         * Implementation inspired by this stackoverflow page: <a href=
6507         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6508         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6509         * get-a-sorted-list-of-indices-of-an-array </a>
6510         * 
6511         * @param main
6512         *            the values to use for determining the order
6513         * @param indices
6514         *            the second array
6515         */
6516        public static void parallelQuicksortDescending(final short[] main, final byte[] indices) {
6517                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
6518        }
6519
6520        /**
6521         * Sort parallel arrays. Arrays are sorted in-place. The first array
6522         * determines the order, and is sorted into descending order.
6523         * <p>
6524         * Implementation inspired by this stackoverflow page: <a href=
6525         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6526         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6527         * get-a-sorted-list-of-indices-of-an-array </a>
6528         * 
6529         * @param main
6530         *            the values to use for determining the order
6531         * @param indices
6532         *            the second array
6533         * @param left
6534         *            the starting index
6535         * @param right
6536         *            the ending index
6537         */
6538        public static void parallelQuicksortDescending(final short[] main, final byte[] indices, final int left,
6539                        final int right)
6540        {
6541                if (right <= left)
6542                        return;
6543
6544                final int i = partitionDesc(main, indices, left, right);
6545
6546                parallelQuicksortDescending(main, indices, left, i - 1);
6547                parallelQuicksortDescending(main, indices, i + 1, right);
6548        }
6549
6550        // partition a[left] to a[right], assumes left < right
6551        private static int partitionDesc(final short[] a, final byte[] index, final int left, final int right) {
6552                int i = left - 1;
6553                int j = right;
6554                while (true) {
6555                        while (a[++i] > a[right])
6556                                // find item on left to swap
6557                                ; // a[right] acts as sentinel
6558                        while (a[right] > a[--j])
6559                                // find item on right to swap
6560                                if (j == left)
6561                                        break; // don't go out-of-bounds
6562                        if (i >= j)
6563                                break; // check if pointers cross
6564                        exch(a, index, i, j); // swap two elements into place
6565                }
6566                exch(a, index, i, right); // swap with partition element
6567                return i;
6568        }
6569        
6570        
6571        /**
6572         * Sort parallel arrays. Arrays are sorted in-place. The first array
6573         * determines the order, and is sorted into descending order.
6574         * <p>
6575         * Implementation inspired by this stackoverflow page: <a href=
6576         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6577         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6578         * get-a-sorted-list-of-indices-of-an-array </a>
6579         * 
6580         * @param main
6581         *            the values to use for determining the order
6582         * @param indices
6583         *            the second array
6584         */
6585        public static void parallelQuicksortDescending(final double[] main, final short[] indices) {
6586                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
6587        }
6588
6589        /**
6590         * Sort parallel arrays. Arrays are sorted in-place. The first array
6591         * determines the order, and is sorted into descending order.
6592         * <p>
6593         * Implementation inspired by this stackoverflow page: <a href=
6594         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6595         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6596         * get-a-sorted-list-of-indices-of-an-array </a>
6597         * 
6598         * @param main
6599         *            the values to use for determining the order
6600         * @param indices
6601         *            the second array
6602         * @param left
6603         *            the starting index
6604         * @param right
6605         *            the ending index
6606         */
6607        public static void parallelQuicksortDescending(final double[] main, final short[] indices, final int left,
6608                        final int right)
6609        {
6610                if (right <= left)
6611                        return;
6612
6613                final int i = partitionDesc(main, indices, left, right);
6614
6615                parallelQuicksortDescending(main, indices, left, i - 1);
6616                parallelQuicksortDescending(main, indices, i + 1, right);
6617        }
6618
6619        // partition a[left] to a[right], assumes left < right
6620        private static int partitionDesc(final double[] a, final short[] index, final int left, final int right) {
6621                int i = left - 1;
6622                int j = right;
6623                while (true) {
6624                        while (a[++i] > a[right])
6625                                // find item on left to swap
6626                                ; // a[right] acts as sentinel
6627                        while (a[right] > a[--j])
6628                                // find item on right to swap
6629                                if (j == left)
6630                                        break; // don't go out-of-bounds
6631                        if (i >= j)
6632                                break; // check if pointers cross
6633                        exch(a, index, i, j); // swap two elements into place
6634                }
6635                exch(a, index, i, right); // swap with partition element
6636                return i;
6637        }
6638        
6639        
6640        /**
6641         * Sort parallel arrays. Arrays are sorted in-place. The first array
6642         * determines the order, and is sorted into descending order.
6643         * <p>
6644         * Implementation inspired by this stackoverflow page: <a href=
6645         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6646         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6647         * get-a-sorted-list-of-indices-of-an-array </a>
6648         * 
6649         * @param main
6650         *            the values to use for determining the order
6651         * @param indices
6652         *            the second array
6653         */
6654        public static void parallelQuicksortDescending(final float[] main, final short[] indices) {
6655                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
6656        }
6657
6658        /**
6659         * Sort parallel arrays. Arrays are sorted in-place. The first array
6660         * determines the order, and is sorted into descending order.
6661         * <p>
6662         * Implementation inspired by this stackoverflow page: <a href=
6663         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6664         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6665         * get-a-sorted-list-of-indices-of-an-array </a>
6666         * 
6667         * @param main
6668         *            the values to use for determining the order
6669         * @param indices
6670         *            the second array
6671         * @param left
6672         *            the starting index
6673         * @param right
6674         *            the ending index
6675         */
6676        public static void parallelQuicksortDescending(final float[] main, final short[] indices, final int left,
6677                        final int right)
6678        {
6679                if (right <= left)
6680                        return;
6681
6682                final int i = partitionDesc(main, indices, left, right);
6683
6684                parallelQuicksortDescending(main, indices, left, i - 1);
6685                parallelQuicksortDescending(main, indices, i + 1, right);
6686        }
6687
6688        // partition a[left] to a[right], assumes left < right
6689        private static int partitionDesc(final float[] a, final short[] index, final int left, final int right) {
6690                int i = left - 1;
6691                int j = right;
6692                while (true) {
6693                        while (a[++i] > a[right])
6694                                // find item on left to swap
6695                                ; // a[right] acts as sentinel
6696                        while (a[right] > a[--j])
6697                                // find item on right to swap
6698                                if (j == left)
6699                                        break; // don't go out-of-bounds
6700                        if (i >= j)
6701                                break; // check if pointers cross
6702                        exch(a, index, i, j); // swap two elements into place
6703                }
6704                exch(a, index, i, right); // swap with partition element
6705                return i;
6706        }
6707        
6708        
6709        /**
6710         * Sort parallel arrays. Arrays are sorted in-place. The first array
6711         * determines the order, and is sorted into descending order.
6712         * <p>
6713         * Implementation inspired by this stackoverflow page: <a href=
6714         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6715         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6716         * get-a-sorted-list-of-indices-of-an-array </a>
6717         * 
6718         * @param main
6719         *            the values to use for determining the order
6720         * @param indices
6721         *            the second array
6722         */
6723        public static void parallelQuicksortDescending(final int[] main, final short[] indices) {
6724                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
6725        }
6726
6727        /**
6728         * Sort parallel arrays. Arrays are sorted in-place. The first array
6729         * determines the order, and is sorted into descending order.
6730         * <p>
6731         * Implementation inspired by this stackoverflow page: <a href=
6732         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6733         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6734         * get-a-sorted-list-of-indices-of-an-array </a>
6735         * 
6736         * @param main
6737         *            the values to use for determining the order
6738         * @param indices
6739         *            the second array
6740         * @param left
6741         *            the starting index
6742         * @param right
6743         *            the ending index
6744         */
6745        public static void parallelQuicksortDescending(final int[] main, final short[] indices, final int left,
6746                        final int right)
6747        {
6748                if (right <= left)
6749                        return;
6750
6751                final int i = partitionDesc(main, indices, left, right);
6752
6753                parallelQuicksortDescending(main, indices, left, i - 1);
6754                parallelQuicksortDescending(main, indices, i + 1, right);
6755        }
6756
6757        // partition a[left] to a[right], assumes left < right
6758        private static int partitionDesc(final int[] a, final short[] index, final int left, final int right) {
6759                int i = left - 1;
6760                int j = right;
6761                while (true) {
6762                        while (a[++i] > a[right])
6763                                // find item on left to swap
6764                                ; // a[right] acts as sentinel
6765                        while (a[right] > a[--j])
6766                                // find item on right to swap
6767                                if (j == left)
6768                                        break; // don't go out-of-bounds
6769                        if (i >= j)
6770                                break; // check if pointers cross
6771                        exch(a, index, i, j); // swap two elements into place
6772                }
6773                exch(a, index, i, right); // swap with partition element
6774                return i;
6775        }
6776        
6777        
6778        /**
6779         * Sort parallel arrays. Arrays are sorted in-place. The first array
6780         * determines the order, and is sorted into descending order.
6781         * <p>
6782         * Implementation inspired by this stackoverflow page: <a href=
6783         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6784         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6785         * get-a-sorted-list-of-indices-of-an-array </a>
6786         * 
6787         * @param main
6788         *            the values to use for determining the order
6789         * @param indices
6790         *            the second array
6791         */
6792        public static void parallelQuicksortDescending(final long[] main, final short[] indices) {
6793                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
6794        }
6795
6796        /**
6797         * Sort parallel arrays. Arrays are sorted in-place. The first array
6798         * determines the order, and is sorted into descending order.
6799         * <p>
6800         * Implementation inspired by this stackoverflow page: <a href=
6801         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6802         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6803         * get-a-sorted-list-of-indices-of-an-array </a>
6804         * 
6805         * @param main
6806         *            the values to use for determining the order
6807         * @param indices
6808         *            the second array
6809         * @param left
6810         *            the starting index
6811         * @param right
6812         *            the ending index
6813         */
6814        public static void parallelQuicksortDescending(final long[] main, final short[] indices, final int left,
6815                        final int right)
6816        {
6817                if (right <= left)
6818                        return;
6819
6820                final int i = partitionDesc(main, indices, left, right);
6821
6822                parallelQuicksortDescending(main, indices, left, i - 1);
6823                parallelQuicksortDescending(main, indices, i + 1, right);
6824        }
6825
6826        // partition a[left] to a[right], assumes left < right
6827        private static int partitionDesc(final long[] a, final short[] index, final int left, final int right) {
6828                int i = left - 1;
6829                int j = right;
6830                while (true) {
6831                        while (a[++i] > a[right])
6832                                // find item on left to swap
6833                                ; // a[right] acts as sentinel
6834                        while (a[right] > a[--j])
6835                                // find item on right to swap
6836                                if (j == left)
6837                                        break; // don't go out-of-bounds
6838                        if (i >= j)
6839                                break; // check if pointers cross
6840                        exch(a, index, i, j); // swap two elements into place
6841                }
6842                exch(a, index, i, right); // swap with partition element
6843                return i;
6844        }
6845        
6846        
6847        /**
6848         * Sort parallel arrays. Arrays are sorted in-place. The first array
6849         * determines the order, and is sorted into descending order.
6850         * <p>
6851         * Implementation inspired by this stackoverflow page: <a href=
6852         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6853         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6854         * get-a-sorted-list-of-indices-of-an-array </a>
6855         * 
6856         * @param main
6857         *            the values to use for determining the order
6858         * @param indices
6859         *            the second array
6860         */
6861        public static void parallelQuicksortDescending(final byte[] main, final short[] indices) {
6862                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
6863        }
6864
6865        /**
6866         * Sort parallel arrays. Arrays are sorted in-place. The first array
6867         * determines the order, and is sorted into descending order.
6868         * <p>
6869         * Implementation inspired by this stackoverflow page: <a href=
6870         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6871         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6872         * get-a-sorted-list-of-indices-of-an-array </a>
6873         * 
6874         * @param main
6875         *            the values to use for determining the order
6876         * @param indices
6877         *            the second array
6878         * @param left
6879         *            the starting index
6880         * @param right
6881         *            the ending index
6882         */
6883        public static void parallelQuicksortDescending(final byte[] main, final short[] indices, final int left,
6884                        final int right)
6885        {
6886                if (right <= left)
6887                        return;
6888
6889                final int i = partitionDesc(main, indices, left, right);
6890
6891                parallelQuicksortDescending(main, indices, left, i - 1);
6892                parallelQuicksortDescending(main, indices, i + 1, right);
6893        }
6894
6895        // partition a[left] to a[right], assumes left < right
6896        private static int partitionDesc(final byte[] a, final short[] index, final int left, final int right) {
6897                int i = left - 1;
6898                int j = right;
6899                while (true) {
6900                        while (a[++i] > a[right])
6901                                // find item on left to swap
6902                                ; // a[right] acts as sentinel
6903                        while (a[right] > a[--j])
6904                                // find item on right to swap
6905                                if (j == left)
6906                                        break; // don't go out-of-bounds
6907                        if (i >= j)
6908                                break; // check if pointers cross
6909                        exch(a, index, i, j); // swap two elements into place
6910                }
6911                exch(a, index, i, right); // swap with partition element
6912                return i;
6913        }
6914        
6915        
6916        /**
6917         * Sort parallel arrays. Arrays are sorted in-place. The first array
6918         * determines the order, and is sorted into descending order.
6919         * <p>
6920         * Implementation inspired by this stackoverflow page: <a href=
6921         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6922         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6923         * get-a-sorted-list-of-indices-of-an-array </a>
6924         * 
6925         * @param main
6926         *            the values to use for determining the order
6927         * @param indices
6928         *            the second array
6929         */
6930        public static void parallelQuicksortDescending(final short[] main, final short[] indices) {
6931                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
6932        }
6933
6934        /**
6935         * Sort parallel arrays. Arrays are sorted in-place. The first array
6936         * determines the order, and is sorted into descending order.
6937         * <p>
6938         * Implementation inspired by this stackoverflow page: <a href=
6939         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6940         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6941         * get-a-sorted-list-of-indices-of-an-array </a>
6942         * 
6943         * @param main
6944         *            the values to use for determining the order
6945         * @param indices
6946         *            the second array
6947         * @param left
6948         *            the starting index
6949         * @param right
6950         *            the ending index
6951         */
6952        public static void parallelQuicksortDescending(final short[] main, final short[] indices, final int left,
6953                        final int right)
6954        {
6955                if (right <= left)
6956                        return;
6957
6958                final int i = partitionDesc(main, indices, left, right);
6959
6960                parallelQuicksortDescending(main, indices, left, i - 1);
6961                parallelQuicksortDescending(main, indices, i + 1, right);
6962        }
6963
6964        // partition a[left] to a[right], assumes left < right
6965        private static int partitionDesc(final short[] a, final short[] index, final int left, final int right) {
6966                int i = left - 1;
6967                int j = right;
6968                while (true) {
6969                        while (a[++i] > a[right])
6970                                // find item on left to swap
6971                                ; // a[right] acts as sentinel
6972                        while (a[right] > a[--j])
6973                                // find item on right to swap
6974                                if (j == left)
6975                                        break; // don't go out-of-bounds
6976                        if (i >= j)
6977                                break; // check if pointers cross
6978                        exch(a, index, i, j); // swap two elements into place
6979                }
6980                exch(a, index, i, right); // swap with partition element
6981                return i;
6982        }
6983        
6984        
6985    /**
6986         * Sort parallel arrays. Arrays are sorted in-place. The first array
6987         * determines the order, and is sorted into ascending order.
6988         * <p>
6989         * Implementation inspired by this stackoverflow page: <a href=
6990         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6991         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6992         * get-a-sorted-list-of-indices-of-an-array </a>
6993         * 
6994         * @param main
6995         *            the values to use for determining the order
6996         * @param indices
6997         *            the second array
6998         */
6999        public static void parallelQuicksortAscending(final double[] main, final double[] indices) {
7000                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
7001        }
7002        
7003    /**
7004         * Sort parallel arrays. Arrays are sorted in-place. The first array
7005         * determines the order, and is sorted into ascending order.
7006         * <p>
7007         * Implementation inspired by this stackoverflow page: <a href=
7008         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7009         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7010         * get-a-sorted-list-of-indices-of-an-array </a>
7011         * 
7012         * @param main
7013         *            the values to use for determining the order
7014         * @param indices
7015         *            the second array
7016         * @param left
7017         *            the starting index
7018         * @param right
7019         *            the ending index
7020         */
7021        public static void
7022                        parallelQuicksortAscending(final double[] main, final double[] indices, final int left, final int right)
7023        {
7024                if (right <= left)
7025                        return;
7026
7027                final int i = partitionAsc(main, indices, left, right);
7028
7029                parallelQuicksortAscending(main, indices, left, i - 1);
7030                parallelQuicksortAscending(main, indices, i + 1, right);
7031        }
7032
7033        // partition a[left] to a[right], assumes left < right
7034        private static int partitionAsc(final double[] a, final double[] index, final int left, final int right) {
7035                int i = left - 1;
7036                int j = right;
7037                while (true) {
7038                        while (a[++i] < a[right])
7039                                // find item on left to swap
7040                                ; // a[right] acts as sentinel
7041                        while (a[right] < a[--j])
7042                                // find item on right to swap
7043                                if (j == left)
7044                                        break; // don't go out-of-bounds
7045                        if (i >= j)
7046                                break; // check if pointers cross
7047                        exch(a, index, i, j); // swap two elements into place
7048                }
7049                exch(a, index, i, right); // swap with partition element
7050                return i;
7051        }
7052
7053    
7054    /**
7055         * Sort parallel arrays. Arrays are sorted in-place. The first array
7056         * determines the order, and is sorted into ascending order.
7057         * <p>
7058         * Implementation inspired by this stackoverflow page: <a href=
7059         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7060         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7061         * get-a-sorted-list-of-indices-of-an-array </a>
7062         * 
7063         * @param main
7064         *            the values to use for determining the order
7065         * @param indices
7066         *            the second array
7067         */
7068        public static void parallelQuicksortAscending(final float[] main, final double[] indices) {
7069                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
7070        }
7071        
7072    /**
7073         * Sort parallel arrays. Arrays are sorted in-place. The first array
7074         * determines the order, and is sorted into ascending order.
7075         * <p>
7076         * Implementation inspired by this stackoverflow page: <a href=
7077         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7078         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7079         * get-a-sorted-list-of-indices-of-an-array </a>
7080         * 
7081         * @param main
7082         *            the values to use for determining the order
7083         * @param indices
7084         *            the second array
7085         * @param left
7086         *            the starting index
7087         * @param right
7088         *            the ending index
7089         */
7090        public static void
7091                        parallelQuicksortAscending(final float[] main, final double[] indices, final int left, final int right)
7092        {
7093                if (right <= left)
7094                        return;
7095
7096                final int i = partitionAsc(main, indices, left, right);
7097
7098                parallelQuicksortAscending(main, indices, left, i - 1);
7099                parallelQuicksortAscending(main, indices, i + 1, right);
7100        }
7101
7102        // partition a[left] to a[right], assumes left < right
7103        private static int partitionAsc(final float[] a, final double[] index, final int left, final int right) {
7104                int i = left - 1;
7105                int j = right;
7106                while (true) {
7107                        while (a[++i] < a[right])
7108                                // find item on left to swap
7109                                ; // a[right] acts as sentinel
7110                        while (a[right] < a[--j])
7111                                // find item on right to swap
7112                                if (j == left)
7113                                        break; // don't go out-of-bounds
7114                        if (i >= j)
7115                                break; // check if pointers cross
7116                        exch(a, index, i, j); // swap two elements into place
7117                }
7118                exch(a, index, i, right); // swap with partition element
7119                return i;
7120        }
7121
7122    
7123    /**
7124         * Sort parallel arrays. Arrays are sorted in-place. The first array
7125         * determines the order, and is sorted into ascending order.
7126         * <p>
7127         * Implementation inspired by this stackoverflow page: <a href=
7128         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7129         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7130         * get-a-sorted-list-of-indices-of-an-array </a>
7131         * 
7132         * @param main
7133         *            the values to use for determining the order
7134         * @param indices
7135         *            the second array
7136         */
7137        public static void parallelQuicksortAscending(final int[] main, final double[] indices) {
7138                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
7139        }
7140        
7141    /**
7142         * Sort parallel arrays. Arrays are sorted in-place. The first array
7143         * determines the order, and is sorted into ascending order.
7144         * <p>
7145         * Implementation inspired by this stackoverflow page: <a href=
7146         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7147         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7148         * get-a-sorted-list-of-indices-of-an-array </a>
7149         * 
7150         * @param main
7151         *            the values to use for determining the order
7152         * @param indices
7153         *            the second array
7154         * @param left
7155         *            the starting index
7156         * @param right
7157         *            the ending index
7158         */
7159        public static void
7160                        parallelQuicksortAscending(final int[] main, final double[] indices, final int left, final int right)
7161        {
7162                if (right <= left)
7163                        return;
7164
7165                final int i = partitionAsc(main, indices, left, right);
7166
7167                parallelQuicksortAscending(main, indices, left, i - 1);
7168                parallelQuicksortAscending(main, indices, i + 1, right);
7169        }
7170
7171        // partition a[left] to a[right], assumes left < right
7172        private static int partitionAsc(final int[] a, final double[] index, final int left, final int right) {
7173                int i = left - 1;
7174                int j = right;
7175                while (true) {
7176                        while (a[++i] < a[right])
7177                                // find item on left to swap
7178                                ; // a[right] acts as sentinel
7179                        while (a[right] < a[--j])
7180                                // find item on right to swap
7181                                if (j == left)
7182                                        break; // don't go out-of-bounds
7183                        if (i >= j)
7184                                break; // check if pointers cross
7185                        exch(a, index, i, j); // swap two elements into place
7186                }
7187                exch(a, index, i, right); // swap with partition element
7188                return i;
7189        }
7190
7191    
7192    /**
7193         * Sort parallel arrays. Arrays are sorted in-place. The first array
7194         * determines the order, and is sorted into ascending order.
7195         * <p>
7196         * Implementation inspired by this stackoverflow page: <a href=
7197         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7198         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7199         * get-a-sorted-list-of-indices-of-an-array </a>
7200         * 
7201         * @param main
7202         *            the values to use for determining the order
7203         * @param indices
7204         *            the second array
7205         */
7206        public static void parallelQuicksortAscending(final long[] main, final double[] indices) {
7207                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
7208        }
7209        
7210    /**
7211         * Sort parallel arrays. Arrays are sorted in-place. The first array
7212         * determines the order, and is sorted into ascending order.
7213         * <p>
7214         * Implementation inspired by this stackoverflow page: <a href=
7215         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7216         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7217         * get-a-sorted-list-of-indices-of-an-array </a>
7218         * 
7219         * @param main
7220         *            the values to use for determining the order
7221         * @param indices
7222         *            the second array
7223         * @param left
7224         *            the starting index
7225         * @param right
7226         *            the ending index
7227         */
7228        public static void
7229                        parallelQuicksortAscending(final long[] main, final double[] indices, final int left, final int right)
7230        {
7231                if (right <= left)
7232                        return;
7233
7234                final int i = partitionAsc(main, indices, left, right);
7235
7236                parallelQuicksortAscending(main, indices, left, i - 1);
7237                parallelQuicksortAscending(main, indices, i + 1, right);
7238        }
7239
7240        // partition a[left] to a[right], assumes left < right
7241        private static int partitionAsc(final long[] a, final double[] index, final int left, final int right) {
7242                int i = left - 1;
7243                int j = right;
7244                while (true) {
7245                        while (a[++i] < a[right])
7246                                // find item on left to swap
7247                                ; // a[right] acts as sentinel
7248                        while (a[right] < a[--j])
7249                                // find item on right to swap
7250                                if (j == left)
7251                                        break; // don't go out-of-bounds
7252                        if (i >= j)
7253                                break; // check if pointers cross
7254                        exch(a, index, i, j); // swap two elements into place
7255                }
7256                exch(a, index, i, right); // swap with partition element
7257                return i;
7258        }
7259
7260    
7261    /**
7262         * Sort parallel arrays. Arrays are sorted in-place. The first array
7263         * determines the order, and is sorted into ascending order.
7264         * <p>
7265         * Implementation inspired by this stackoverflow page: <a href=
7266         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7267         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7268         * get-a-sorted-list-of-indices-of-an-array </a>
7269         * 
7270         * @param main
7271         *            the values to use for determining the order
7272         * @param indices
7273         *            the second array
7274         */
7275        public static void parallelQuicksortAscending(final byte[] main, final double[] indices) {
7276                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
7277        }
7278        
7279    /**
7280         * Sort parallel arrays. Arrays are sorted in-place. The first array
7281         * determines the order, and is sorted into ascending order.
7282         * <p>
7283         * Implementation inspired by this stackoverflow page: <a href=
7284         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7285         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7286         * get-a-sorted-list-of-indices-of-an-array </a>
7287         * 
7288         * @param main
7289         *            the values to use for determining the order
7290         * @param indices
7291         *            the second array
7292         * @param left
7293         *            the starting index
7294         * @param right
7295         *            the ending index
7296         */
7297        public static void
7298                        parallelQuicksortAscending(final byte[] main, final double[] indices, final int left, final int right)
7299        {
7300                if (right <= left)
7301                        return;
7302
7303                final int i = partitionAsc(main, indices, left, right);
7304
7305                parallelQuicksortAscending(main, indices, left, i - 1);
7306                parallelQuicksortAscending(main, indices, i + 1, right);
7307        }
7308
7309        // partition a[left] to a[right], assumes left < right
7310        private static int partitionAsc(final byte[] a, final double[] index, final int left, final int right) {
7311                int i = left - 1;
7312                int j = right;
7313                while (true) {
7314                        while (a[++i] < a[right])
7315                                // find item on left to swap
7316                                ; // a[right] acts as sentinel
7317                        while (a[right] < a[--j])
7318                                // find item on right to swap
7319                                if (j == left)
7320                                        break; // don't go out-of-bounds
7321                        if (i >= j)
7322                                break; // check if pointers cross
7323                        exch(a, index, i, j); // swap two elements into place
7324                }
7325                exch(a, index, i, right); // swap with partition element
7326                return i;
7327        }
7328
7329    
7330    /**
7331         * Sort parallel arrays. Arrays are sorted in-place. The first array
7332         * determines the order, and is sorted into ascending order.
7333         * <p>
7334         * Implementation inspired by this stackoverflow page: <a href=
7335         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7336         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7337         * get-a-sorted-list-of-indices-of-an-array </a>
7338         * 
7339         * @param main
7340         *            the values to use for determining the order
7341         * @param indices
7342         *            the second array
7343         */
7344        public static void parallelQuicksortAscending(final short[] main, final double[] indices) {
7345                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
7346        }
7347        
7348    /**
7349         * Sort parallel arrays. Arrays are sorted in-place. The first array
7350         * determines the order, and is sorted into ascending order.
7351         * <p>
7352         * Implementation inspired by this stackoverflow page: <a href=
7353         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7354         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7355         * get-a-sorted-list-of-indices-of-an-array </a>
7356         * 
7357         * @param main
7358         *            the values to use for determining the order
7359         * @param indices
7360         *            the second array
7361         * @param left
7362         *            the starting index
7363         * @param right
7364         *            the ending index
7365         */
7366        public static void
7367                        parallelQuicksortAscending(final short[] main, final double[] indices, final int left, final int right)
7368        {
7369                if (right <= left)
7370                        return;
7371
7372                final int i = partitionAsc(main, indices, left, right);
7373
7374                parallelQuicksortAscending(main, indices, left, i - 1);
7375                parallelQuicksortAscending(main, indices, i + 1, right);
7376        }
7377
7378        // partition a[left] to a[right], assumes left < right
7379        private static int partitionAsc(final short[] a, final double[] index, final int left, final int right) {
7380                int i = left - 1;
7381                int j = right;
7382                while (true) {
7383                        while (a[++i] < a[right])
7384                                // find item on left to swap
7385                                ; // a[right] acts as sentinel
7386                        while (a[right] < a[--j])
7387                                // find item on right to swap
7388                                if (j == left)
7389                                        break; // don't go out-of-bounds
7390                        if (i >= j)
7391                                break; // check if pointers cross
7392                        exch(a, index, i, j); // swap two elements into place
7393                }
7394                exch(a, index, i, right); // swap with partition element
7395                return i;
7396        }
7397
7398    
7399    /**
7400         * Sort parallel arrays. Arrays are sorted in-place. The first array
7401         * determines the order, and is sorted into ascending order.
7402         * <p>
7403         * Implementation inspired by this stackoverflow page: <a href=
7404         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7405         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7406         * get-a-sorted-list-of-indices-of-an-array </a>
7407         * 
7408         * @param main
7409         *            the values to use for determining the order
7410         * @param indices
7411         *            the second array
7412         */
7413        public static void parallelQuicksortAscending(final double[] main, final float[] indices) {
7414                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
7415        }
7416        
7417    /**
7418         * Sort parallel arrays. Arrays are sorted in-place. The first array
7419         * determines the order, and is sorted into ascending order.
7420         * <p>
7421         * Implementation inspired by this stackoverflow page: <a href=
7422         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7423         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7424         * get-a-sorted-list-of-indices-of-an-array </a>
7425         * 
7426         * @param main
7427         *            the values to use for determining the order
7428         * @param indices
7429         *            the second array
7430         * @param left
7431         *            the starting index
7432         * @param right
7433         *            the ending index
7434         */
7435        public static void
7436                        parallelQuicksortAscending(final double[] main, final float[] indices, final int left, final int right)
7437        {
7438                if (right <= left)
7439                        return;
7440
7441                final int i = partitionAsc(main, indices, left, right);
7442
7443                parallelQuicksortAscending(main, indices, left, i - 1);
7444                parallelQuicksortAscending(main, indices, i + 1, right);
7445        }
7446
7447        // partition a[left] to a[right], assumes left < right
7448        private static int partitionAsc(final double[] a, final float[] index, final int left, final int right) {
7449                int i = left - 1;
7450                int j = right;
7451                while (true) {
7452                        while (a[++i] < a[right])
7453                                // find item on left to swap
7454                                ; // a[right] acts as sentinel
7455                        while (a[right] < a[--j])
7456                                // find item on right to swap
7457                                if (j == left)
7458                                        break; // don't go out-of-bounds
7459                        if (i >= j)
7460                                break; // check if pointers cross
7461                        exch(a, index, i, j); // swap two elements into place
7462                }
7463                exch(a, index, i, right); // swap with partition element
7464                return i;
7465        }
7466
7467    
7468    /**
7469         * Sort parallel arrays. Arrays are sorted in-place. The first array
7470         * determines the order, and is sorted into ascending order.
7471         * <p>
7472         * Implementation inspired by this stackoverflow page: <a href=
7473         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7474         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7475         * get-a-sorted-list-of-indices-of-an-array </a>
7476         * 
7477         * @param main
7478         *            the values to use for determining the order
7479         * @param indices
7480         *            the second array
7481         */
7482        public static void parallelQuicksortAscending(final float[] main, final float[] indices) {
7483                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
7484        }
7485        
7486    /**
7487         * Sort parallel arrays. Arrays are sorted in-place. The first array
7488         * determines the order, and is sorted into ascending order.
7489         * <p>
7490         * Implementation inspired by this stackoverflow page: <a href=
7491         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7492         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7493         * get-a-sorted-list-of-indices-of-an-array </a>
7494         * 
7495         * @param main
7496         *            the values to use for determining the order
7497         * @param indices
7498         *            the second array
7499         * @param left
7500         *            the starting index
7501         * @param right
7502         *            the ending index
7503         */
7504        public static void
7505                        parallelQuicksortAscending(final float[] main, final float[] indices, final int left, final int right)
7506        {
7507                if (right <= left)
7508                        return;
7509
7510                final int i = partitionAsc(main, indices, left, right);
7511
7512                parallelQuicksortAscending(main, indices, left, i - 1);
7513                parallelQuicksortAscending(main, indices, i + 1, right);
7514        }
7515
7516        // partition a[left] to a[right], assumes left < right
7517        private static int partitionAsc(final float[] a, final float[] index, final int left, final int right) {
7518                int i = left - 1;
7519                int j = right;
7520                while (true) {
7521                        while (a[++i] < a[right])
7522                                // find item on left to swap
7523                                ; // a[right] acts as sentinel
7524                        while (a[right] < a[--j])
7525                                // find item on right to swap
7526                                if (j == left)
7527                                        break; // don't go out-of-bounds
7528                        if (i >= j)
7529                                break; // check if pointers cross
7530                        exch(a, index, i, j); // swap two elements into place
7531                }
7532                exch(a, index, i, right); // swap with partition element
7533                return i;
7534        }
7535
7536    
7537    /**
7538         * Sort parallel arrays. Arrays are sorted in-place. The first array
7539         * determines the order, and is sorted into ascending order.
7540         * <p>
7541         * Implementation inspired by this stackoverflow page: <a href=
7542         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7543         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7544         * get-a-sorted-list-of-indices-of-an-array </a>
7545         * 
7546         * @param main
7547         *            the values to use for determining the order
7548         * @param indices
7549         *            the second array
7550         */
7551        public static void parallelQuicksortAscending(final int[] main, final float[] indices) {
7552                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
7553        }
7554        
7555    /**
7556         * Sort parallel arrays. Arrays are sorted in-place. The first array
7557         * determines the order, and is sorted into ascending order.
7558         * <p>
7559         * Implementation inspired by this stackoverflow page: <a href=
7560         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7561         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7562         * get-a-sorted-list-of-indices-of-an-array </a>
7563         * 
7564         * @param main
7565         *            the values to use for determining the order
7566         * @param indices
7567         *            the second array
7568         * @param left
7569         *            the starting index
7570         * @param right
7571         *            the ending index
7572         */
7573        public static void
7574                        parallelQuicksortAscending(final int[] main, final float[] indices, final int left, final int right)
7575        {
7576                if (right <= left)
7577                        return;
7578
7579                final int i = partitionAsc(main, indices, left, right);
7580
7581                parallelQuicksortAscending(main, indices, left, i - 1);
7582                parallelQuicksortAscending(main, indices, i + 1, right);
7583        }
7584
7585        // partition a[left] to a[right], assumes left < right
7586        private static int partitionAsc(final int[] a, final float[] index, final int left, final int right) {
7587                int i = left - 1;
7588                int j = right;
7589                while (true) {
7590                        while (a[++i] < a[right])
7591                                // find item on left to swap
7592                                ; // a[right] acts as sentinel
7593                        while (a[right] < a[--j])
7594                                // find item on right to swap
7595                                if (j == left)
7596                                        break; // don't go out-of-bounds
7597                        if (i >= j)
7598                                break; // check if pointers cross
7599                        exch(a, index, i, j); // swap two elements into place
7600                }
7601                exch(a, index, i, right); // swap with partition element
7602                return i;
7603        }
7604
7605    
7606    /**
7607         * Sort parallel arrays. Arrays are sorted in-place. The first array
7608         * determines the order, and is sorted into ascending order.
7609         * <p>
7610         * Implementation inspired by this stackoverflow page: <a href=
7611         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7612         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7613         * get-a-sorted-list-of-indices-of-an-array </a>
7614         * 
7615         * @param main
7616         *            the values to use for determining the order
7617         * @param indices
7618         *            the second array
7619         */
7620        public static void parallelQuicksortAscending(final long[] main, final float[] indices) {
7621                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
7622        }
7623        
7624    /**
7625         * Sort parallel arrays. Arrays are sorted in-place. The first array
7626         * determines the order, and is sorted into ascending order.
7627         * <p>
7628         * Implementation inspired by this stackoverflow page: <a href=
7629         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7630         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7631         * get-a-sorted-list-of-indices-of-an-array </a>
7632         * 
7633         * @param main
7634         *            the values to use for determining the order
7635         * @param indices
7636         *            the second array
7637         * @param left
7638         *            the starting index
7639         * @param right
7640         *            the ending index
7641         */
7642        public static void
7643                        parallelQuicksortAscending(final long[] main, final float[] indices, final int left, final int right)
7644        {
7645                if (right <= left)
7646                        return;
7647
7648                final int i = partitionAsc(main, indices, left, right);
7649
7650                parallelQuicksortAscending(main, indices, left, i - 1);
7651                parallelQuicksortAscending(main, indices, i + 1, right);
7652        }
7653
7654        // partition a[left] to a[right], assumes left < right
7655        private static int partitionAsc(final long[] a, final float[] index, final int left, final int right) {
7656                int i = left - 1;
7657                int j = right;
7658                while (true) {
7659                        while (a[++i] < a[right])
7660                                // find item on left to swap
7661                                ; // a[right] acts as sentinel
7662                        while (a[right] < a[--j])
7663                                // find item on right to swap
7664                                if (j == left)
7665                                        break; // don't go out-of-bounds
7666                        if (i >= j)
7667                                break; // check if pointers cross
7668                        exch(a, index, i, j); // swap two elements into place
7669                }
7670                exch(a, index, i, right); // swap with partition element
7671                return i;
7672        }
7673
7674    
7675    /**
7676         * Sort parallel arrays. Arrays are sorted in-place. The first array
7677         * determines the order, and is sorted into ascending order.
7678         * <p>
7679         * Implementation inspired by this stackoverflow page: <a href=
7680         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7681         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7682         * get-a-sorted-list-of-indices-of-an-array </a>
7683         * 
7684         * @param main
7685         *            the values to use for determining the order
7686         * @param indices
7687         *            the second array
7688         */
7689        public static void parallelQuicksortAscending(final byte[] main, final float[] indices) {
7690                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
7691        }
7692        
7693    /**
7694         * Sort parallel arrays. Arrays are sorted in-place. The first array
7695         * determines the order, and is sorted into ascending order.
7696         * <p>
7697         * Implementation inspired by this stackoverflow page: <a href=
7698         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7699         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7700         * get-a-sorted-list-of-indices-of-an-array </a>
7701         * 
7702         * @param main
7703         *            the values to use for determining the order
7704         * @param indices
7705         *            the second array
7706         * @param left
7707         *            the starting index
7708         * @param right
7709         *            the ending index
7710         */
7711        public static void
7712                        parallelQuicksortAscending(final byte[] main, final float[] indices, final int left, final int right)
7713        {
7714                if (right <= left)
7715                        return;
7716
7717                final int i = partitionAsc(main, indices, left, right);
7718
7719                parallelQuicksortAscending(main, indices, left, i - 1);
7720                parallelQuicksortAscending(main, indices, i + 1, right);
7721        }
7722
7723        // partition a[left] to a[right], assumes left < right
7724        private static int partitionAsc(final byte[] a, final float[] index, final int left, final int right) {
7725                int i = left - 1;
7726                int j = right;
7727                while (true) {
7728                        while (a[++i] < a[right])
7729                                // find item on left to swap
7730                                ; // a[right] acts as sentinel
7731                        while (a[right] < a[--j])
7732                                // find item on right to swap
7733                                if (j == left)
7734                                        break; // don't go out-of-bounds
7735                        if (i >= j)
7736                                break; // check if pointers cross
7737                        exch(a, index, i, j); // swap two elements into place
7738                }
7739                exch(a, index, i, right); // swap with partition element
7740                return i;
7741        }
7742
7743    
7744    /**
7745         * Sort parallel arrays. Arrays are sorted in-place. The first array
7746         * determines the order, and is sorted into ascending order.
7747         * <p>
7748         * Implementation inspired by this stackoverflow page: <a href=
7749         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7750         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7751         * get-a-sorted-list-of-indices-of-an-array </a>
7752         * 
7753         * @param main
7754         *            the values to use for determining the order
7755         * @param indices
7756         *            the second array
7757         */
7758        public static void parallelQuicksortAscending(final short[] main, final float[] indices) {
7759                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
7760        }
7761        
7762    /**
7763         * Sort parallel arrays. Arrays are sorted in-place. The first array
7764         * determines the order, and is sorted into ascending order.
7765         * <p>
7766         * Implementation inspired by this stackoverflow page: <a href=
7767         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7768         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7769         * get-a-sorted-list-of-indices-of-an-array </a>
7770         * 
7771         * @param main
7772         *            the values to use for determining the order
7773         * @param indices
7774         *            the second array
7775         * @param left
7776         *            the starting index
7777         * @param right
7778         *            the ending index
7779         */
7780        public static void
7781                        parallelQuicksortAscending(final short[] main, final float[] indices, final int left, final int right)
7782        {
7783                if (right <= left)
7784                        return;
7785
7786                final int i = partitionAsc(main, indices, left, right);
7787
7788                parallelQuicksortAscending(main, indices, left, i - 1);
7789                parallelQuicksortAscending(main, indices, i + 1, right);
7790        }
7791
7792        // partition a[left] to a[right], assumes left < right
7793        private static int partitionAsc(final short[] a, final float[] index, final int left, final int right) {
7794                int i = left - 1;
7795                int j = right;
7796                while (true) {
7797                        while (a[++i] < a[right])
7798                                // find item on left to swap
7799                                ; // a[right] acts as sentinel
7800                        while (a[right] < a[--j])
7801                                // find item on right to swap
7802                                if (j == left)
7803                                        break; // don't go out-of-bounds
7804                        if (i >= j)
7805                                break; // check if pointers cross
7806                        exch(a, index, i, j); // swap two elements into place
7807                }
7808                exch(a, index, i, right); // swap with partition element
7809                return i;
7810        }
7811
7812    
7813    /**
7814         * Sort parallel arrays. Arrays are sorted in-place. The first array
7815         * determines the order, and is sorted into ascending order.
7816         * <p>
7817         * Implementation inspired by this stackoverflow page: <a href=
7818         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7819         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7820         * get-a-sorted-list-of-indices-of-an-array </a>
7821         * 
7822         * @param main
7823         *            the values to use for determining the order
7824         * @param indices
7825         *            the second array
7826         */
7827        public static void parallelQuicksortAscending(final double[] main, final int[] indices) {
7828                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
7829        }
7830        
7831    /**
7832         * Sort parallel arrays. Arrays are sorted in-place. The first array
7833         * determines the order, and is sorted into ascending order.
7834         * <p>
7835         * Implementation inspired by this stackoverflow page: <a href=
7836         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7837         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7838         * get-a-sorted-list-of-indices-of-an-array </a>
7839         * 
7840         * @param main
7841         *            the values to use for determining the order
7842         * @param indices
7843         *            the second array
7844         * @param left
7845         *            the starting index
7846         * @param right
7847         *            the ending index
7848         */
7849        public static void
7850                        parallelQuicksortAscending(final double[] main, final int[] indices, final int left, final int right)
7851        {
7852                if (right <= left)
7853                        return;
7854
7855                final int i = partitionAsc(main, indices, left, right);
7856
7857                parallelQuicksortAscending(main, indices, left, i - 1);
7858                parallelQuicksortAscending(main, indices, i + 1, right);
7859        }
7860
7861        // partition a[left] to a[right], assumes left < right
7862        private static int partitionAsc(final double[] a, final int[] index, final int left, final int right) {
7863                int i = left - 1;
7864                int j = right;
7865                while (true) {
7866                        while (a[++i] < a[right])
7867                                // find item on left to swap
7868                                ; // a[right] acts as sentinel
7869                        while (a[right] < a[--j])
7870                                // find item on right to swap
7871                                if (j == left)
7872                                        break; // don't go out-of-bounds
7873                        if (i >= j)
7874                                break; // check if pointers cross
7875                        exch(a, index, i, j); // swap two elements into place
7876                }
7877                exch(a, index, i, right); // swap with partition element
7878                return i;
7879        }
7880
7881    
7882    /**
7883         * Sort parallel arrays. Arrays are sorted in-place. The first array
7884         * determines the order, and is sorted into ascending order.
7885         * <p>
7886         * Implementation inspired by this stackoverflow page: <a href=
7887         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7888         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7889         * get-a-sorted-list-of-indices-of-an-array </a>
7890         * 
7891         * @param main
7892         *            the values to use for determining the order
7893         * @param indices
7894         *            the second array
7895         */
7896        public static void parallelQuicksortAscending(final float[] main, final int[] indices) {
7897                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
7898        }
7899        
7900    /**
7901         * Sort parallel arrays. Arrays are sorted in-place. The first array
7902         * determines the order, and is sorted into ascending order.
7903         * <p>
7904         * Implementation inspired by this stackoverflow page: <a href=
7905         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7906         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7907         * get-a-sorted-list-of-indices-of-an-array </a>
7908         * 
7909         * @param main
7910         *            the values to use for determining the order
7911         * @param indices
7912         *            the second array
7913         * @param left
7914         *            the starting index
7915         * @param right
7916         *            the ending index
7917         */
7918        public static void
7919                        parallelQuicksortAscending(final float[] main, final int[] indices, final int left, final int right)
7920        {
7921                if (right <= left)
7922                        return;
7923
7924                final int i = partitionAsc(main, indices, left, right);
7925
7926                parallelQuicksortAscending(main, indices, left, i - 1);
7927                parallelQuicksortAscending(main, indices, i + 1, right);
7928        }
7929
7930        // partition a[left] to a[right], assumes left < right
7931        private static int partitionAsc(final float[] a, final int[] index, final int left, final int right) {
7932                int i = left - 1;
7933                int j = right;
7934                while (true) {
7935                        while (a[++i] < a[right])
7936                                // find item on left to swap
7937                                ; // a[right] acts as sentinel
7938                        while (a[right] < a[--j])
7939                                // find item on right to swap
7940                                if (j == left)
7941                                        break; // don't go out-of-bounds
7942                        if (i >= j)
7943                                break; // check if pointers cross
7944                        exch(a, index, i, j); // swap two elements into place
7945                }
7946                exch(a, index, i, right); // swap with partition element
7947                return i;
7948        }
7949
7950    
7951    /**
7952         * Sort parallel arrays. Arrays are sorted in-place. The first array
7953         * determines the order, and is sorted into ascending order.
7954         * <p>
7955         * Implementation inspired by this stackoverflow page: <a href=
7956         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7957         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7958         * get-a-sorted-list-of-indices-of-an-array </a>
7959         * 
7960         * @param main
7961         *            the values to use for determining the order
7962         * @param indices
7963         *            the second array
7964         */
7965        public static void parallelQuicksortAscending(final int[] main, final int[] indices) {
7966                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
7967        }
7968        
7969    /**
7970         * Sort parallel arrays. Arrays are sorted in-place. The first array
7971         * determines the order, and is sorted into ascending order.
7972         * <p>
7973         * Implementation inspired by this stackoverflow page: <a href=
7974         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7975         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7976         * get-a-sorted-list-of-indices-of-an-array </a>
7977         * 
7978         * @param main
7979         *            the values to use for determining the order
7980         * @param indices
7981         *            the second array
7982         * @param left
7983         *            the starting index
7984         * @param right
7985         *            the ending index
7986         */
7987        public static void
7988                        parallelQuicksortAscending(final int[] main, final int[] indices, final int left, final int right)
7989        {
7990                if (right <= left)
7991                        return;
7992
7993                final int i = partitionAsc(main, indices, left, right);
7994
7995                parallelQuicksortAscending(main, indices, left, i - 1);
7996                parallelQuicksortAscending(main, indices, i + 1, right);
7997        }
7998
7999        // partition a[left] to a[right], assumes left < right
8000        private static int partitionAsc(final int[] a, final int[] index, final int left, final int right) {
8001                int i = left - 1;
8002                int j = right;
8003                while (true) {
8004                        while (a[++i] < a[right])
8005                                // find item on left to swap
8006                                ; // a[right] acts as sentinel
8007                        while (a[right] < a[--j])
8008                                // find item on right to swap
8009                                if (j == left)
8010                                        break; // don't go out-of-bounds
8011                        if (i >= j)
8012                                break; // check if pointers cross
8013                        exch(a, index, i, j); // swap two elements into place
8014                }
8015                exch(a, index, i, right); // swap with partition element
8016                return i;
8017        }
8018
8019    
8020    /**
8021         * Sort parallel arrays. Arrays are sorted in-place. The first array
8022         * determines the order, and is sorted into ascending order.
8023         * <p>
8024         * Implementation inspired by this stackoverflow page: <a href=
8025         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8026         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8027         * get-a-sorted-list-of-indices-of-an-array </a>
8028         * 
8029         * @param main
8030         *            the values to use for determining the order
8031         * @param indices
8032         *            the second array
8033         */
8034        public static void parallelQuicksortAscending(final long[] main, final int[] indices) {
8035                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
8036        }
8037        
8038    /**
8039         * Sort parallel arrays. Arrays are sorted in-place. The first array
8040         * determines the order, and is sorted into ascending order.
8041         * <p>
8042         * Implementation inspired by this stackoverflow page: <a href=
8043         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8044         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8045         * get-a-sorted-list-of-indices-of-an-array </a>
8046         * 
8047         * @param main
8048         *            the values to use for determining the order
8049         * @param indices
8050         *            the second array
8051         * @param left
8052         *            the starting index
8053         * @param right
8054         *            the ending index
8055         */
8056        public static void
8057                        parallelQuicksortAscending(final long[] main, final int[] indices, final int left, final int right)
8058        {
8059                if (right <= left)
8060                        return;
8061
8062                final int i = partitionAsc(main, indices, left, right);
8063
8064                parallelQuicksortAscending(main, indices, left, i - 1);
8065                parallelQuicksortAscending(main, indices, i + 1, right);
8066        }
8067
8068        // partition a[left] to a[right], assumes left < right
8069        private static int partitionAsc(final long[] a, final int[] index, final int left, final int right) {
8070                int i = left - 1;
8071                int j = right;
8072                while (true) {
8073                        while (a[++i] < a[right])
8074                                // find item on left to swap
8075                                ; // a[right] acts as sentinel
8076                        while (a[right] < a[--j])
8077                                // find item on right to swap
8078                                if (j == left)
8079                                        break; // don't go out-of-bounds
8080                        if (i >= j)
8081                                break; // check if pointers cross
8082                        exch(a, index, i, j); // swap two elements into place
8083                }
8084                exch(a, index, i, right); // swap with partition element
8085                return i;
8086        }
8087
8088    
8089    /**
8090         * Sort parallel arrays. Arrays are sorted in-place. The first array
8091         * determines the order, and is sorted into ascending order.
8092         * <p>
8093         * Implementation inspired by this stackoverflow page: <a href=
8094         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8095         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8096         * get-a-sorted-list-of-indices-of-an-array </a>
8097         * 
8098         * @param main
8099         *            the values to use for determining the order
8100         * @param indices
8101         *            the second array
8102         */
8103        public static void parallelQuicksortAscending(final byte[] main, final int[] indices) {
8104                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
8105        }
8106        
8107    /**
8108         * Sort parallel arrays. Arrays are sorted in-place. The first array
8109         * determines the order, and is sorted into ascending order.
8110         * <p>
8111         * Implementation inspired by this stackoverflow page: <a href=
8112         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8113         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8114         * get-a-sorted-list-of-indices-of-an-array </a>
8115         * 
8116         * @param main
8117         *            the values to use for determining the order
8118         * @param indices
8119         *            the second array
8120         * @param left
8121         *            the starting index
8122         * @param right
8123         *            the ending index
8124         */
8125        public static void
8126                        parallelQuicksortAscending(final byte[] main, final int[] indices, final int left, final int right)
8127        {
8128                if (right <= left)
8129                        return;
8130
8131                final int i = partitionAsc(main, indices, left, right);
8132
8133                parallelQuicksortAscending(main, indices, left, i - 1);
8134                parallelQuicksortAscending(main, indices, i + 1, right);
8135        }
8136
8137        // partition a[left] to a[right], assumes left < right
8138        private static int partitionAsc(final byte[] a, final int[] index, final int left, final int right) {
8139                int i = left - 1;
8140                int j = right;
8141                while (true) {
8142                        while (a[++i] < a[right])
8143                                // find item on left to swap
8144                                ; // a[right] acts as sentinel
8145                        while (a[right] < a[--j])
8146                                // find item on right to swap
8147                                if (j == left)
8148                                        break; // don't go out-of-bounds
8149                        if (i >= j)
8150                                break; // check if pointers cross
8151                        exch(a, index, i, j); // swap two elements into place
8152                }
8153                exch(a, index, i, right); // swap with partition element
8154                return i;
8155        }
8156
8157    
8158    /**
8159         * Sort parallel arrays. Arrays are sorted in-place. The first array
8160         * determines the order, and is sorted into ascending order.
8161         * <p>
8162         * Implementation inspired by this stackoverflow page: <a href=
8163         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8164         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8165         * get-a-sorted-list-of-indices-of-an-array </a>
8166         * 
8167         * @param main
8168         *            the values to use for determining the order
8169         * @param indices
8170         *            the second array
8171         */
8172        public static void parallelQuicksortAscending(final short[] main, final int[] indices) {
8173                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
8174        }
8175        
8176    /**
8177         * Sort parallel arrays. Arrays are sorted in-place. The first array
8178         * determines the order, and is sorted into ascending order.
8179         * <p>
8180         * Implementation inspired by this stackoverflow page: <a href=
8181         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8182         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8183         * get-a-sorted-list-of-indices-of-an-array </a>
8184         * 
8185         * @param main
8186         *            the values to use for determining the order
8187         * @param indices
8188         *            the second array
8189         * @param left
8190         *            the starting index
8191         * @param right
8192         *            the ending index
8193         */
8194        public static void
8195                        parallelQuicksortAscending(final short[] main, final int[] indices, final int left, final int right)
8196        {
8197                if (right <= left)
8198                        return;
8199
8200                final int i = partitionAsc(main, indices, left, right);
8201
8202                parallelQuicksortAscending(main, indices, left, i - 1);
8203                parallelQuicksortAscending(main, indices, i + 1, right);
8204        }
8205
8206        // partition a[left] to a[right], assumes left < right
8207        private static int partitionAsc(final short[] a, final int[] index, final int left, final int right) {
8208                int i = left - 1;
8209                int j = right;
8210                while (true) {
8211                        while (a[++i] < a[right])
8212                                // find item on left to swap
8213                                ; // a[right] acts as sentinel
8214                        while (a[right] < a[--j])
8215                                // find item on right to swap
8216                                if (j == left)
8217                                        break; // don't go out-of-bounds
8218                        if (i >= j)
8219                                break; // check if pointers cross
8220                        exch(a, index, i, j); // swap two elements into place
8221                }
8222                exch(a, index, i, right); // swap with partition element
8223                return i;
8224        }
8225
8226    
8227    /**
8228         * Sort parallel arrays. Arrays are sorted in-place. The first array
8229         * determines the order, and is sorted into ascending order.
8230         * <p>
8231         * Implementation inspired by this stackoverflow page: <a href=
8232         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8233         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8234         * get-a-sorted-list-of-indices-of-an-array </a>
8235         * 
8236         * @param main
8237         *            the values to use for determining the order
8238         * @param indices
8239         *            the second array
8240         */
8241        public static void parallelQuicksortAscending(final double[] main, final long[] indices) {
8242                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
8243        }
8244        
8245    /**
8246         * Sort parallel arrays. Arrays are sorted in-place. The first array
8247         * determines the order, and is sorted into ascending order.
8248         * <p>
8249         * Implementation inspired by this stackoverflow page: <a href=
8250         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8251         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8252         * get-a-sorted-list-of-indices-of-an-array </a>
8253         * 
8254         * @param main
8255         *            the values to use for determining the order
8256         * @param indices
8257         *            the second array
8258         * @param left
8259         *            the starting index
8260         * @param right
8261         *            the ending index
8262         */
8263        public static void
8264                        parallelQuicksortAscending(final double[] main, final long[] indices, final int left, final int right)
8265        {
8266                if (right <= left)
8267                        return;
8268
8269                final int i = partitionAsc(main, indices, left, right);
8270
8271                parallelQuicksortAscending(main, indices, left, i - 1);
8272                parallelQuicksortAscending(main, indices, i + 1, right);
8273        }
8274
8275        // partition a[left] to a[right], assumes left < right
8276        private static int partitionAsc(final double[] a, final long[] index, final int left, final int right) {
8277                int i = left - 1;
8278                int j = right;
8279                while (true) {
8280                        while (a[++i] < a[right])
8281                                // find item on left to swap
8282                                ; // a[right] acts as sentinel
8283                        while (a[right] < a[--j])
8284                                // find item on right to swap
8285                                if (j == left)
8286                                        break; // don't go out-of-bounds
8287                        if (i >= j)
8288                                break; // check if pointers cross
8289                        exch(a, index, i, j); // swap two elements into place
8290                }
8291                exch(a, index, i, right); // swap with partition element
8292                return i;
8293        }
8294
8295    
8296    /**
8297         * Sort parallel arrays. Arrays are sorted in-place. The first array
8298         * determines the order, and is sorted into ascending order.
8299         * <p>
8300         * Implementation inspired by this stackoverflow page: <a href=
8301         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8302         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8303         * get-a-sorted-list-of-indices-of-an-array </a>
8304         * 
8305         * @param main
8306         *            the values to use for determining the order
8307         * @param indices
8308         *            the second array
8309         */
8310        public static void parallelQuicksortAscending(final float[] main, final long[] indices) {
8311                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
8312        }
8313        
8314    /**
8315         * Sort parallel arrays. Arrays are sorted in-place. The first array
8316         * determines the order, and is sorted into ascending order.
8317         * <p>
8318         * Implementation inspired by this stackoverflow page: <a href=
8319         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8320         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8321         * get-a-sorted-list-of-indices-of-an-array </a>
8322         * 
8323         * @param main
8324         *            the values to use for determining the order
8325         * @param indices
8326         *            the second array
8327         * @param left
8328         *            the starting index
8329         * @param right
8330         *            the ending index
8331         */
8332        public static void
8333                        parallelQuicksortAscending(final float[] main, final long[] indices, final int left, final int right)
8334        {
8335                if (right <= left)
8336                        return;
8337
8338                final int i = partitionAsc(main, indices, left, right);
8339
8340                parallelQuicksortAscending(main, indices, left, i - 1);
8341                parallelQuicksortAscending(main, indices, i + 1, right);
8342        }
8343
8344        // partition a[left] to a[right], assumes left < right
8345        private static int partitionAsc(final float[] a, final long[] index, final int left, final int right) {
8346                int i = left - 1;
8347                int j = right;
8348                while (true) {
8349                        while (a[++i] < a[right])
8350                                // find item on left to swap
8351                                ; // a[right] acts as sentinel
8352                        while (a[right] < a[--j])
8353                                // find item on right to swap
8354                                if (j == left)
8355                                        break; // don't go out-of-bounds
8356                        if (i >= j)
8357                                break; // check if pointers cross
8358                        exch(a, index, i, j); // swap two elements into place
8359                }
8360                exch(a, index, i, right); // swap with partition element
8361                return i;
8362        }
8363
8364    
8365    /**
8366         * Sort parallel arrays. Arrays are sorted in-place. The first array
8367         * determines the order, and is sorted into ascending order.
8368         * <p>
8369         * Implementation inspired by this stackoverflow page: <a href=
8370         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8371         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8372         * get-a-sorted-list-of-indices-of-an-array </a>
8373         * 
8374         * @param main
8375         *            the values to use for determining the order
8376         * @param indices
8377         *            the second array
8378         */
8379        public static void parallelQuicksortAscending(final int[] main, final long[] indices) {
8380                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
8381        }
8382        
8383    /**
8384         * Sort parallel arrays. Arrays are sorted in-place. The first array
8385         * determines the order, and is sorted into ascending order.
8386         * <p>
8387         * Implementation inspired by this stackoverflow page: <a href=
8388         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8389         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8390         * get-a-sorted-list-of-indices-of-an-array </a>
8391         * 
8392         * @param main
8393         *            the values to use for determining the order
8394         * @param indices
8395         *            the second array
8396         * @param left
8397         *            the starting index
8398         * @param right
8399         *            the ending index
8400         */
8401        public static void
8402                        parallelQuicksortAscending(final int[] main, final long[] indices, final int left, final int right)
8403        {
8404                if (right <= left)
8405                        return;
8406
8407                final int i = partitionAsc(main, indices, left, right);
8408
8409                parallelQuicksortAscending(main, indices, left, i - 1);
8410                parallelQuicksortAscending(main, indices, i + 1, right);
8411        }
8412
8413        // partition a[left] to a[right], assumes left < right
8414        private static int partitionAsc(final int[] a, final long[] index, final int left, final int right) {
8415                int i = left - 1;
8416                int j = right;
8417                while (true) {
8418                        while (a[++i] < a[right])
8419                                // find item on left to swap
8420                                ; // a[right] acts as sentinel
8421                        while (a[right] < a[--j])
8422                                // find item on right to swap
8423                                if (j == left)
8424                                        break; // don't go out-of-bounds
8425                        if (i >= j)
8426                                break; // check if pointers cross
8427                        exch(a, index, i, j); // swap two elements into place
8428                }
8429                exch(a, index, i, right); // swap with partition element
8430                return i;
8431        }
8432
8433    
8434    /**
8435         * Sort parallel arrays. Arrays are sorted in-place. The first array
8436         * determines the order, and is sorted into ascending order.
8437         * <p>
8438         * Implementation inspired by this stackoverflow page: <a href=
8439         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8440         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8441         * get-a-sorted-list-of-indices-of-an-array </a>
8442         * 
8443         * @param main
8444         *            the values to use for determining the order
8445         * @param indices
8446         *            the second array
8447         */
8448        public static void parallelQuicksortAscending(final long[] main, final long[] indices) {
8449                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
8450        }
8451        
8452    /**
8453         * Sort parallel arrays. Arrays are sorted in-place. The first array
8454         * determines the order, and is sorted into ascending order.
8455         * <p>
8456         * Implementation inspired by this stackoverflow page: <a href=
8457         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8458         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8459         * get-a-sorted-list-of-indices-of-an-array </a>
8460         * 
8461         * @param main
8462         *            the values to use for determining the order
8463         * @param indices
8464         *            the second array
8465         * @param left
8466         *            the starting index
8467         * @param right
8468         *            the ending index
8469         */
8470        public static void
8471                        parallelQuicksortAscending(final long[] main, final long[] indices, final int left, final int right)
8472        {
8473                if (right <= left)
8474                        return;
8475
8476                final int i = partitionAsc(main, indices, left, right);
8477
8478                parallelQuicksortAscending(main, indices, left, i - 1);
8479                parallelQuicksortAscending(main, indices, i + 1, right);
8480        }
8481
8482        // partition a[left] to a[right], assumes left < right
8483        private static int partitionAsc(final long[] a, final long[] index, final int left, final int right) {
8484                int i = left - 1;
8485                int j = right;
8486                while (true) {
8487                        while (a[++i] < a[right])
8488                                // find item on left to swap
8489                                ; // a[right] acts as sentinel
8490                        while (a[right] < a[--j])
8491                                // find item on right to swap
8492                                if (j == left)
8493                                        break; // don't go out-of-bounds
8494                        if (i >= j)
8495                                break; // check if pointers cross
8496                        exch(a, index, i, j); // swap two elements into place
8497                }
8498                exch(a, index, i, right); // swap with partition element
8499                return i;
8500        }
8501
8502    
8503    /**
8504         * Sort parallel arrays. Arrays are sorted in-place. The first array
8505         * determines the order, and is sorted into ascending order.
8506         * <p>
8507         * Implementation inspired by this stackoverflow page: <a href=
8508         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8509         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8510         * get-a-sorted-list-of-indices-of-an-array </a>
8511         * 
8512         * @param main
8513         *            the values to use for determining the order
8514         * @param indices
8515         *            the second array
8516         */
8517        public static void parallelQuicksortAscending(final byte[] main, final long[] indices) {
8518                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
8519        }
8520        
8521    /**
8522         * Sort parallel arrays. Arrays are sorted in-place. The first array
8523         * determines the order, and is sorted into ascending order.
8524         * <p>
8525         * Implementation inspired by this stackoverflow page: <a href=
8526         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8527         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8528         * get-a-sorted-list-of-indices-of-an-array </a>
8529         * 
8530         * @param main
8531         *            the values to use for determining the order
8532         * @param indices
8533         *            the second array
8534         * @param left
8535         *            the starting index
8536         * @param right
8537         *            the ending index
8538         */
8539        public static void
8540                        parallelQuicksortAscending(final byte[] main, final long[] indices, final int left, final int right)
8541        {
8542                if (right <= left)
8543                        return;
8544
8545                final int i = partitionAsc(main, indices, left, right);
8546
8547                parallelQuicksortAscending(main, indices, left, i - 1);
8548                parallelQuicksortAscending(main, indices, i + 1, right);
8549        }
8550
8551        // partition a[left] to a[right], assumes left < right
8552        private static int partitionAsc(final byte[] a, final long[] index, final int left, final int right) {
8553                int i = left - 1;
8554                int j = right;
8555                while (true) {
8556                        while (a[++i] < a[right])
8557                                // find item on left to swap
8558                                ; // a[right] acts as sentinel
8559                        while (a[right] < a[--j])
8560                                // find item on right to swap
8561                                if (j == left)
8562                                        break; // don't go out-of-bounds
8563                        if (i >= j)
8564                                break; // check if pointers cross
8565                        exch(a, index, i, j); // swap two elements into place
8566                }
8567                exch(a, index, i, right); // swap with partition element
8568                return i;
8569        }
8570
8571    
8572    /**
8573         * Sort parallel arrays. Arrays are sorted in-place. The first array
8574         * determines the order, and is sorted into ascending order.
8575         * <p>
8576         * Implementation inspired by this stackoverflow page: <a href=
8577         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8578         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8579         * get-a-sorted-list-of-indices-of-an-array </a>
8580         * 
8581         * @param main
8582         *            the values to use for determining the order
8583         * @param indices
8584         *            the second array
8585         */
8586        public static void parallelQuicksortAscending(final short[] main, final long[] indices) {
8587                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
8588        }
8589        
8590    /**
8591         * Sort parallel arrays. Arrays are sorted in-place. The first array
8592         * determines the order, and is sorted into ascending order.
8593         * <p>
8594         * Implementation inspired by this stackoverflow page: <a href=
8595         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8596         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8597         * get-a-sorted-list-of-indices-of-an-array </a>
8598         * 
8599         * @param main
8600         *            the values to use for determining the order
8601         * @param indices
8602         *            the second array
8603         * @param left
8604         *            the starting index
8605         * @param right
8606         *            the ending index
8607         */
8608        public static void
8609                        parallelQuicksortAscending(final short[] main, final long[] indices, final int left, final int right)
8610        {
8611                if (right <= left)
8612                        return;
8613
8614                final int i = partitionAsc(main, indices, left, right);
8615
8616                parallelQuicksortAscending(main, indices, left, i - 1);
8617                parallelQuicksortAscending(main, indices, i + 1, right);
8618        }
8619
8620        // partition a[left] to a[right], assumes left < right
8621        private static int partitionAsc(final short[] a, final long[] index, final int left, final int right) {
8622                int i = left - 1;
8623                int j = right;
8624                while (true) {
8625                        while (a[++i] < a[right])
8626                                // find item on left to swap
8627                                ; // a[right] acts as sentinel
8628                        while (a[right] < a[--j])
8629                                // find item on right to swap
8630                                if (j == left)
8631                                        break; // don't go out-of-bounds
8632                        if (i >= j)
8633                                break; // check if pointers cross
8634                        exch(a, index, i, j); // swap two elements into place
8635                }
8636                exch(a, index, i, right); // swap with partition element
8637                return i;
8638        }
8639
8640    
8641    /**
8642         * Sort parallel arrays. Arrays are sorted in-place. The first array
8643         * determines the order, and is sorted into ascending order.
8644         * <p>
8645         * Implementation inspired by this stackoverflow page: <a href=
8646         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8647         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8648         * get-a-sorted-list-of-indices-of-an-array </a>
8649         * 
8650         * @param main
8651         *            the values to use for determining the order
8652         * @param indices
8653         *            the second array
8654         */
8655        public static void parallelQuicksortAscending(final double[] main, final byte[] indices) {
8656                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
8657        }
8658        
8659    /**
8660         * Sort parallel arrays. Arrays are sorted in-place. The first array
8661         * determines the order, and is sorted into ascending order.
8662         * <p>
8663         * Implementation inspired by this stackoverflow page: <a href=
8664         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8665         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8666         * get-a-sorted-list-of-indices-of-an-array </a>
8667         * 
8668         * @param main
8669         *            the values to use for determining the order
8670         * @param indices
8671         *            the second array
8672         * @param left
8673         *            the starting index
8674         * @param right
8675         *            the ending index
8676         */
8677        public static void
8678                        parallelQuicksortAscending(final double[] main, final byte[] indices, final int left, final int right)
8679        {
8680                if (right <= left)
8681                        return;
8682
8683                final int i = partitionAsc(main, indices, left, right);
8684
8685                parallelQuicksortAscending(main, indices, left, i - 1);
8686                parallelQuicksortAscending(main, indices, i + 1, right);
8687        }
8688
8689        // partition a[left] to a[right], assumes left < right
8690        private static int partitionAsc(final double[] a, final byte[] index, final int left, final int right) {
8691                int i = left - 1;
8692                int j = right;
8693                while (true) {
8694                        while (a[++i] < a[right])
8695                                // find item on left to swap
8696                                ; // a[right] acts as sentinel
8697                        while (a[right] < a[--j])
8698                                // find item on right to swap
8699                                if (j == left)
8700                                        break; // don't go out-of-bounds
8701                        if (i >= j)
8702                                break; // check if pointers cross
8703                        exch(a, index, i, j); // swap two elements into place
8704                }
8705                exch(a, index, i, right); // swap with partition element
8706                return i;
8707        }
8708
8709    
8710    /**
8711         * Sort parallel arrays. Arrays are sorted in-place. The first array
8712         * determines the order, and is sorted into ascending order.
8713         * <p>
8714         * Implementation inspired by this stackoverflow page: <a href=
8715         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8716         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8717         * get-a-sorted-list-of-indices-of-an-array </a>
8718         * 
8719         * @param main
8720         *            the values to use for determining the order
8721         * @param indices
8722         *            the second array
8723         */
8724        public static void parallelQuicksortAscending(final float[] main, final byte[] indices) {
8725                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
8726        }
8727        
8728    /**
8729         * Sort parallel arrays. Arrays are sorted in-place. The first array
8730         * determines the order, and is sorted into ascending order.
8731         * <p>
8732         * Implementation inspired by this stackoverflow page: <a href=
8733         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8734         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8735         * get-a-sorted-list-of-indices-of-an-array </a>
8736         * 
8737         * @param main
8738         *            the values to use for determining the order
8739         * @param indices
8740         *            the second array
8741         * @param left
8742         *            the starting index
8743         * @param right
8744         *            the ending index
8745         */
8746        public static void
8747                        parallelQuicksortAscending(final float[] main, final byte[] indices, final int left, final int right)
8748        {
8749                if (right <= left)
8750                        return;
8751
8752                final int i = partitionAsc(main, indices, left, right);
8753
8754                parallelQuicksortAscending(main, indices, left, i - 1);
8755                parallelQuicksortAscending(main, indices, i + 1, right);
8756        }
8757
8758        // partition a[left] to a[right], assumes left < right
8759        private static int partitionAsc(final float[] a, final byte[] index, final int left, final int right) {
8760                int i = left - 1;
8761                int j = right;
8762                while (true) {
8763                        while (a[++i] < a[right])
8764                                // find item on left to swap
8765                                ; // a[right] acts as sentinel
8766                        while (a[right] < a[--j])
8767                                // find item on right to swap
8768                                if (j == left)
8769                                        break; // don't go out-of-bounds
8770                        if (i >= j)
8771                                break; // check if pointers cross
8772                        exch(a, index, i, j); // swap two elements into place
8773                }
8774                exch(a, index, i, right); // swap with partition element
8775                return i;
8776        }
8777
8778    
8779    /**
8780         * Sort parallel arrays. Arrays are sorted in-place. The first array
8781         * determines the order, and is sorted into ascending order.
8782         * <p>
8783         * Implementation inspired by this stackoverflow page: <a href=
8784         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8785         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8786         * get-a-sorted-list-of-indices-of-an-array </a>
8787         * 
8788         * @param main
8789         *            the values to use for determining the order
8790         * @param indices
8791         *            the second array
8792         */
8793        public static void parallelQuicksortAscending(final int[] main, final byte[] indices) {
8794                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
8795        }
8796        
8797    /**
8798         * Sort parallel arrays. Arrays are sorted in-place. The first array
8799         * determines the order, and is sorted into ascending order.
8800         * <p>
8801         * Implementation inspired by this stackoverflow page: <a href=
8802         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8803         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8804         * get-a-sorted-list-of-indices-of-an-array </a>
8805         * 
8806         * @param main
8807         *            the values to use for determining the order
8808         * @param indices
8809         *            the second array
8810         * @param left
8811         *            the starting index
8812         * @param right
8813         *            the ending index
8814         */
8815        public static void
8816                        parallelQuicksortAscending(final int[] main, final byte[] indices, final int left, final int right)
8817        {
8818                if (right <= left)
8819                        return;
8820
8821                final int i = partitionAsc(main, indices, left, right);
8822
8823                parallelQuicksortAscending(main, indices, left, i - 1);
8824                parallelQuicksortAscending(main, indices, i + 1, right);
8825        }
8826
8827        // partition a[left] to a[right], assumes left < right
8828        private static int partitionAsc(final int[] a, final byte[] index, final int left, final int right) {
8829                int i = left - 1;
8830                int j = right;
8831                while (true) {
8832                        while (a[++i] < a[right])
8833                                // find item on left to swap
8834                                ; // a[right] acts as sentinel
8835                        while (a[right] < a[--j])
8836                                // find item on right to swap
8837                                if (j == left)
8838                                        break; // don't go out-of-bounds
8839                        if (i >= j)
8840                                break; // check if pointers cross
8841                        exch(a, index, i, j); // swap two elements into place
8842                }
8843                exch(a, index, i, right); // swap with partition element
8844                return i;
8845        }
8846
8847    
8848    /**
8849         * Sort parallel arrays. Arrays are sorted in-place. The first array
8850         * determines the order, and is sorted into ascending order.
8851         * <p>
8852         * Implementation inspired by this stackoverflow page: <a href=
8853         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8854         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8855         * get-a-sorted-list-of-indices-of-an-array </a>
8856         * 
8857         * @param main
8858         *            the values to use for determining the order
8859         * @param indices
8860         *            the second array
8861         */
8862        public static void parallelQuicksortAscending(final long[] main, final byte[] indices) {
8863                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
8864        }
8865        
8866    /**
8867         * Sort parallel arrays. Arrays are sorted in-place. The first array
8868         * determines the order, and is sorted into ascending order.
8869         * <p>
8870         * Implementation inspired by this stackoverflow page: <a href=
8871         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8872         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8873         * get-a-sorted-list-of-indices-of-an-array </a>
8874         * 
8875         * @param main
8876         *            the values to use for determining the order
8877         * @param indices
8878         *            the second array
8879         * @param left
8880         *            the starting index
8881         * @param right
8882         *            the ending index
8883         */
8884        public static void
8885                        parallelQuicksortAscending(final long[] main, final byte[] indices, final int left, final int right)
8886        {
8887                if (right <= left)
8888                        return;
8889
8890                final int i = partitionAsc(main, indices, left, right);
8891
8892                parallelQuicksortAscending(main, indices, left, i - 1);
8893                parallelQuicksortAscending(main, indices, i + 1, right);
8894        }
8895
8896        // partition a[left] to a[right], assumes left < right
8897        private static int partitionAsc(final long[] a, final byte[] index, final int left, final int right) {
8898                int i = left - 1;
8899                int j = right;
8900                while (true) {
8901                        while (a[++i] < a[right])
8902                                // find item on left to swap
8903                                ; // a[right] acts as sentinel
8904                        while (a[right] < a[--j])
8905                                // find item on right to swap
8906                                if (j == left)
8907                                        break; // don't go out-of-bounds
8908                        if (i >= j)
8909                                break; // check if pointers cross
8910                        exch(a, index, i, j); // swap two elements into place
8911                }
8912                exch(a, index, i, right); // swap with partition element
8913                return i;
8914        }
8915
8916    
8917    /**
8918         * Sort parallel arrays. Arrays are sorted in-place. The first array
8919         * determines the order, and is sorted into ascending order.
8920         * <p>
8921         * Implementation inspired by this stackoverflow page: <a href=
8922         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8923         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8924         * get-a-sorted-list-of-indices-of-an-array </a>
8925         * 
8926         * @param main
8927         *            the values to use for determining the order
8928         * @param indices
8929         *            the second array
8930         */
8931        public static void parallelQuicksortAscending(final byte[] main, final byte[] indices) {
8932                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
8933        }
8934        
8935    /**
8936         * Sort parallel arrays. Arrays are sorted in-place. The first array
8937         * determines the order, and is sorted into ascending order.
8938         * <p>
8939         * Implementation inspired by this stackoverflow page: <a href=
8940         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8941         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8942         * get-a-sorted-list-of-indices-of-an-array </a>
8943         * 
8944         * @param main
8945         *            the values to use for determining the order
8946         * @param indices
8947         *            the second array
8948         * @param left
8949         *            the starting index
8950         * @param right
8951         *            the ending index
8952         */
8953        public static void
8954                        parallelQuicksortAscending(final byte[] main, final byte[] indices, final int left, final int right)
8955        {
8956                if (right <= left)
8957                        return;
8958
8959                final int i = partitionAsc(main, indices, left, right);
8960
8961                parallelQuicksortAscending(main, indices, left, i - 1);
8962                parallelQuicksortAscending(main, indices, i + 1, right);
8963        }
8964
8965        // partition a[left] to a[right], assumes left < right
8966        private static int partitionAsc(final byte[] a, final byte[] index, final int left, final int right) {
8967                int i = left - 1;
8968                int j = right;
8969                while (true) {
8970                        while (a[++i] < a[right])
8971                                // find item on left to swap
8972                                ; // a[right] acts as sentinel
8973                        while (a[right] < a[--j])
8974                                // find item on right to swap
8975                                if (j == left)
8976                                        break; // don't go out-of-bounds
8977                        if (i >= j)
8978                                break; // check if pointers cross
8979                        exch(a, index, i, j); // swap two elements into place
8980                }
8981                exch(a, index, i, right); // swap with partition element
8982                return i;
8983        }
8984
8985    
8986    /**
8987         * Sort parallel arrays. Arrays are sorted in-place. The first array
8988         * determines the order, and is sorted into ascending order.
8989         * <p>
8990         * Implementation inspired by this stackoverflow page: <a href=
8991         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8992         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8993         * get-a-sorted-list-of-indices-of-an-array </a>
8994         * 
8995         * @param main
8996         *            the values to use for determining the order
8997         * @param indices
8998         *            the second array
8999         */
9000        public static void parallelQuicksortAscending(final short[] main, final byte[] indices) {
9001                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
9002        }
9003        
9004    /**
9005         * Sort parallel arrays. Arrays are sorted in-place. The first array
9006         * determines the order, and is sorted into ascending order.
9007         * <p>
9008         * Implementation inspired by this stackoverflow page: <a href=
9009         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
9010         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
9011         * get-a-sorted-list-of-indices-of-an-array </a>
9012         * 
9013         * @param main
9014         *            the values to use for determining the order
9015         * @param indices
9016         *            the second array
9017         * @param left
9018         *            the starting index
9019         * @param right
9020         *            the ending index
9021         */
9022        public static void
9023                        parallelQuicksortAscending(final short[] main, final byte[] indices, final int left, final int right)
9024        {
9025                if (right <= left)
9026                        return;
9027
9028                final int i = partitionAsc(main, indices, left, right);
9029
9030                parallelQuicksortAscending(main, indices, left, i - 1);
9031                parallelQuicksortAscending(main, indices, i + 1, right);
9032        }
9033
9034        // partition a[left] to a[right], assumes left < right
9035        private static int partitionAsc(final short[] a, final byte[] index, final int left, final int right) {
9036                int i = left - 1;
9037                int j = right;
9038                while (true) {
9039                        while (a[++i] < a[right])
9040                                // find item on left to swap
9041                                ; // a[right] acts as sentinel
9042                        while (a[right] < a[--j])
9043                                // find item on right to swap
9044                                if (j == left)
9045                                        break; // don't go out-of-bounds
9046                        if (i >= j)
9047                                break; // check if pointers cross
9048                        exch(a, index, i, j); // swap two elements into place
9049                }
9050                exch(a, index, i, right); // swap with partition element
9051                return i;
9052        }
9053
9054    
9055    /**
9056         * Sort parallel arrays. Arrays are sorted in-place. The first array
9057         * determines the order, and is sorted into ascending order.
9058         * <p>
9059         * Implementation inspired by this stackoverflow page: <a href=
9060         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
9061         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
9062         * get-a-sorted-list-of-indices-of-an-array </a>
9063         * 
9064         * @param main
9065         *            the values to use for determining the order
9066         * @param indices
9067         *            the second array
9068         */
9069        public static void parallelQuicksortAscending(final double[] main, final short[] indices) {
9070                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
9071        }
9072        
9073    /**
9074         * Sort parallel arrays. Arrays are sorted in-place. The first array
9075         * determines the order, and is sorted into ascending order.
9076         * <p>
9077         * Implementation inspired by this stackoverflow page: <a href=
9078         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
9079         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
9080         * get-a-sorted-list-of-indices-of-an-array </a>
9081         * 
9082         * @param main
9083         *            the values to use for determining the order
9084         * @param indices
9085         *            the second array
9086         * @param left
9087         *            the starting index
9088         * @param right
9089         *            the ending index
9090         */
9091        public static void
9092                        parallelQuicksortAscending(final double[] main, final short[] indices, final int left, final int right)
9093        {
9094                if (right <= left)
9095                        return;
9096
9097                final int i = partitionAsc(main, indices, left, right);
9098
9099                parallelQuicksortAscending(main, indices, left, i - 1);
9100                parallelQuicksortAscending(main, indices, i + 1, right);
9101        }
9102
9103        // partition a[left] to a[right], assumes left < right
9104        private static int partitionAsc(final double[] a, final short[] index, final int left, final int right) {
9105                int i = left - 1;
9106                int j = right;
9107                while (true) {
9108                        while (a[++i] < a[right])
9109                                // find item on left to swap
9110                                ; // a[right] acts as sentinel
9111                        while (a[right] < a[--j])
9112                                // find item on right to swap
9113                                if (j == left)
9114                                        break; // don't go out-of-bounds
9115                        if (i >= j)
9116                                break; // check if pointers cross
9117                        exch(a, index, i, j); // swap two elements into place
9118                }
9119                exch(a, index, i, right); // swap with partition element
9120                return i;
9121        }
9122
9123    
9124    /**
9125         * Sort parallel arrays. Arrays are sorted in-place. The first array
9126         * determines the order, and is sorted into ascending order.
9127         * <p>
9128         * Implementation inspired by this stackoverflow page: <a href=
9129         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
9130         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
9131         * get-a-sorted-list-of-indices-of-an-array </a>
9132         * 
9133         * @param main
9134         *            the values to use for determining the order
9135         * @param indices
9136         *            the second array
9137         */
9138        public static void parallelQuicksortAscending(final float[] main, final short[] indices) {
9139                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
9140        }
9141        
9142    /**
9143         * Sort parallel arrays. Arrays are sorted in-place. The first array
9144         * determines the order, and is sorted into ascending order.
9145         * <p>
9146         * Implementation inspired by this stackoverflow page: <a href=
9147         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
9148         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
9149         * get-a-sorted-list-of-indices-of-an-array </a>
9150         * 
9151         * @param main
9152         *            the values to use for determining the order
9153         * @param indices
9154         *            the second array
9155         * @param left
9156         *            the starting index
9157         * @param right
9158         *            the ending index
9159         */
9160        public static void
9161                        parallelQuicksortAscending(final float[] main, final short[] indices, final int left, final int right)
9162        {
9163                if (right <= left)
9164                        return;
9165
9166                final int i = partitionAsc(main, indices, left, right);
9167
9168                parallelQuicksortAscending(main, indices, left, i - 1);
9169                parallelQuicksortAscending(main, indices, i + 1, right);
9170        }
9171
9172        // partition a[left] to a[right], assumes left < right
9173        private static int partitionAsc(final float[] a, final short[] index, final int left, final int right) {
9174                int i = left - 1;
9175                int j = right;
9176                while (true) {
9177                        while (a[++i] < a[right])
9178                                // find item on left to swap
9179                                ; // a[right] acts as sentinel
9180                        while (a[right] < a[--j])
9181                                // find item on right to swap
9182                                if (j == left)
9183                                        break; // don't go out-of-bounds
9184                        if (i >= j)
9185                                break; // check if pointers cross
9186                        exch(a, index, i, j); // swap two elements into place
9187                }
9188                exch(a, index, i, right); // swap with partition element
9189                return i;
9190        }
9191
9192    
9193    /**
9194         * Sort parallel arrays. Arrays are sorted in-place. The first array
9195         * determines the order, and is sorted into ascending order.
9196         * <p>
9197         * Implementation inspired by this stackoverflow page: <a href=
9198         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
9199         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
9200         * get-a-sorted-list-of-indices-of-an-array </a>
9201         * 
9202         * @param main
9203         *            the values to use for determining the order
9204         * @param indices
9205         *            the second array
9206         */
9207        public static void parallelQuicksortAscending(final int[] main, final short[] indices) {
9208                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
9209        }
9210        
9211    /**
9212         * Sort parallel arrays. Arrays are sorted in-place. The first array
9213         * determines the order, and is sorted into ascending order.
9214         * <p>
9215         * Implementation inspired by this stackoverflow page: <a href=
9216         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
9217         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
9218         * get-a-sorted-list-of-indices-of-an-array </a>
9219         * 
9220         * @param main
9221         *            the values to use for determining the order
9222         * @param indices
9223         *            the second array
9224         * @param left
9225         *            the starting index
9226         * @param right
9227         *            the ending index
9228         */
9229        public static void
9230                        parallelQuicksortAscending(final int[] main, final short[] indices, final int left, final int right)
9231        {
9232                if (right <= left)
9233                        return;
9234
9235                final int i = partitionAsc(main, indices, left, right);
9236
9237                parallelQuicksortAscending(main, indices, left, i - 1);
9238                parallelQuicksortAscending(main, indices, i + 1, right);
9239        }
9240
9241        // partition a[left] to a[right], assumes left < right
9242        private static int partitionAsc(final int[] a, final short[] index, final int left, final int right) {
9243                int i = left - 1;
9244                int j = right;
9245                while (true) {
9246                        while (a[++i] < a[right])
9247                                // find item on left to swap
9248                                ; // a[right] acts as sentinel
9249                        while (a[right] < a[--j])
9250                                // find item on right to swap
9251                                if (j == left)
9252                                        break; // don't go out-of-bounds
9253                        if (i >= j)
9254                                break; // check if pointers cross
9255                        exch(a, index, i, j); // swap two elements into place
9256                }
9257                exch(a, index, i, right); // swap with partition element
9258                return i;
9259        }
9260
9261    
9262    /**
9263         * Sort parallel arrays. Arrays are sorted in-place. The first array
9264         * determines the order, and is sorted into ascending order.
9265         * <p>
9266         * Implementation inspired by this stackoverflow page: <a href=
9267         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
9268         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
9269         * get-a-sorted-list-of-indices-of-an-array </a>
9270         * 
9271         * @param main
9272         *            the values to use for determining the order
9273         * @param indices
9274         *            the second array
9275         */
9276        public static void parallelQuicksortAscending(final long[] main, final short[] indices) {
9277                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
9278        }
9279        
9280    /**
9281         * Sort parallel arrays. Arrays are sorted in-place. The first array
9282         * determines the order, and is sorted into ascending order.
9283         * <p>
9284         * Implementation inspired by this stackoverflow page: <a href=
9285         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
9286         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
9287         * get-a-sorted-list-of-indices-of-an-array </a>
9288         * 
9289         * @param main
9290         *            the values to use for determining the order
9291         * @param indices
9292         *            the second array
9293         * @param left
9294         *            the starting index
9295         * @param right
9296         *            the ending index
9297         */
9298        public static void
9299                        parallelQuicksortAscending(final long[] main, final short[] indices, final int left, final int right)
9300        {
9301                if (right <= left)
9302                        return;
9303
9304                final int i = partitionAsc(main, indices, left, right);
9305
9306                parallelQuicksortAscending(main, indices, left, i - 1);
9307                parallelQuicksortAscending(main, indices, i + 1, right);
9308        }
9309
9310        // partition a[left] to a[right], assumes left < right
9311        private static int partitionAsc(final long[] a, final short[] index, final int left, final int right) {
9312                int i = left - 1;
9313                int j = right;
9314                while (true) {
9315                        while (a[++i] < a[right])
9316                                // find item on left to swap
9317                                ; // a[right] acts as sentinel
9318                        while (a[right] < a[--j])
9319                                // find item on right to swap
9320                                if (j == left)
9321                                        break; // don't go out-of-bounds
9322                        if (i >= j)
9323                                break; // check if pointers cross
9324                        exch(a, index, i, j); // swap two elements into place
9325                }
9326                exch(a, index, i, right); // swap with partition element
9327                return i;
9328        }
9329
9330    
9331    /**
9332         * Sort parallel arrays. Arrays are sorted in-place. The first array
9333         * determines the order, and is sorted into ascending order.
9334         * <p>
9335         * Implementation inspired by this stackoverflow page: <a href=
9336         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
9337         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
9338         * get-a-sorted-list-of-indices-of-an-array </a>
9339         * 
9340         * @param main
9341         *            the values to use for determining the order
9342         * @param indices
9343         *            the second array
9344         */
9345        public static void parallelQuicksortAscending(final byte[] main, final short[] indices) {
9346                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
9347        }
9348        
9349    /**
9350         * Sort parallel arrays. Arrays are sorted in-place. The first array
9351         * determines the order, and is sorted into ascending order.
9352         * <p>
9353         * Implementation inspired by this stackoverflow page: <a href=
9354         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
9355         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
9356         * get-a-sorted-list-of-indices-of-an-array </a>
9357         * 
9358         * @param main
9359         *            the values to use for determining the order
9360         * @param indices
9361         *            the second array
9362         * @param left
9363         *            the starting index
9364         * @param right
9365         *            the ending index
9366         */
9367        public static void
9368                        parallelQuicksortAscending(final byte[] main, final short[] indices, final int left, final int right)
9369        {
9370                if (right <= left)
9371                        return;
9372
9373                final int i = partitionAsc(main, indices, left, right);
9374
9375                parallelQuicksortAscending(main, indices, left, i - 1);
9376                parallelQuicksortAscending(main, indices, i + 1, right);
9377        }
9378
9379        // partition a[left] to a[right], assumes left < right
9380        private static int partitionAsc(final byte[] a, final short[] index, final int left, final int right) {
9381                int i = left - 1;
9382                int j = right;
9383                while (true) {
9384                        while (a[++i] < a[right])
9385                                // find item on left to swap
9386                                ; // a[right] acts as sentinel
9387                        while (a[right] < a[--j])
9388                                // find item on right to swap
9389                                if (j == left)
9390                                        break; // don't go out-of-bounds
9391                        if (i >= j)
9392                                break; // check if pointers cross
9393                        exch(a, index, i, j); // swap two elements into place
9394                }
9395                exch(a, index, i, right); // swap with partition element
9396                return i;
9397        }
9398
9399    
9400    /**
9401         * Sort parallel arrays. Arrays are sorted in-place. The first array
9402         * determines the order, and is sorted into ascending order.
9403         * <p>
9404         * Implementation inspired by this stackoverflow page: <a href=
9405         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
9406         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
9407         * get-a-sorted-list-of-indices-of-an-array </a>
9408         * 
9409         * @param main
9410         *            the values to use for determining the order
9411         * @param indices
9412         *            the second array
9413         */
9414        public static void parallelQuicksortAscending(final short[] main, final short[] indices) {
9415                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
9416        }
9417        
9418    /**
9419         * Sort parallel arrays. Arrays are sorted in-place. The first array
9420         * determines the order, and is sorted into ascending order.
9421         * <p>
9422         * Implementation inspired by this stackoverflow page: <a href=
9423         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
9424         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
9425         * get-a-sorted-list-of-indices-of-an-array </a>
9426         * 
9427         * @param main
9428         *            the values to use for determining the order
9429         * @param indices
9430         *            the second array
9431         * @param left
9432         *            the starting index
9433         * @param right
9434         *            the ending index
9435         */
9436        public static void
9437                        parallelQuicksortAscending(final short[] main, final short[] indices, final int left, final int right)
9438        {
9439                if (right <= left)
9440                        return;
9441
9442                final int i = partitionAsc(main, indices, left, right);
9443
9444                parallelQuicksortAscending(main, indices, left, i - 1);
9445                parallelQuicksortAscending(main, indices, i + 1, right);
9446        }
9447
9448        // partition a[left] to a[right], assumes left < right
9449        private static int partitionAsc(final short[] a, final short[] index, final int left, final int right) {
9450                int i = left - 1;
9451                int j = right;
9452                while (true) {
9453                        while (a[++i] < a[right])
9454                                // find item on left to swap
9455                                ; // a[right] acts as sentinel
9456                        while (a[right] < a[--j])
9457                                // find item on right to swap
9458                                if (j == left)
9459                                        break; // don't go out-of-bounds
9460                        if (i >= j)
9461                                break; // check if pointers cross
9462                        exch(a, index, i, j); // swap two elements into place
9463                }
9464                exch(a, index, i, right); // swap with partition element
9465                return i;
9466        }
9467
9468    
9469    // exchange a[i] and a[j]
9470        private static void exch(final double[] a, final double[] index, final int i, final int j) {
9471                final double swap = a[i];
9472                a[i] = a[j];
9473                a[j] = swap;
9474
9475                final double b = index[i];
9476                index[i] = index[j];
9477                index[j] = b;
9478        }
9479
9480    
9481    // exchange a[i] and a[j]
9482        private static void exch(final float[] a, final double[] index, final int i, final int j) {
9483                final float swap = a[i];
9484                a[i] = a[j];
9485                a[j] = swap;
9486
9487                final double b = index[i];
9488                index[i] = index[j];
9489                index[j] = b;
9490        }
9491
9492    
9493    // exchange a[i] and a[j]
9494        private static void exch(final int[] a, final double[] index, final int i, final int j) {
9495                final int swap = a[i];
9496                a[i] = a[j];
9497                a[j] = swap;
9498
9499                final double b = index[i];
9500                index[i] = index[j];
9501                index[j] = b;
9502        }
9503
9504    
9505    // exchange a[i] and a[j]
9506        private static void exch(final long[] a, final double[] index, final int i, final int j) {
9507                final long swap = a[i];
9508                a[i] = a[j];
9509                a[j] = swap;
9510
9511                final double b = index[i];
9512                index[i] = index[j];
9513                index[j] = b;
9514        }
9515
9516    
9517    // exchange a[i] and a[j]
9518        private static void exch(final byte[] a, final double[] index, final int i, final int j) {
9519                final byte swap = a[i];
9520                a[i] = a[j];
9521                a[j] = swap;
9522
9523                final double b = index[i];
9524                index[i] = index[j];
9525                index[j] = b;
9526        }
9527
9528    
9529    // exchange a[i] and a[j]
9530        private static void exch(final short[] a, final double[] index, final int i, final int j) {
9531                final short swap = a[i];
9532                a[i] = a[j];
9533                a[j] = swap;
9534
9535                final double b = index[i];
9536                index[i] = index[j];
9537                index[j] = b;
9538        }
9539
9540    
9541    // exchange a[i] and a[j]
9542        private static void exch(final double[] a, final float[] index, final int i, final int j) {
9543                final double swap = a[i];
9544                a[i] = a[j];
9545                a[j] = swap;
9546
9547                final float b = index[i];
9548                index[i] = index[j];
9549                index[j] = b;
9550        }
9551
9552    
9553    // exchange a[i] and a[j]
9554        private static void exch(final float[] a, final float[] index, final int i, final int j) {
9555                final float swap = a[i];
9556                a[i] = a[j];
9557                a[j] = swap;
9558
9559                final float b = index[i];
9560                index[i] = index[j];
9561                index[j] = b;
9562        }
9563
9564    
9565    // exchange a[i] and a[j]
9566        private static void exch(final int[] a, final float[] index, final int i, final int j) {
9567                final int swap = a[i];
9568                a[i] = a[j];
9569                a[j] = swap;
9570
9571                final float b = index[i];
9572                index[i] = index[j];
9573                index[j] = b;
9574        }
9575
9576    
9577    // exchange a[i] and a[j]
9578        private static void exch(final long[] a, final float[] index, final int i, final int j) {
9579                final long swap = a[i];
9580                a[i] = a[j];
9581                a[j] = swap;
9582
9583                final float b = index[i];
9584                index[i] = index[j];
9585                index[j] = b;
9586        }
9587
9588    
9589    // exchange a[i] and a[j]
9590        private static void exch(final byte[] a, final float[] index, final int i, final int j) {
9591                final byte swap = a[i];
9592                a[i] = a[j];
9593                a[j] = swap;
9594
9595                final float b = index[i];
9596                index[i] = index[j];
9597                index[j] = b;
9598        }
9599
9600    
9601    // exchange a[i] and a[j]
9602        private static void exch(final short[] a, final float[] index, final int i, final int j) {
9603                final short swap = a[i];
9604                a[i] = a[j];
9605                a[j] = swap;
9606
9607                final float b = index[i];
9608                index[i] = index[j];
9609                index[j] = b;
9610        }
9611
9612    
9613    // exchange a[i] and a[j]
9614        private static void exch(final double[] a, final int[] index, final int i, final int j) {
9615                final double swap = a[i];
9616                a[i] = a[j];
9617                a[j] = swap;
9618
9619                final int b = index[i];
9620                index[i] = index[j];
9621                index[j] = b;
9622        }
9623
9624    
9625    // exchange a[i] and a[j]
9626        private static void exch(final float[] a, final int[] index, final int i, final int j) {
9627                final float swap = a[i];
9628                a[i] = a[j];
9629                a[j] = swap;
9630
9631                final int b = index[i];
9632                index[i] = index[j];
9633                index[j] = b;
9634        }
9635
9636    
9637    // exchange a[i] and a[j]
9638        private static void exch(final int[] a, final int[] index, final int i, final int j) {
9639                final int swap = a[i];
9640                a[i] = a[j];
9641                a[j] = swap;
9642
9643                final int b = index[i];
9644                index[i] = index[j];
9645                index[j] = b;
9646        }
9647
9648    
9649    // exchange a[i] and a[j]
9650        private static void exch(final long[] a, final int[] index, final int i, final int j) {
9651                final long swap = a[i];
9652                a[i] = a[j];
9653                a[j] = swap;
9654
9655                final int b = index[i];
9656                index[i] = index[j];
9657                index[j] = b;
9658        }
9659
9660    
9661    // exchange a[i] and a[j]
9662        private static void exch(final byte[] a, final int[] index, final int i, final int j) {
9663                final byte swap = a[i];
9664                a[i] = a[j];
9665                a[j] = swap;
9666
9667                final int b = index[i];
9668                index[i] = index[j];
9669                index[j] = b;
9670        }
9671
9672    
9673    // exchange a[i] and a[j]
9674        private static void exch(final short[] a, final int[] index, final int i, final int j) {
9675                final short swap = a[i];
9676                a[i] = a[j];
9677                a[j] = swap;
9678
9679                final int b = index[i];
9680                index[i] = index[j];
9681                index[j] = b;
9682        }
9683
9684    
9685    // exchange a[i] and a[j]
9686        private static void exch(final double[] a, final long[] index, final int i, final int j) {
9687                final double swap = a[i];
9688                a[i] = a[j];
9689                a[j] = swap;
9690
9691                final long b = index[i];
9692                index[i] = index[j];
9693                index[j] = b;
9694        }
9695
9696    
9697    // exchange a[i] and a[j]
9698        private static void exch(final float[] a, final long[] index, final int i, final int j) {
9699                final float swap = a[i];
9700                a[i] = a[j];
9701                a[j] = swap;
9702
9703                final long b = index[i];
9704                index[i] = index[j];
9705                index[j] = b;
9706        }
9707
9708    
9709    // exchange a[i] and a[j]
9710        private static void exch(final int[] a, final long[] index, final int i, final int j) {
9711                final int swap = a[i];
9712                a[i] = a[j];
9713                a[j] = swap;
9714
9715                final long b = index[i];
9716                index[i] = index[j];
9717                index[j] = b;
9718        }
9719
9720    
9721    // exchange a[i] and a[j]
9722        private static void exch(final long[] a, final long[] index, final int i, final int j) {
9723                final long swap = a[i];
9724                a[i] = a[j];
9725                a[j] = swap;
9726
9727                final long b = index[i];
9728                index[i] = index[j];
9729                index[j] = b;
9730        }
9731
9732    
9733    // exchange a[i] and a[j]
9734        private static void exch(final byte[] a, final long[] index, final int i, final int j) {
9735                final byte swap = a[i];
9736                a[i] = a[j];
9737                a[j] = swap;
9738
9739                final long b = index[i];
9740                index[i] = index[j];
9741                index[j] = b;
9742        }
9743
9744    
9745    // exchange a[i] and a[j]
9746        private static void exch(final short[] a, final long[] index, final int i, final int j) {
9747                final short swap = a[i];
9748                a[i] = a[j];
9749                a[j] = swap;
9750
9751                final long b = index[i];
9752                index[i] = index[j];
9753                index[j] = b;
9754        }
9755
9756    
9757    // exchange a[i] and a[j]
9758        private static void exch(final double[] a, final byte[] index, final int i, final int j) {
9759                final double swap = a[i];
9760                a[i] = a[j];
9761                a[j] = swap;
9762
9763                final byte b = index[i];
9764                index[i] = index[j];
9765                index[j] = b;
9766        }
9767
9768    
9769    // exchange a[i] and a[j]
9770        private static void exch(final float[] a, final byte[] index, final int i, final int j) {
9771                final float swap = a[i];
9772                a[i] = a[j];
9773                a[j] = swap;
9774
9775                final byte b = index[i];
9776                index[i] = index[j];
9777                index[j] = b;
9778        }
9779
9780    
9781    // exchange a[i] and a[j]
9782        private static void exch(final int[] a, final byte[] index, final int i, final int j) {
9783                final int swap = a[i];
9784                a[i] = a[j];
9785                a[j] = swap;
9786
9787                final byte b = index[i];
9788                index[i] = index[j];
9789                index[j] = b;
9790        }
9791
9792    
9793    // exchange a[i] and a[j]
9794        private static void exch(final long[] a, final byte[] index, final int i, final int j) {
9795                final long swap = a[i];
9796                a[i] = a[j];
9797                a[j] = swap;
9798
9799                final byte b = index[i];
9800                index[i] = index[j];
9801                index[j] = b;
9802        }
9803
9804    
9805    // exchange a[i] and a[j]
9806        private static void exch(final byte[] a, final byte[] index, final int i, final int j) {
9807                final byte swap = a[i];
9808                a[i] = a[j];
9809                a[j] = swap;
9810
9811                final byte b = index[i];
9812                index[i] = index[j];
9813                index[j] = b;
9814        }
9815
9816    
9817    // exchange a[i] and a[j]
9818        private static void exch(final short[] a, final byte[] index, final int i, final int j) {
9819                final short swap = a[i];
9820                a[i] = a[j];
9821                a[j] = swap;
9822
9823                final byte b = index[i];
9824                index[i] = index[j];
9825                index[j] = b;
9826        }
9827
9828    
9829    // exchange a[i] and a[j]
9830        private static void exch(final double[] a, final short[] index, final int i, final int j) {
9831                final double swap = a[i];
9832                a[i] = a[j];
9833                a[j] = swap;
9834
9835                final short b = index[i];
9836                index[i] = index[j];
9837                index[j] = b;
9838        }
9839
9840    
9841    // exchange a[i] and a[j]
9842        private static void exch(final float[] a, final short[] index, final int i, final int j) {
9843                final float swap = a[i];
9844                a[i] = a[j];
9845                a[j] = swap;
9846
9847                final short b = index[i];
9848                index[i] = index[j];
9849                index[j] = b;
9850        }
9851
9852    
9853    // exchange a[i] and a[j]
9854        private static void exch(final int[] a, final short[] index, final int i, final int j) {
9855                final int swap = a[i];
9856                a[i] = a[j];
9857                a[j] = swap;
9858
9859                final short b = index[i];
9860                index[i] = index[j];
9861                index[j] = b;
9862        }
9863
9864    
9865    // exchange a[i] and a[j]
9866        private static void exch(final long[] a, final short[] index, final int i, final int j) {
9867                final long swap = a[i];
9868                a[i] = a[j];
9869                a[j] = swap;
9870
9871                final short b = index[i];
9872                index[i] = index[j];
9873                index[j] = b;
9874        }
9875
9876    
9877    // exchange a[i] and a[j]
9878        private static void exch(final byte[] a, final short[] index, final int i, final int j) {
9879                final byte swap = a[i];
9880                a[i] = a[j];
9881                a[j] = swap;
9882
9883                final short b = index[i];
9884                index[i] = index[j];
9885                index[j] = b;
9886        }
9887
9888    
9889    // exchange a[i] and a[j]
9890        private static void exch(final short[] a, final short[] index, final int i, final int j) {
9891                final short swap = a[i];
9892                a[i] = a[j];
9893                a[j] = swap;
9894
9895                final short b = index[i];
9896                index[i] = index[j];
9897                index[j] = b;
9898        }
9899
9900    
9901        /**
9902         * Determine the indices of the given array if it were to be sorted into
9903         * ascending order.
9904         * 
9905         * @param arr
9906         *            the array
9907         * @return the sorted indices
9908         */
9909        public static int[] indexSort(final double[] arr) {
9910                final int[] index = new int[arr.length];
9911
9912                for (int i = 0; i < index.length; i++)
9913                        index[i] = i;
9914
9915                quicksort(arr, index, 0, index.length - 1);
9916
9917                return index;
9918        }
9919
9920        // quicksort a[left] to a[right]
9921        private static void quicksort(final double[] a, final int[] index, final int left, final int right) {
9922                if (right <= left)
9923                        return;
9924                final int i = partition(a, index, left, right);
9925                quicksort(a, index, left, i - 1);
9926                quicksort(a, index, i + 1, right);
9927        }
9928
9929        // partition a[left] to a[right], assumes left < right
9930        private static int partition(final double[] a, final int[] index,
9931                        final int left, final int right)
9932        {
9933                int i = left - 1;
9934                int j = right;
9935                while (true) {
9936                        while (a[index[++i]] < a[index[right]])
9937                                // find item on left to swap
9938                                ; // a[right] acts as sentinel
9939                        while (a[index[right]] < a[index[--j]])
9940                                // find item on right to swap
9941                                if (j == left)
9942                                        break; // don't go out-of-bounds
9943                        if (i >= j)
9944                                break; // check if pointers cross
9945                        exch(index, i, j); // swap two elements into place
9946                }
9947                exch(index, i, right); // swap with partition element
9948                return i;
9949        }
9950
9951    
9952        /**
9953         * Determine the indices of the given array if it were to be sorted into
9954         * ascending order.
9955         * 
9956         * @param arr
9957         *            the array
9958         * @return the sorted indices
9959         */
9960        public static int[] indexSort(final float[] arr) {
9961                final int[] index = new int[arr.length];
9962
9963                for (int i = 0; i < index.length; i++)
9964                        index[i] = i;
9965
9966                quicksort(arr, index, 0, index.length - 1);
9967
9968                return index;
9969        }
9970
9971        // quicksort a[left] to a[right]
9972        private static void quicksort(final float[] a, final int[] index, final int left, final int right) {
9973                if (right <= left)
9974                        return;
9975                final int i = partition(a, index, left, right);
9976                quicksort(a, index, left, i - 1);
9977                quicksort(a, index, i + 1, right);
9978        }
9979
9980        // partition a[left] to a[right], assumes left < right
9981        private static int partition(final float[] a, final int[] index,
9982                        final int left, final int right)
9983        {
9984                int i = left - 1;
9985                int j = right;
9986                while (true) {
9987                        while (a[index[++i]] < a[index[right]])
9988                                // find item on left to swap
9989                                ; // a[right] acts as sentinel
9990                        while (a[index[right]] < a[index[--j]])
9991                                // find item on right to swap
9992                                if (j == left)
9993                                        break; // don't go out-of-bounds
9994                        if (i >= j)
9995                                break; // check if pointers cross
9996                        exch(index, i, j); // swap two elements into place
9997                }
9998                exch(index, i, right); // swap with partition element
9999                return i;
10000        }
10001
10002    
10003        /**
10004         * Determine the indices of the given array if it were to be sorted into
10005         * ascending order.
10006         * 
10007         * @param arr
10008         *            the array
10009         * @return the sorted indices
10010         */
10011        public static int[] indexSort(final int[] arr) {
10012                final int[] index = new int[arr.length];
10013
10014                for (int i = 0; i < index.length; i++)
10015                        index[i] = i;
10016
10017                quicksort(arr, index, 0, index.length - 1);
10018
10019                return index;
10020        }
10021
10022        // quicksort a[left] to a[right]
10023        private static void quicksort(final int[] a, final int[] index, final int left, final int right) {
10024                if (right <= left)
10025                        return;
10026                final int i = partition(a, index, left, right);
10027                quicksort(a, index, left, i - 1);
10028                quicksort(a, index, i + 1, right);
10029        }
10030
10031        // partition a[left] to a[right], assumes left < right
10032        private static int partition(final int[] a, final int[] index,
10033                        final int left, final int right)
10034        {
10035                int i = left - 1;
10036                int j = right;
10037                while (true) {
10038                        while (a[index[++i]] < a[index[right]])
10039                                // find item on left to swap
10040                                ; // a[right] acts as sentinel
10041                        while (a[index[right]] < a[index[--j]])
10042                                // find item on right to swap
10043                                if (j == left)
10044                                        break; // don't go out-of-bounds
10045                        if (i >= j)
10046                                break; // check if pointers cross
10047                        exch(index, i, j); // swap two elements into place
10048                }
10049                exch(index, i, right); // swap with partition element
10050                return i;
10051        }
10052
10053    
10054        /**
10055         * Determine the indices of the given array if it were to be sorted into
10056         * ascending order.
10057         * 
10058         * @param arr
10059         *            the array
10060         * @return the sorted indices
10061         */
10062        public static int[] indexSort(final long[] arr) {
10063                final int[] index = new int[arr.length];
10064
10065                for (int i = 0; i < index.length; i++)
10066                        index[i] = i;
10067
10068                quicksort(arr, index, 0, index.length - 1);
10069
10070                return index;
10071        }
10072
10073        // quicksort a[left] to a[right]
10074        private static void quicksort(final long[] a, final int[] index, final int left, final int right) {
10075                if (right <= left)
10076                        return;
10077                final int i = partition(a, index, left, right);
10078                quicksort(a, index, left, i - 1);
10079                quicksort(a, index, i + 1, right);
10080        }
10081
10082        // partition a[left] to a[right], assumes left < right
10083        private static int partition(final long[] a, final int[] index,
10084                        final int left, final int right)
10085        {
10086                int i = left - 1;
10087                int j = right;
10088                while (true) {
10089                        while (a[index[++i]] < a[index[right]])
10090                                // find item on left to swap
10091                                ; // a[right] acts as sentinel
10092                        while (a[index[right]] < a[index[--j]])
10093                                // find item on right to swap
10094                                if (j == left)
10095                                        break; // don't go out-of-bounds
10096                        if (i >= j)
10097                                break; // check if pointers cross
10098                        exch(index, i, j); // swap two elements into place
10099                }
10100                exch(index, i, right); // swap with partition element
10101                return i;
10102        }
10103
10104    
10105        /**
10106         * Determine the indices of the given array if it were to be sorted into
10107         * ascending order.
10108         * 
10109         * @param arr
10110         *            the array
10111         * @return the sorted indices
10112         */
10113        public static int[] indexSort(final byte[] arr) {
10114                final int[] index = new int[arr.length];
10115
10116                for (int i = 0; i < index.length; i++)
10117                        index[i] = i;
10118
10119                quicksort(arr, index, 0, index.length - 1);
10120
10121                return index;
10122        }
10123
10124        // quicksort a[left] to a[right]
10125        private static void quicksort(final byte[] a, final int[] index, final int left, final int right) {
10126                if (right <= left)
10127                        return;
10128                final int i = partition(a, index, left, right);
10129                quicksort(a, index, left, i - 1);
10130                quicksort(a, index, i + 1, right);
10131        }
10132
10133        // partition a[left] to a[right], assumes left < right
10134        private static int partition(final byte[] a, final int[] index,
10135                        final int left, final int right)
10136        {
10137                int i = left - 1;
10138                int j = right;
10139                while (true) {
10140                        while (a[index[++i]] < a[index[right]])
10141                                // find item on left to swap
10142                                ; // a[right] acts as sentinel
10143                        while (a[index[right]] < a[index[--j]])
10144                                // find item on right to swap
10145                                if (j == left)
10146                                        break; // don't go out-of-bounds
10147                        if (i >= j)
10148                                break; // check if pointers cross
10149                        exch(index, i, j); // swap two elements into place
10150                }
10151                exch(index, i, right); // swap with partition element
10152                return i;
10153        }
10154
10155    
10156        /**
10157         * Determine the indices of the given array if it were to be sorted into
10158         * ascending order.
10159         * 
10160         * @param arr
10161         *            the array
10162         * @return the sorted indices
10163         */
10164        public static int[] indexSort(final short[] arr) {
10165                final int[] index = new int[arr.length];
10166
10167                for (int i = 0; i < index.length; i++)
10168                        index[i] = i;
10169
10170                quicksort(arr, index, 0, index.length - 1);
10171
10172                return index;
10173        }
10174
10175        // quicksort a[left] to a[right]
10176        private static void quicksort(final short[] a, final int[] index, final int left, final int right) {
10177                if (right <= left)
10178                        return;
10179                final int i = partition(a, index, left, right);
10180                quicksort(a, index, left, i - 1);
10181                quicksort(a, index, i + 1, right);
10182        }
10183
10184        // partition a[left] to a[right], assumes left < right
10185        private static int partition(final short[] a, final int[] index,
10186                        final int left, final int right)
10187        {
10188                int i = left - 1;
10189                int j = right;
10190                while (true) {
10191                        while (a[index[++i]] < a[index[right]])
10192                                // find item on left to swap
10193                                ; // a[right] acts as sentinel
10194                        while (a[index[right]] < a[index[--j]])
10195                                // find item on right to swap
10196                                if (j == left)
10197                                        break; // don't go out-of-bounds
10198                        if (i >= j)
10199                                break; // check if pointers cross
10200                        exch(index, i, j); // swap two elements into place
10201                }
10202                exch(index, i, right); // swap with partition element
10203                return i;
10204        }
10205
10206    
10207        // exchange a[i] and a[j]
10208        static void exch(final int[] index, final int i, final int j) {
10209                final int b = index[i];
10210                index[i] = index[j];
10211                index[j] = b;
10212        }
10213
10214    
10215        /**
10216         * Normalise and scale the values so that the maximum value in the array is
10217         * 1.
10218         * 
10219         * @param array
10220         *            The array to normalise
10221         * @return The array
10222         */
10223        public static double[] normaliseMax(final double[] array) {
10224                return normaliseMax(array, 1d);
10225        }
10226
10227        /**
10228         * Normalise and scale the values so that the maximum value in the array is
10229         * max
10230         * 
10231         * @param array
10232         *            The array to normalise
10233         * @param max
10234         *            The maximum value
10235         * @return The array
10236         */
10237        public static double[] normaliseMax(final double[] array, final double max) {
10238                final double m = maxValue(array);
10239                for (int i = 0; i < array.length; i++)
10240                        array[i] /= m;
10241                return array;
10242        }
10243
10244    
10245        /**
10246         * Convert the array to a {@link String} by joining the elements with the
10247         * given glue.
10248         * 
10249         * @param s
10250         *            the array
10251         * @param glue
10252         *            the glue
10253         * @return the string
10254         */
10255        public static String toString(final String[] s, final String glue) {
10256                final int k = s.length;
10257
10258                if (k == 0)
10259                        return null;
10260
10261                final StringBuilder out = new StringBuilder();
10262                out.append(s[0]);
10263
10264                for (int x = 1; x < k; ++x)
10265                        out.append(glue).append(s[x]);
10266
10267                return out.toString();
10268        }
10269
10270    
10271        /**
10272         * Fill the array with the value
10273         * 
10274         * @param a1
10275         *            The array
10276         * @param i
10277         *            The value
10278         * @return The array
10279         */
10280        public static double[][] fill(final double[][] a1, final double i)
10281        {
10282                for (int j = 0; j < a1.length; j++)
10283                        fill(a1[j], i);
10284                return a1;
10285        }
10286
10287        /**
10288         * Fill the array with the value from the start index for the length given
10289         * 
10290         * @param a1
10291         *            The array to fill
10292         * @param i
10293         *            The value to fill with
10294         * @param s
10295         *            The start index
10296         * @param l
10297         *            The length of the fill
10298         * @return The array
10299         */
10300        public static double[] fill(final double[] a1, final double i, final int s, final int l)
10301        {
10302                for (int j = s; j < s + l; j++)
10303                        a1[j] = i;
10304                return a1;
10305        }
10306
10307        /**
10308         * Fill the array with the value
10309         * 
10310         * @param a1
10311         *            The array
10312         * @param i
10313         *            The value
10314         * @return The array
10315         */
10316        public static double[] fill(final double[] a1, final double i)
10317        {
10318                for (int j = 0; j < a1.length; j++)
10319                        a1[j] = i;
10320                return a1;
10321        }
10322
10323    
10324        /**
10325         * Fill the array with the value
10326         * 
10327         * @param a1
10328         *            The array
10329         * @param i
10330         *            The value
10331         * @return The array
10332         */
10333        public static float[][] fill(final float[][] a1, final float i)
10334        {
10335                for (int j = 0; j < a1.length; j++)
10336                        fill(a1[j], i);
10337                return a1;
10338        }
10339
10340        /**
10341         * Fill the array with the value from the start index for the length given
10342         * 
10343         * @param a1
10344         *            The array to fill
10345         * @param i
10346         *            The value to fill with
10347         * @param s
10348         *            The start index
10349         * @param l
10350         *            The length of the fill
10351         * @return The array
10352         */
10353        public static float[] fill(final float[] a1, final float i, final int s, final int l)
10354        {
10355                for (int j = s; j < s + l; j++)
10356                        a1[j] = i;
10357                return a1;
10358        }
10359
10360        /**
10361         * Fill the array with the value
10362         * 
10363         * @param a1
10364         *            The array
10365         * @param i
10366         *            The value
10367         * @return The array
10368         */
10369        public static float[] fill(final float[] a1, final float i)
10370        {
10371                for (int j = 0; j < a1.length; j++)
10372                        a1[j] = i;
10373                return a1;
10374        }
10375
10376    
10377        /**
10378         * Fill the array with the value
10379         * 
10380         * @param a1
10381         *            The array
10382         * @param i
10383         *            The value
10384         * @return The array
10385         */
10386        public static int[][] fill(final int[][] a1, final int i)
10387        {
10388                for (int j = 0; j < a1.length; j++)
10389                        fill(a1[j], i);
10390                return a1;
10391        }
10392
10393        /**
10394         * Fill the array with the value from the start index for the length given
10395         * 
10396         * @param a1
10397         *            The array to fill
10398         * @param i
10399         *            The value to fill with
10400         * @param s
10401         *            The start index
10402         * @param l
10403         *            The length of the fill
10404         * @return The array
10405         */
10406        public static int[] fill(final int[] a1, final int i, final int s, final int l)
10407        {
10408                for (int j = s; j < s + l; j++)
10409                        a1[j] = i;
10410                return a1;
10411        }
10412
10413        /**
10414         * Fill the array with the value
10415         * 
10416         * @param a1
10417         *            The array
10418         * @param i
10419         *            The value
10420         * @return The array
10421         */
10422        public static int[] fill(final int[] a1, final int i)
10423        {
10424                for (int j = 0; j < a1.length; j++)
10425                        a1[j] = i;
10426                return a1;
10427        }
10428
10429    
10430        /**
10431         * Fill the array with the value
10432         * 
10433         * @param a1
10434         *            The array
10435         * @param i
10436         *            The value
10437         * @return The array
10438         */
10439        public static long[][] fill(final long[][] a1, final long i)
10440        {
10441                for (int j = 0; j < a1.length; j++)
10442                        fill(a1[j], i);
10443                return a1;
10444        }
10445
10446        /**
10447         * Fill the array with the value from the start index for the length given
10448         * 
10449         * @param a1
10450         *            The array to fill
10451         * @param i
10452         *            The value to fill with
10453         * @param s
10454         *            The start index
10455         * @param l
10456         *            The length of the fill
10457         * @return The array
10458         */
10459        public static long[] fill(final long[] a1, final long i, final int s, final int l)
10460        {
10461                for (int j = s; j < s + l; j++)
10462                        a1[j] = i;
10463                return a1;
10464        }
10465
10466        /**
10467         * Fill the array with the value
10468         * 
10469         * @param a1
10470         *            The array
10471         * @param i
10472         *            The value
10473         * @return The array
10474         */
10475        public static long[] fill(final long[] a1, final long i)
10476        {
10477                for (int j = 0; j < a1.length; j++)
10478                        a1[j] = i;
10479                return a1;
10480        }
10481
10482    
10483        /**
10484         * Fill the array with the value
10485         * 
10486         * @param a1
10487         *            The array
10488         * @param i
10489         *            The value
10490         * @return The array
10491         */
10492        public static byte[][] fill(final byte[][] a1, final byte i)
10493        {
10494                for (int j = 0; j < a1.length; j++)
10495                        fill(a1[j], i);
10496                return a1;
10497        }
10498
10499        /**
10500         * Fill the array with the value from the start index for the length given
10501         * 
10502         * @param a1
10503         *            The array to fill
10504         * @param i
10505         *            The value to fill with
10506         * @param s
10507         *            The start index
10508         * @param l
10509         *            The length of the fill
10510         * @return The array
10511         */
10512        public static byte[] fill(final byte[] a1, final byte i, final int s, final int l)
10513        {
10514                for (int j = s; j < s + l; j++)
10515                        a1[j] = i;
10516                return a1;
10517        }
10518
10519        /**
10520         * Fill the array with the value
10521         * 
10522         * @param a1
10523         *            The array
10524         * @param i
10525         *            The value
10526         * @return The array
10527         */
10528        public static byte[] fill(final byte[] a1, final byte i)
10529        {
10530                for (int j = 0; j < a1.length; j++)
10531                        a1[j] = i;
10532                return a1;
10533        }
10534
10535    
10536        /**
10537         * Fill the array with the value
10538         * 
10539         * @param a1
10540         *            The array
10541         * @param i
10542         *            The value
10543         * @return The array
10544         */
10545        public static short[][] fill(final short[][] a1, final short i)
10546        {
10547                for (int j = 0; j < a1.length; j++)
10548                        fill(a1[j], i);
10549                return a1;
10550        }
10551
10552        /**
10553         * Fill the array with the value from the start index for the length given
10554         * 
10555         * @param a1
10556         *            The array to fill
10557         * @param i
10558         *            The value to fill with
10559         * @param s
10560         *            The start index
10561         * @param l
10562         *            The length of the fill
10563         * @return The array
10564         */
10565        public static short[] fill(final short[] a1, final short i, final int s, final int l)
10566        {
10567                for (int j = s; j < s + l; j++)
10568                        a1[j] = i;
10569                return a1;
10570        }
10571
10572        /**
10573         * Fill the array with the value
10574         * 
10575         * @param a1
10576         *            The array
10577         * @param i
10578         *            The value
10579         * @return The array
10580         */
10581        public static short[] fill(final short[] a1, final short i)
10582        {
10583                for (int j = 0; j < a1.length; j++)
10584                        a1[j] = i;
10585                return a1;
10586        }
10587
10588    
10589        /**
10590         * Fills the array with ordinal values
10591         * 
10592         * @param array
10593         *            The array to fill
10594         * @return the array
10595         */
10596        public static int[] fill(final int[] array)
10597        {
10598                for (int i = 0; i < array.length; i++)
10599                        array[i] = i;
10600                return array;
10601        }
10602
10603    
10604        /**
10605         * Truncates the given array to the given size.
10606         * 
10607         * @param array
10608         *            The array to truncate
10609         * @param index
10610         *            The size to truncate it to
10611         * @return The truncated array
10612         */
10613        public static double[] truncate(final double[] array, final int index)
10614        {
10615                final double[] d = new double[index];
10616                System.arraycopy(array, 0, d, 0, index);
10617                return d;
10618        }
10619
10620        /**
10621         * Truncates every element in the given array to the given size.
10622         * 
10623         * @param array
10624         *            The array to truncate
10625         * @param index
10626         *            The size to truncate it to
10627         * @return The truncated array
10628         */
10629        public static double[][] truncate(final double[][] array, final int index)
10630        {
10631                final double[][] d = new double[Math.min(array.length, index)][index];
10632                for (int i = 0; i < d.length; i++)
10633                        d[i] = truncate(array[i], index);
10634                return d;
10635        }
10636
10637    
10638        /**
10639         * Truncates the given array to the given size.
10640         * 
10641         * @param array
10642         *            The array to truncate
10643         * @param index
10644         *            The size to truncate it to
10645         * @return The truncated array
10646         */
10647        public static float[] truncate(final float[] array, final int index)
10648        {
10649                final float[] d = new float[index];
10650                System.arraycopy(array, 0, d, 0, index);
10651                return d;
10652        }
10653
10654        /**
10655         * Truncates every element in the given array to the given size.
10656         * 
10657         * @param array
10658         *            The array to truncate
10659         * @param index
10660         *            The size to truncate it to
10661         * @return The truncated array
10662         */
10663        public static float[][] truncate(final float[][] array, final int index)
10664        {
10665                final float[][] d = new float[Math.min(array.length, index)][index];
10666                for (int i = 0; i < d.length; i++)
10667                        d[i] = truncate(array[i], index);
10668                return d;
10669        }
10670
10671    
10672        /**
10673         * Truncates the given array to the given size.
10674         * 
10675         * @param array
10676         *            The array to truncate
10677         * @param index
10678         *            The size to truncate it to
10679         * @return The truncated array
10680         */
10681        public static int[] truncate(final int[] array, final int index)
10682        {
10683                final int[] d = new int[index];
10684                System.arraycopy(array, 0, d, 0, index);
10685                return d;
10686        }
10687
10688        /**
10689         * Truncates every element in the given array to the given size.
10690         * 
10691         * @param array
10692         *            The array to truncate
10693         * @param index
10694         *            The size to truncate it to
10695         * @return The truncated array
10696         */
10697        public static int[][] truncate(final int[][] array, final int index)
10698        {
10699                final int[][] d = new int[Math.min(array.length, index)][index];
10700                for (int i = 0; i < d.length; i++)
10701                        d[i] = truncate(array[i], index);
10702                return d;
10703        }
10704
10705    
10706        /**
10707         * Truncates the given array to the given size.
10708         * 
10709         * @param array
10710         *            The array to truncate
10711         * @param index
10712         *            The size to truncate it to
10713         * @return The truncated array
10714         */
10715        public static long[] truncate(final long[] array, final int index)
10716        {
10717                final long[] d = new long[index];
10718                System.arraycopy(array, 0, d, 0, index);
10719                return d;
10720        }
10721
10722        /**
10723         * Truncates every element in the given array to the given size.
10724         * 
10725         * @param array
10726         *            The array to truncate
10727         * @param index
10728         *            The size to truncate it to
10729         * @return The truncated array
10730         */
10731        public static long[][] truncate(final long[][] array, final int index)
10732        {
10733                final long[][] d = new long[Math.min(array.length, index)][index];
10734                for (int i = 0; i < d.length; i++)
10735                        d[i] = truncate(array[i], index);
10736                return d;
10737        }
10738
10739    
10740        /**
10741         * Truncates the given array to the given size.
10742         * 
10743         * @param array
10744         *            The array to truncate
10745         * @param index
10746         *            The size to truncate it to
10747         * @return The truncated array
10748         */
10749        public static byte[] truncate(final byte[] array, final int index)
10750        {
10751                final byte[] d = new byte[index];
10752                System.arraycopy(array, 0, d, 0, index);
10753                return d;
10754        }
10755
10756        /**
10757         * Truncates every element in the given array to the given size.
10758         * 
10759         * @param array
10760         *            The array to truncate
10761         * @param index
10762         *            The size to truncate it to
10763         * @return The truncated array
10764         */
10765        public static byte[][] truncate(final byte[][] array, final int index)
10766        {
10767                final byte[][] d = new byte[Math.min(array.length, index)][index];
10768                for (int i = 0; i < d.length; i++)
10769                        d[i] = truncate(array[i], index);
10770                return d;
10771        }
10772
10773    
10774        /**
10775         * Truncates the given array to the given size.
10776         * 
10777         * @param array
10778         *            The array to truncate
10779         * @param index
10780         *            The size to truncate it to
10781         * @return The truncated array
10782         */
10783        public static short[] truncate(final short[] array, final int index)
10784        {
10785                final short[] d = new short[index];
10786                System.arraycopy(array, 0, d, 0, index);
10787                return d;
10788        }
10789
10790        /**
10791         * Truncates every element in the given array to the given size.
10792         * 
10793         * @param array
10794         *            The array to truncate
10795         * @param index
10796         *            The size to truncate it to
10797         * @return The truncated array
10798         */
10799        public static short[][] truncate(final short[][] array, final int index)
10800        {
10801                final short[][] d = new short[Math.min(array.length, index)][index];
10802                for (int i = 0; i < d.length; i++)
10803                        d[i] = truncate(array[i], index);
10804                return d;
10805        }
10806
10807    
10808        /**
10809         * Quick Select algorithm for getting the nth item from the array as if it
10810         * were sorted. Expected complexity is O(N); worst case is O(N^2). The input
10811         * array will be reordered; clone it first if this is a problem.
10812         * Implementation based on public domain code from Nicolas Devillard.
10813         * 
10814         * @see "http://ndevilla.free.fr/median/median/src/quickselect.c"
10815         * 
10816         * @param arr
10817         *            the array to select from
10818         * @param n
10819         *            the item to select
10820         * @return the selected item
10821         */
10822        public static double quickSelect(double arr[], int n) {
10823                return quickSelect(arr, n, 0, arr.length - 1);
10824        }
10825
10826        /**
10827         * Quick Select algorithm for getting the nth item from a sub-array as if it
10828         * were sorted. Expected complexity is O(N); worst case is O(N^2). The input
10829         * array will be reordered; clone it first if this is a problem.
10830         * Implementation based on public domain code from Nicolas Devillard.
10831         * 
10832         * @see "http://ndevilla.free.fr/median/median/src/quickselect.c"
10833         * 
10834         * @param arr
10835         *            the array to select from
10836         * @param n
10837         *            the item to select
10838         * @param low
10839         *            the starting position in the array (inclusive)
10840         * @param high
10841         *            the ending position in the array (exclusive)
10842         * @return the selected item
10843         */
10844        public static double quickSelect(double arr[], int n, int low, int high) {
10845                high--; // make high inclusive
10846
10847                int middle, ll, hh;
10848                double tmp = 0;
10849                final int median = (low + high) / 2;
10850
10851                while (true) {
10852                        if (high <= low) /* One element only */
10853                                return arr[median];
10854
10855                        if (high == low + 1) { /* Two elements only */
10856                                if (arr[low] > arr[high]) {
10857                                        tmp = arr[low];
10858                                        arr[low] = arr[high];
10859                                        arr[high] = tmp;
10860                                }
10861                                return arr[median];
10862                        }
10863
10864                        /* Find median of low, middle and high items; swap into position low */
10865                        middle = (low + high) / 2;
10866                        if (arr[middle] > arr[high]) {
10867                                tmp = arr[middle];
10868                                arr[middle] = arr[high];
10869                                arr[high] = tmp;
10870                                ;
10871                        }
10872                        if (arr[low] > arr[high]) {
10873                                tmp = arr[low];
10874                                arr[low] = arr[high];
10875                                arr[high] = tmp;
10876                        }
10877                        if (arr[middle] > arr[low]) {
10878                                tmp = arr[low];
10879                                arr[low] = arr[middle];
10880                                arr[middle] = tmp;
10881                        }
10882
10883                        /* Swap low item (now in position middle) into position (low+1) */
10884                        tmp = arr[middle];
10885                        arr[middle] = arr[low + 1];
10886                        arr[low + 1] = tmp;
10887
10888                        /* Nibble from each end towards middle, swapping items when stuck */
10889                        ll = low + 1;
10890                        hh = high;
10891                        for (;;) {
10892                                do
10893                                        ll++;
10894                                while (arr[low] > arr[ll]);
10895                                do
10896                                        hh--;
10897                                while (arr[hh] > arr[low]);
10898
10899                                if (hh < ll)
10900                                        break;
10901
10902                                tmp = arr[ll];
10903                                arr[ll] = arr[hh];
10904                                arr[hh] = tmp;
10905                        }
10906
10907                        /* Swap middle item (in position low) back into correct position */
10908                        tmp = arr[low];
10909                        arr[low] = arr[hh];
10910                        arr[hh] = tmp;
10911
10912                        /* Re-set active partition */
10913                        if (hh <= median)
10914                                low = ll;
10915                        if (hh >= median)
10916                                high = hh - 1;
10917                }
10918        }       
10919        
10920        /**
10921         * Quick Select algorithm for getting the nth item from the array as if it
10922         * were sorted. Expected complexity is O(N); worst case is O(N^2). The input
10923         * array will be reordered; clone it first if this is a problem.
10924         * Implementation based on public domain code from Nicolas Devillard.
10925         * 
10926         * @see "http://ndevilla.free.fr/median/median/src/quickselect.c"
10927         * 
10928         * @param arr
10929         *            the array to select from
10930         * @param n
10931         *            the item to select
10932         * @return the selected item
10933         */
10934        public static float quickSelect(float arr[], int n) {
10935                return quickSelect(arr, n, 0, arr.length - 1);
10936        }
10937
10938        /**
10939         * Quick Select algorithm for getting the nth item from a sub-array as if it
10940         * were sorted. Expected complexity is O(N); worst case is O(N^2). The input
10941         * array will be reordered; clone it first if this is a problem.
10942         * Implementation based on public domain code from Nicolas Devillard.
10943         * 
10944         * @see "http://ndevilla.free.fr/median/median/src/quickselect.c"
10945         * 
10946         * @param arr
10947         *            the array to select from
10948         * @param n
10949         *            the item to select
10950         * @param low
10951         *            the starting position in the array (inclusive)
10952         * @param high
10953         *            the ending position in the array (exclusive)
10954         * @return the selected item
10955         */
10956        public static float quickSelect(float arr[], int n, int low, int high) {
10957                high--; // make high inclusive
10958
10959                int middle, ll, hh;
10960                float tmp = 0;
10961                final int median = (low + high) / 2;
10962
10963                while (true) {
10964                        if (high <= low) /* One element only */
10965                                return arr[median];
10966
10967                        if (high == low + 1) { /* Two elements only */
10968                                if (arr[low] > arr[high]) {
10969                                        tmp = arr[low];
10970                                        arr[low] = arr[high];
10971                                        arr[high] = tmp;
10972                                }
10973                                return arr[median];
10974                        }
10975
10976                        /* Find median of low, middle and high items; swap into position low */
10977                        middle = (low + high) / 2;
10978                        if (arr[middle] > arr[high]) {
10979                                tmp = arr[middle];
10980                                arr[middle] = arr[high];
10981                                arr[high] = tmp;
10982                                ;
10983                        }
10984                        if (arr[low] > arr[high]) {
10985                                tmp = arr[low];
10986                                arr[low] = arr[high];
10987                                arr[high] = tmp;
10988                        }
10989                        if (arr[middle] > arr[low]) {
10990                                tmp = arr[low];
10991                                arr[low] = arr[middle];
10992                                arr[middle] = tmp;
10993                        }
10994
10995                        /* Swap low item (now in position middle) into position (low+1) */
10996                        tmp = arr[middle];
10997                        arr[middle] = arr[low + 1];
10998                        arr[low + 1] = tmp;
10999
11000                        /* Nibble from each end towards middle, swapping items when stuck */
11001                        ll = low + 1;
11002                        hh = high;
11003                        for (;;) {
11004                                do
11005                                        ll++;
11006                                while (arr[low] > arr[ll]);
11007                                do
11008                                        hh--;
11009                                while (arr[hh] > arr[low]);
11010
11011                                if (hh < ll)
11012                                        break;
11013
11014                                tmp = arr[ll];
11015                                arr[ll] = arr[hh];
11016                                arr[hh] = tmp;
11017                        }
11018
11019                        /* Swap middle item (in position low) back into correct position */
11020                        tmp = arr[low];
11021                        arr[low] = arr[hh];
11022                        arr[hh] = tmp;
11023
11024                        /* Re-set active partition */
11025                        if (hh <= median)
11026                                low = ll;
11027                        if (hh >= median)
11028                                high = hh - 1;
11029                }
11030        }       
11031        
11032        /**
11033         * Quick Select algorithm for getting the nth item from the array as if it
11034         * were sorted. Expected complexity is O(N); worst case is O(N^2). The input
11035         * array will be reordered; clone it first if this is a problem.
11036         * Implementation based on public domain code from Nicolas Devillard.
11037         * 
11038         * @see "http://ndevilla.free.fr/median/median/src/quickselect.c"
11039         * 
11040         * @param arr
11041         *            the array to select from
11042         * @param n
11043         *            the item to select
11044         * @return the selected item
11045         */
11046        public static int quickSelect(int arr[], int n) {
11047                return quickSelect(arr, n, 0, arr.length - 1);
11048        }
11049
11050        /**
11051         * Quick Select algorithm for getting the nth item from a sub-array as if it
11052         * were sorted. Expected complexity is O(N); worst case is O(N^2). The input
11053         * array will be reordered; clone it first if this is a problem.
11054         * Implementation based on public domain code from Nicolas Devillard.
11055         * 
11056         * @see "http://ndevilla.free.fr/median/median/src/quickselect.c"
11057         * 
11058         * @param arr
11059         *            the array to select from
11060         * @param n
11061         *            the item to select
11062         * @param low
11063         *            the starting position in the array (inclusive)
11064         * @param high
11065         *            the ending position in the array (exclusive)
11066         * @return the selected item
11067         */
11068        public static int quickSelect(int arr[], int n, int low, int high) {
11069                high--; // make high inclusive
11070
11071                int middle, ll, hh;
11072                int tmp = 0;
11073                final int median = (low + high) / 2;
11074
11075                while (true) {
11076                        if (high <= low) /* One element only */
11077                                return arr[median];
11078
11079                        if (high == low + 1) { /* Two elements only */
11080                                if (arr[low] > arr[high]) {
11081                                        tmp = arr[low];
11082                                        arr[low] = arr[high];
11083                                        arr[high] = tmp;
11084                                }
11085                                return arr[median];
11086                        }
11087
11088                        /* Find median of low, middle and high items; swap into position low */
11089                        middle = (low + high) / 2;
11090                        if (arr[middle] > arr[high]) {
11091                                tmp = arr[middle];
11092                                arr[middle] = arr[high];
11093                                arr[high] = tmp;
11094                                ;
11095                        }
11096                        if (arr[low] > arr[high]) {
11097                                tmp = arr[low];
11098                                arr[low] = arr[high];
11099                                arr[high] = tmp;
11100                        }
11101                        if (arr[middle] > arr[low]) {
11102                                tmp = arr[low];
11103                                arr[low] = arr[middle];
11104                                arr[middle] = tmp;
11105                        }
11106
11107                        /* Swap low item (now in position middle) into position (low+1) */
11108                        tmp = arr[middle];
11109                        arr[middle] = arr[low + 1];
11110                        arr[low + 1] = tmp;
11111
11112                        /* Nibble from each end towards middle, swapping items when stuck */
11113                        ll = low + 1;
11114                        hh = high;
11115                        for (;;) {
11116                                do
11117                                        ll++;
11118                                while (arr[low] > arr[ll]);
11119                                do
11120                                        hh--;
11121                                while (arr[hh] > arr[low]);
11122
11123                                if (hh < ll)
11124                                        break;
11125
11126                                tmp = arr[ll];
11127                                arr[ll] = arr[hh];
11128                                arr[hh] = tmp;
11129                        }
11130
11131                        /* Swap middle item (in position low) back into correct position */
11132                        tmp = arr[low];
11133                        arr[low] = arr[hh];
11134                        arr[hh] = tmp;
11135
11136                        /* Re-set active partition */
11137                        if (hh <= median)
11138                                low = ll;
11139                        if (hh >= median)
11140                                high = hh - 1;
11141                }
11142        }       
11143        
11144        /**
11145         * Quick Select algorithm for getting the nth item from the array as if it
11146         * were sorted. Expected complexity is O(N); worst case is O(N^2). The input
11147         * array will be reordered; clone it first if this is a problem.
11148         * Implementation based on public domain code from Nicolas Devillard.
11149         * 
11150         * @see "http://ndevilla.free.fr/median/median/src/quickselect.c"
11151         * 
11152         * @param arr
11153         *            the array to select from
11154         * @param n
11155         *            the item to select
11156         * @return the selected item
11157         */
11158        public static long quickSelect(long arr[], int n) {
11159                return quickSelect(arr, n, 0, arr.length - 1);
11160        }
11161
11162        /**
11163         * Quick Select algorithm for getting the nth item from a sub-array as if it
11164         * were sorted. Expected complexity is O(N); worst case is O(N^2). The input
11165         * array will be reordered; clone it first if this is a problem.
11166         * Implementation based on public domain code from Nicolas Devillard.
11167         * 
11168         * @see "http://ndevilla.free.fr/median/median/src/quickselect.c"
11169         * 
11170         * @param arr
11171         *            the array to select from
11172         * @param n
11173         *            the item to select
11174         * @param low
11175         *            the starting position in the array (inclusive)
11176         * @param high
11177         *            the ending position in the array (exclusive)
11178         * @return the selected item
11179         */
11180        public static long quickSelect(long arr[], int n, int low, int high) {
11181                high--; // make high inclusive
11182
11183                int middle, ll, hh;
11184                long tmp = 0;
11185                final int median = (low + high) / 2;
11186
11187                while (true) {
11188                        if (high <= low) /* One element only */
11189                                return arr[median];
11190
11191                        if (high == low + 1) { /* Two elements only */
11192                                if (arr[low] > arr[high]) {
11193                                        tmp = arr[low];
11194                                        arr[low] = arr[high];
11195                                        arr[high] = tmp;
11196                                }
11197                                return arr[median];
11198                        }
11199
11200                        /* Find median of low, middle and high items; swap into position low */
11201                        middle = (low + high) / 2;
11202                        if (arr[middle] > arr[high]) {
11203                                tmp = arr[middle];
11204                                arr[middle] = arr[high];
11205                                arr[high] = tmp;
11206                                ;
11207                        }
11208                        if (arr[low] > arr[high]) {
11209                                tmp = arr[low];
11210                                arr[low] = arr[high];
11211                                arr[high] = tmp;
11212                        }
11213                        if (arr[middle] > arr[low]) {
11214                                tmp = arr[low];
11215                                arr[low] = arr[middle];
11216                                arr[middle] = tmp;
11217                        }
11218
11219                        /* Swap low item (now in position middle) into position (low+1) */
11220                        tmp = arr[middle];
11221                        arr[middle] = arr[low + 1];
11222                        arr[low + 1] = tmp;
11223
11224                        /* Nibble from each end towards middle, swapping items when stuck */
11225                        ll = low + 1;
11226                        hh = high;
11227                        for (;;) {
11228                                do
11229                                        ll++;
11230                                while (arr[low] > arr[ll]);
11231                                do
11232                                        hh--;
11233                                while (arr[hh] > arr[low]);
11234
11235                                if (hh < ll)
11236                                        break;
11237
11238                                tmp = arr[ll];
11239                                arr[ll] = arr[hh];
11240                                arr[hh] = tmp;
11241                        }
11242
11243                        /* Swap middle item (in position low) back into correct position */
11244                        tmp = arr[low];
11245                        arr[low] = arr[hh];
11246                        arr[hh] = tmp;
11247
11248                        /* Re-set active partition */
11249                        if (hh <= median)
11250                                low = ll;
11251                        if (hh >= median)
11252                                high = hh - 1;
11253                }
11254        }       
11255        
11256        /**
11257         * Quick Select algorithm for getting the nth item from the array as if it
11258         * were sorted. Expected complexity is O(N); worst case is O(N^2). The input
11259         * array will be reordered; clone it first if this is a problem.
11260         * Implementation based on public domain code from Nicolas Devillard.
11261         * 
11262         * @see "http://ndevilla.free.fr/median/median/src/quickselect.c"
11263         * 
11264         * @param arr
11265         *            the array to select from
11266         * @param n
11267         *            the item to select
11268         * @return the selected item
11269         */
11270        public static byte quickSelect(byte arr[], int n) {
11271                return quickSelect(arr, n, 0, arr.length - 1);
11272        }
11273
11274        /**
11275         * Quick Select algorithm for getting the nth item from a sub-array as if it
11276         * were sorted. Expected complexity is O(N); worst case is O(N^2). The input
11277         * array will be reordered; clone it first if this is a problem.
11278         * Implementation based on public domain code from Nicolas Devillard.
11279         * 
11280         * @see "http://ndevilla.free.fr/median/median/src/quickselect.c"
11281         * 
11282         * @param arr
11283         *            the array to select from
11284         * @param n
11285         *            the item to select
11286         * @param low
11287         *            the starting position in the array (inclusive)
11288         * @param high
11289         *            the ending position in the array (exclusive)
11290         * @return the selected item
11291         */
11292        public static byte quickSelect(byte arr[], int n, int low, int high) {
11293                high--; // make high inclusive
11294
11295                int middle, ll, hh;
11296                byte tmp = 0;
11297                final int median = (low + high) / 2;
11298
11299                while (true) {
11300                        if (high <= low) /* One element only */
11301                                return arr[median];
11302
11303                        if (high == low + 1) { /* Two elements only */
11304                                if (arr[low] > arr[high]) {
11305                                        tmp = arr[low];
11306                                        arr[low] = arr[high];
11307                                        arr[high] = tmp;
11308                                }
11309                                return arr[median];
11310                        }
11311
11312                        /* Find median of low, middle and high items; swap into position low */
11313                        middle = (low + high) / 2;
11314                        if (arr[middle] > arr[high]) {
11315                                tmp = arr[middle];
11316                                arr[middle] = arr[high];
11317                                arr[high] = tmp;
11318                                ;
11319                        }
11320                        if (arr[low] > arr[high]) {
11321                                tmp = arr[low];
11322                                arr[low] = arr[high];
11323                                arr[high] = tmp;
11324                        }
11325                        if (arr[middle] > arr[low]) {
11326                                tmp = arr[low];
11327                                arr[low] = arr[middle];
11328                                arr[middle] = tmp;
11329                        }
11330
11331                        /* Swap low item (now in position middle) into position (low+1) */
11332                        tmp = arr[middle];
11333                        arr[middle] = arr[low + 1];
11334                        arr[low + 1] = tmp;
11335
11336                        /* Nibble from each end towards middle, swapping items when stuck */
11337                        ll = low + 1;
11338                        hh = high;
11339                        for (;;) {
11340                                do
11341                                        ll++;
11342                                while (arr[low] > arr[ll]);
11343                                do
11344                                        hh--;
11345                                while (arr[hh] > arr[low]);
11346
11347                                if (hh < ll)
11348                                        break;
11349
11350                                tmp = arr[ll];
11351                                arr[ll] = arr[hh];
11352                                arr[hh] = tmp;
11353                        }
11354
11355                        /* Swap middle item (in position low) back into correct position */
11356                        tmp = arr[low];
11357                        arr[low] = arr[hh];
11358                        arr[hh] = tmp;
11359
11360                        /* Re-set active partition */
11361                        if (hh <= median)
11362                                low = ll;
11363                        if (hh >= median)
11364                                high = hh - 1;
11365                }
11366        }       
11367        
11368        /**
11369         * Quick Select algorithm for getting the nth item from the array as if it
11370         * were sorted. Expected complexity is O(N); worst case is O(N^2). The input
11371         * array will be reordered; clone it first if this is a problem.
11372         * Implementation based on public domain code from Nicolas Devillard.
11373         * 
11374         * @see "http://ndevilla.free.fr/median/median/src/quickselect.c"
11375         * 
11376         * @param arr
11377         *            the array to select from
11378         * @param n
11379         *            the item to select
11380         * @return the selected item
11381         */
11382        public static short quickSelect(short arr[], int n) {
11383                return quickSelect(arr, n, 0, arr.length - 1);
11384        }
11385
11386        /**
11387         * Quick Select algorithm for getting the nth item from a sub-array as if it
11388         * were sorted. Expected complexity is O(N); worst case is O(N^2). The input
11389         * array will be reordered; clone it first if this is a problem.
11390         * Implementation based on public domain code from Nicolas Devillard.
11391         * 
11392         * @see "http://ndevilla.free.fr/median/median/src/quickselect.c"
11393         * 
11394         * @param arr
11395         *            the array to select from
11396         * @param n
11397         *            the item to select
11398         * @param low
11399         *            the starting position in the array (inclusive)
11400         * @param high
11401         *            the ending position in the array (exclusive)
11402         * @return the selected item
11403         */
11404        public static short quickSelect(short arr[], int n, int low, int high) {
11405                high--; // make high inclusive
11406
11407                int middle, ll, hh;
11408                short tmp = 0;
11409                final int median = (low + high) / 2;
11410
11411                while (true) {
11412                        if (high <= low) /* One element only */
11413                                return arr[median];
11414
11415                        if (high == low + 1) { /* Two elements only */
11416                                if (arr[low] > arr[high]) {
11417                                        tmp = arr[low];
11418                                        arr[low] = arr[high];
11419                                        arr[high] = tmp;
11420                                }
11421                                return arr[median];
11422                        }
11423
11424                        /* Find median of low, middle and high items; swap into position low */
11425                        middle = (low + high) / 2;
11426                        if (arr[middle] > arr[high]) {
11427                                tmp = arr[middle];
11428                                arr[middle] = arr[high];
11429                                arr[high] = tmp;
11430                                ;
11431                        }
11432                        if (arr[low] > arr[high]) {
11433                                tmp = arr[low];
11434                                arr[low] = arr[high];
11435                                arr[high] = tmp;
11436                        }
11437                        if (arr[middle] > arr[low]) {
11438                                tmp = arr[low];
11439                                arr[low] = arr[middle];
11440                                arr[middle] = tmp;
11441                        }
11442
11443                        /* Swap low item (now in position middle) into position (low+1) */
11444                        tmp = arr[middle];
11445                        arr[middle] = arr[low + 1];
11446                        arr[low + 1] = tmp;
11447
11448                        /* Nibble from each end towards middle, swapping items when stuck */
11449                        ll = low + 1;
11450                        hh = high;
11451                        for (;;) {
11452                                do
11453                                        ll++;
11454                                while (arr[low] > arr[ll]);
11455                                do
11456                                        hh--;
11457                                while (arr[hh] > arr[low]);
11458
11459                                if (hh < ll)
11460                                        break;
11461
11462                                tmp = arr[ll];
11463                                arr[ll] = arr[hh];
11464                                arr[hh] = tmp;
11465                        }
11466
11467                        /* Swap middle item (in position low) back into correct position */
11468                        tmp = arr[low];
11469                        arr[low] = arr[hh];
11470                        arr[hh] = tmp;
11471
11472                        /* Re-set active partition */
11473                        if (hh <= median)
11474                                low = ll;
11475                        if (hh >= median)
11476                                high = hh - 1;
11477                }
11478        }       
11479        
11480        /**
11481         * Convert from Double[] to double[]. This will create a new array and copy the contents.
11482         *
11483         * @param array input array
11484         * @return the converted array
11485         */
11486        public double[] convert(Double[] array) {
11487                double[] out = new double[array.length];
11488                
11489                for (int i=0; i<array.length; i++) {
11490                        out[i] = array[i];
11491                }
11492                
11493                return out;
11494        }
11495        
11496        /**
11497         * Convert from Double[] to Double[]. This will create a new array and copy the contents.
11498         *
11499         * @param array input array
11500         * @return the converted array
11501         */
11502        public Double[] convert(double[] array) {
11503                Double[] out = new Double[array.length];
11504                
11505                for (int i=0; i<array.length; i++) {
11506                        out[i] = array[i];
11507                }
11508                
11509                return out;
11510        }
11511        
11512        /**
11513         * Convert from Float[] to float[]. This will create a new array and copy the contents.
11514         *
11515         * @param array input array
11516         * @return the converted array
11517         */
11518        public float[] convert(Float[] array) {
11519                float[] out = new float[array.length];
11520                
11521                for (int i=0; i<array.length; i++) {
11522                        out[i] = array[i];
11523                }
11524                
11525                return out;
11526        }
11527        
11528        /**
11529         * Convert from Float[] to Float[]. This will create a new array and copy the contents.
11530         *
11531         * @param array input array
11532         * @return the converted array
11533         */
11534        public Float[] convert(float[] array) {
11535                Float[] out = new Float[array.length];
11536                
11537                for (int i=0; i<array.length; i++) {
11538                        out[i] = array[i];
11539                }
11540                
11541                return out;
11542        }
11543        
11544        /**
11545         * Convert from Integer[] to int[]. This will create a new array and copy the contents.
11546         *
11547         * @param array input array
11548         * @return the converted array
11549         */
11550        public int[] convert(Integer[] array) {
11551                int[] out = new int[array.length];
11552                
11553                for (int i=0; i<array.length; i++) {
11554                        out[i] = array[i];
11555                }
11556                
11557                return out;
11558        }
11559        
11560        /**
11561         * Convert from Int[] to Integer[]. This will create a new array and copy the contents.
11562         *
11563         * @param array input array
11564         * @return the converted array
11565         */
11566        public Integer[] convert(int[] array) {
11567                Integer[] out = new Integer[array.length];
11568                
11569                for (int i=0; i<array.length; i++) {
11570                        out[i] = array[i];
11571                }
11572                
11573                return out;
11574        }
11575        
11576        /**
11577         * Convert from Long[] to long[]. This will create a new array and copy the contents.
11578         *
11579         * @param array input array
11580         * @return the converted array
11581         */
11582        public long[] convert(Long[] array) {
11583                long[] out = new long[array.length];
11584                
11585                for (int i=0; i<array.length; i++) {
11586                        out[i] = array[i];
11587                }
11588                
11589                return out;
11590        }
11591        
11592        /**
11593         * Convert from Long[] to Long[]. This will create a new array and copy the contents.
11594         *
11595         * @param array input array
11596         * @return the converted array
11597         */
11598        public Long[] convert(long[] array) {
11599                Long[] out = new Long[array.length];
11600                
11601                for (int i=0; i<array.length; i++) {
11602                        out[i] = array[i];
11603                }
11604                
11605                return out;
11606        }
11607        
11608        /**
11609         * Convert from Byte[] to byte[]. This will create a new array and copy the contents.
11610         *
11611         * @param array input array
11612         * @return the converted array
11613         */
11614        public byte[] convert(Byte[] array) {
11615                byte[] out = new byte[array.length];
11616                
11617                for (int i=0; i<array.length; i++) {
11618                        out[i] = array[i];
11619                }
11620                
11621                return out;
11622        }
11623        
11624        /**
11625         * Convert from Byte[] to Byte[]. This will create a new array and copy the contents.
11626         *
11627         * @param array input array
11628         * @return the converted array
11629         */
11630        public Byte[] convert(byte[] array) {
11631                Byte[] out = new Byte[array.length];
11632                
11633                for (int i=0; i<array.length; i++) {
11634                        out[i] = array[i];
11635                }
11636                
11637                return out;
11638        }
11639        
11640        /**
11641         * Convert from Short[] to short[]. This will create a new array and copy the contents.
11642         *
11643         * @param array input array
11644         * @return the converted array
11645         */
11646        public short[] convert(Short[] array) {
11647                short[] out = new short[array.length];
11648                
11649                for (int i=0; i<array.length; i++) {
11650                        out[i] = array[i];
11651                }
11652                
11653                return out;
11654        }
11655        
11656        /**
11657         * Convert from Short[] to Short[]. This will create a new array and copy the contents.
11658         *
11659         * @param array input array
11660         * @return the converted array
11661         */
11662        public Short[] convert(short[] array) {
11663                Short[] out = new Short[array.length];
11664                
11665                for (int i=0; i<array.length; i++) {
11666                        out[i] = array[i];
11667                }
11668                
11669                return out;
11670        }
11671        
11672}