001/*
002        AUTOMATICALLY GENERATED BY jTemp FROM
003        /Users/jsh2/Work/openimaj/target/checkout/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         * Format the array as a string, using the provided format 
053         * string to control how each value is printed.
054         * 
055         * @param arr
056         *            array of double
057         * @param fmt
058         *            format string for each element
059         * @return the value
060         */
061    public static String toString(double[] arr, String fmt) {
062                StringBuffer localStringBuffer = new StringBuffer();
063                localStringBuffer.append("[");
064                int i = arr.length - 1;
065                for (int j = 0; j <= i; ++j)
066                {
067                        localStringBuffer.append(String.format(fmt, arr[j]));
068                        if (j >= i)
069                                continue;
070                        localStringBuffer.append(", ");
071                }
072                localStringBuffer.append("]");
073                return localStringBuffer.toString();
074        }
075    
076    
077        /**
078         * Format the array as a string, using the provided format 
079         * string to control how each value is printed.
080         * 
081         * @param arr
082         *            array of float
083         * @param fmt
084         *            format string for each element
085         * @return the value
086         */
087    public static String toString(float[] arr, String fmt) {
088                StringBuffer localStringBuffer = new StringBuffer();
089                localStringBuffer.append("[");
090                int i = arr.length - 1;
091                for (int j = 0; j <= i; ++j)
092                {
093                        localStringBuffer.append(String.format(fmt, arr[j]));
094                        if (j >= i)
095                                continue;
096                        localStringBuffer.append(", ");
097                }
098                localStringBuffer.append("]");
099                return localStringBuffer.toString();
100        }
101    
102    
103        /**
104         * Format the array as a string, using the provided format 
105         * string to control how each value is printed.
106         * 
107         * @param arr
108         *            array of int
109         * @param fmt
110         *            format string for each element
111         * @return the value
112         */
113    public static String toString(int[] arr, String fmt) {
114                StringBuffer localStringBuffer = new StringBuffer();
115                localStringBuffer.append("[");
116                int i = arr.length - 1;
117                for (int j = 0; j <= i; ++j)
118                {
119                        localStringBuffer.append(String.format(fmt, arr[j]));
120                        if (j >= i)
121                                continue;
122                        localStringBuffer.append(", ");
123                }
124                localStringBuffer.append("]");
125                return localStringBuffer.toString();
126        }
127    
128    
129        /**
130         * Format the array as a string, using the provided format 
131         * string to control how each value is printed.
132         * 
133         * @param arr
134         *            array of long
135         * @param fmt
136         *            format string for each element
137         * @return the value
138         */
139    public static String toString(long[] arr, String fmt) {
140                StringBuffer localStringBuffer = new StringBuffer();
141                localStringBuffer.append("[");
142                int i = arr.length - 1;
143                for (int j = 0; j <= i; ++j)
144                {
145                        localStringBuffer.append(String.format(fmt, arr[j]));
146                        if (j >= i)
147                                continue;
148                        localStringBuffer.append(", ");
149                }
150                localStringBuffer.append("]");
151                return localStringBuffer.toString();
152        }
153    
154    
155        /**
156         * Format the array as a string, using the provided format 
157         * string to control how each value is printed.
158         * 
159         * @param arr
160         *            array of byte
161         * @param fmt
162         *            format string for each element
163         * @return the value
164         */
165    public static String toString(byte[] arr, String fmt) {
166                StringBuffer localStringBuffer = new StringBuffer();
167                localStringBuffer.append("[");
168                int i = arr.length - 1;
169                for (int j = 0; j <= i; ++j)
170                {
171                        localStringBuffer.append(String.format(fmt, arr[j]));
172                        if (j >= i)
173                                continue;
174                        localStringBuffer.append(", ");
175                }
176                localStringBuffer.append("]");
177                return localStringBuffer.toString();
178        }
179    
180    
181        /**
182         * Format the array as a string, using the provided format 
183         * string to control how each value is printed.
184         * 
185         * @param arr
186         *            array of short
187         * @param fmt
188         *            format string for each element
189         * @return the value
190         */
191    public static String toString(short[] arr, String fmt) {
192                StringBuffer localStringBuffer = new StringBuffer();
193                localStringBuffer.append("[");
194                int i = arr.length - 1;
195                for (int j = 0; j <= i; ++j)
196                {
197                        localStringBuffer.append(String.format(fmt, arr[j]));
198                        if (j >= i)
199                                continue;
200                        localStringBuffer.append(", ");
201                }
202                localStringBuffer.append("]");
203                return localStringBuffer.toString();
204        }
205    
206    
207        /**
208         * Returns the largest value in the array.
209         * 
210         * @param arr
211         *            array of double
212         * @return the value
213         */
214        public static double maxValue(final double[] arr) {
215                if (arr.length < 0)
216                        return 0;
217
218                double max = arr[0];
219                for (int i = 1; i < arr.length; i++) {
220                        if (arr[i] > max) {
221                                max = arr[i];
222                        }
223                }
224
225                return max;
226        }
227
228    
229        /**
230         * Returns the largest value in the array.
231         * 
232         * @param arr
233         *            array of float
234         * @return the value
235         */
236        public static float maxValue(final float[] arr) {
237                if (arr.length < 0)
238                        return 0;
239
240                float max = arr[0];
241                for (int i = 1; i < arr.length; i++) {
242                        if (arr[i] > max) {
243                                max = arr[i];
244                        }
245                }
246
247                return max;
248        }
249
250    
251        /**
252         * Returns the largest value in the array.
253         * 
254         * @param arr
255         *            array of int
256         * @return the value
257         */
258        public static int maxValue(final int[] arr) {
259                if (arr.length < 0)
260                        return 0;
261
262                int max = arr[0];
263                for (int i = 1; i < arr.length; i++) {
264                        if (arr[i] > max) {
265                                max = arr[i];
266                        }
267                }
268
269                return max;
270        }
271
272    
273        /**
274         * Returns the largest value in the array.
275         * 
276         * @param arr
277         *            array of long
278         * @return the value
279         */
280        public static long maxValue(final long[] arr) {
281                if (arr.length < 0)
282                        return 0;
283
284                long max = arr[0];
285                for (int i = 1; i < arr.length; i++) {
286                        if (arr[i] > max) {
287                                max = arr[i];
288                        }
289                }
290
291                return max;
292        }
293
294    
295        /**
296         * Returns the largest value in the array.
297         * 
298         * @param arr
299         *            array of byte
300         * @return the value
301         */
302        public static byte maxValue(final byte[] arr) {
303                if (arr.length < 0)
304                        return 0;
305
306                byte max = arr[0];
307                for (int i = 1; i < arr.length; i++) {
308                        if (arr[i] > max) {
309                                max = arr[i];
310                        }
311                }
312
313                return max;
314        }
315
316    
317        /**
318         * Returns the largest value in the array.
319         * 
320         * @param arr
321         *            array of short
322         * @return the value
323         */
324        public static short maxValue(final short[] arr) {
325                if (arr.length < 0)
326                        return 0;
327
328                short max = arr[0];
329                for (int i = 1; i < arr.length; i++) {
330                        if (arr[i] > max) {
331                                max = arr[i];
332                        }
333                }
334
335                return max;
336        }
337
338    
339        /**
340         * Returns the smallest value in the array.
341         * 
342         * @param arr
343         *            array of double
344         * @return the value
345         */
346        public static double minValue(final double[] arr) {
347                if (arr.length < 0)
348                        return 0;
349
350                double min = arr[0];
351                for (int i = 1; i < arr.length; i++) {
352                        if (arr[i] < min) {
353                                min = arr[i];
354                        }
355                }
356
357                return min;
358        }
359
360    
361        /**
362         * Returns the smallest value in the array.
363         * 
364         * @param arr
365         *            array of float
366         * @return the value
367         */
368        public static float minValue(final float[] arr) {
369                if (arr.length < 0)
370                        return 0;
371
372                float min = arr[0];
373                for (int i = 1; i < arr.length; i++) {
374                        if (arr[i] < min) {
375                                min = arr[i];
376                        }
377                }
378
379                return min;
380        }
381
382    
383        /**
384         * Returns the smallest value in the array.
385         * 
386         * @param arr
387         *            array of int
388         * @return the value
389         */
390        public static int minValue(final int[] arr) {
391                if (arr.length < 0)
392                        return 0;
393
394                int min = arr[0];
395                for (int i = 1; i < arr.length; i++) {
396                        if (arr[i] < min) {
397                                min = arr[i];
398                        }
399                }
400
401                return min;
402        }
403
404    
405        /**
406         * Returns the smallest value in the array.
407         * 
408         * @param arr
409         *            array of long
410         * @return the value
411         */
412        public static long minValue(final long[] arr) {
413                if (arr.length < 0)
414                        return 0;
415
416                long min = arr[0];
417                for (int i = 1; i < arr.length; i++) {
418                        if (arr[i] < min) {
419                                min = arr[i];
420                        }
421                }
422
423                return min;
424        }
425
426    
427        /**
428         * Returns the smallest value in the array.
429         * 
430         * @param arr
431         *            array of byte
432         * @return the value
433         */
434        public static byte minValue(final byte[] arr) {
435                if (arr.length < 0)
436                        return 0;
437
438                byte min = arr[0];
439                for (int i = 1; i < arr.length; i++) {
440                        if (arr[i] < min) {
441                                min = arr[i];
442                        }
443                }
444
445                return min;
446        }
447
448    
449        /**
450         * Returns the smallest value in the array.
451         * 
452         * @param arr
453         *            array of short
454         * @return the value
455         */
456        public static short minValue(final short[] arr) {
457                if (arr.length < 0)
458                        return 0;
459
460                short min = arr[0];
461                for (int i = 1; i < arr.length; i++) {
462                        if (arr[i] < min) {
463                                min = arr[i];
464                        }
465                }
466
467                return min;
468        }
469
470    
471        /**
472         * Returns the index to the biggest value in the array.
473         * 
474         * @param arr
475         *            array of double
476         * @return the index
477         */
478        public static int maxIndex(final double[] arr) {
479                double max = Double.MIN_VALUE;
480                int index = 0;
481                for (int i = 0; i < arr.length; i++) {
482                        if (arr[i] > max) {
483                                max = arr[i];
484                                index = i;
485                        }
486                }
487
488                return index;
489        }
490
491    
492        /**
493         * Returns the index to the biggest value in the array.
494         * 
495         * @param arr
496         *            array of float
497         * @return the index
498         */
499        public static int maxIndex(final float[] arr) {
500                float max = Float.MIN_VALUE;
501                int index = 0;
502                for (int i = 0; i < arr.length; i++) {
503                        if (arr[i] > max) {
504                                max = arr[i];
505                                index = i;
506                        }
507                }
508
509                return index;
510        }
511
512    
513        /**
514         * Returns the index to the biggest value in the array.
515         * 
516         * @param arr
517         *            array of int
518         * @return the index
519         */
520        public static int maxIndex(final int[] arr) {
521                int max = Integer.MIN_VALUE;
522                int index = 0;
523                for (int i = 0; i < arr.length; i++) {
524                        if (arr[i] > max) {
525                                max = arr[i];
526                                index = i;
527                        }
528                }
529
530                return index;
531        }
532
533    
534        /**
535         * Returns the index to the biggest value in the array.
536         * 
537         * @param arr
538         *            array of long
539         * @return the index
540         */
541        public static int maxIndex(final long[] arr) {
542                long max = Long.MIN_VALUE;
543                int index = 0;
544                for (int i = 0; i < arr.length; i++) {
545                        if (arr[i] > max) {
546                                max = arr[i];
547                                index = i;
548                        }
549                }
550
551                return index;
552        }
553
554    
555        /**
556         * Returns the index to the biggest value in the array.
557         * 
558         * @param arr
559         *            array of byte
560         * @return the index
561         */
562        public static int maxIndex(final byte[] arr) {
563                byte max = Byte.MIN_VALUE;
564                int index = 0;
565                for (int i = 0; i < arr.length; i++) {
566                        if (arr[i] > max) {
567                                max = arr[i];
568                                index = i;
569                        }
570                }
571
572                return index;
573        }
574
575    
576        /**
577         * Returns the index to the biggest value in the array.
578         * 
579         * @param arr
580         *            array of short
581         * @return the index
582         */
583        public static int maxIndex(final short[] arr) {
584                short max = Short.MIN_VALUE;
585                int index = 0;
586                for (int i = 0; i < arr.length; i++) {
587                        if (arr[i] > max) {
588                                max = arr[i];
589                                index = i;
590                        }
591                }
592
593                return index;
594        }
595
596    
597        /**
598         * Returns the index to the smallest value in the array.
599         * 
600         * @param arr
601         *            array of double
602         * @return the index
603         */
604        public static int minIndex(final double[] arr) {
605                double min = Double.MAX_VALUE;
606                int index = 0;
607                for (int i = 0; i < arr.length; i++) {
608                        if (arr[i] < min) {
609                                min = arr[i];
610                                index = i;
611                        }
612                }
613
614                return index;
615        }
616
617    
618        /**
619         * Returns the index to the smallest value in the array.
620         * 
621         * @param arr
622         *            array of float
623         * @return the index
624         */
625        public static int minIndex(final float[] arr) {
626                float min = Float.MAX_VALUE;
627                int index = 0;
628                for (int i = 0; i < arr.length; i++) {
629                        if (arr[i] < min) {
630                                min = arr[i];
631                                index = i;
632                        }
633                }
634
635                return index;
636        }
637
638    
639        /**
640         * Returns the index to the smallest value in the array.
641         * 
642         * @param arr
643         *            array of int
644         * @return the index
645         */
646        public static int minIndex(final int[] arr) {
647                int min = Integer.MAX_VALUE;
648                int index = 0;
649                for (int i = 0; i < arr.length; i++) {
650                        if (arr[i] < min) {
651                                min = arr[i];
652                                index = i;
653                        }
654                }
655
656                return index;
657        }
658
659    
660        /**
661         * Returns the index to the smallest value in the array.
662         * 
663         * @param arr
664         *            array of long
665         * @return the index
666         */
667        public static int minIndex(final long[] arr) {
668                long min = Long.MAX_VALUE;
669                int index = 0;
670                for (int i = 0; i < arr.length; i++) {
671                        if (arr[i] < min) {
672                                min = arr[i];
673                                index = i;
674                        }
675                }
676
677                return index;
678        }
679
680    
681        /**
682         * Returns the index to the smallest value in the array.
683         * 
684         * @param arr
685         *            array of byte
686         * @return the index
687         */
688        public static int minIndex(final byte[] arr) {
689                byte min = Byte.MAX_VALUE;
690                int index = 0;
691                for (int i = 0; i < arr.length; i++) {
692                        if (arr[i] < min) {
693                                min = arr[i];
694                                index = i;
695                        }
696                }
697
698                return index;
699        }
700
701    
702        /**
703         * Returns the index to the smallest value in the array.
704         * 
705         * @param arr
706         *            array of short
707         * @return the index
708         */
709        public static int minIndex(final short[] arr) {
710                short min = Short.MAX_VALUE;
711                int index = 0;
712                for (int i = 0; i < arr.length; i++) {
713                        if (arr[i] < min) {
714                                min = arr[i];
715                                index = i;
716                        }
717                }
718
719                return index;
720        }
721
722    
723        /**
724         * Element-wise summation of two arrays, output writes over first array
725         * 
726         * @param a1
727         *            first array
728         * @param a2
729         *            second array
730         * @return the first array
731         */
732        public static double[][] sum(final double[][] a1, final double[][] a2) {
733                for (int j = 0; j < a1.length; j++) {
734                        sum(a1[j], a2[j]);
735                }
736                return a1;
737        }
738
739        /**
740         * Element-wise summation of two arrays, output writes over first array
741         * 
742         * @param a1
743         *            first array
744         * @param a2
745         *            second array
746         * @return the first array
747         */
748        public static double[] sum(final double[] a1, final double[] a2) {
749                for (int j = 0; j < a1.length; j++) {
750                        a1[j] += a2[j];
751                }
752                return a1;
753        }
754
755    
756        /**
757         * Element-wise summation of two arrays, output writes over first array
758         * 
759         * @param a1
760         *            first array
761         * @param a2
762         *            second array
763         * @return the first array
764         */
765        public static float[][] sum(final float[][] a1, final float[][] a2) {
766                for (int j = 0; j < a1.length; j++) {
767                        sum(a1[j], a2[j]);
768                }
769                return a1;
770        }
771
772        /**
773         * Element-wise summation of two arrays, output writes over first array
774         * 
775         * @param a1
776         *            first array
777         * @param a2
778         *            second array
779         * @return the first array
780         */
781        public static float[] sum(final float[] a1, final float[] a2) {
782                for (int j = 0; j < a1.length; j++) {
783                        a1[j] += a2[j];
784                }
785                return a1;
786        }
787
788    
789        /**
790         * Element-wise summation of two arrays, output writes over first array
791         * 
792         * @param a1
793         *            first array
794         * @param a2
795         *            second array
796         * @return the first array
797         */
798        public static int[][] sum(final int[][] a1, final int[][] a2) {
799                for (int j = 0; j < a1.length; j++) {
800                        sum(a1[j], a2[j]);
801                }
802                return a1;
803        }
804
805        /**
806         * Element-wise summation of two arrays, output writes over first array
807         * 
808         * @param a1
809         *            first array
810         * @param a2
811         *            second array
812         * @return the first array
813         */
814        public static int[] sum(final int[] a1, final int[] a2) {
815                for (int j = 0; j < a1.length; j++) {
816                        a1[j] += a2[j];
817                }
818                return a1;
819        }
820
821    
822        /**
823         * Element-wise summation of two arrays, output writes over first array
824         * 
825         * @param a1
826         *            first array
827         * @param a2
828         *            second array
829         * @return the first array
830         */
831        public static long[][] sum(final long[][] a1, final long[][] a2) {
832                for (int j = 0; j < a1.length; j++) {
833                        sum(a1[j], a2[j]);
834                }
835                return a1;
836        }
837
838        /**
839         * Element-wise summation of two arrays, output writes over first array
840         * 
841         * @param a1
842         *            first array
843         * @param a2
844         *            second array
845         * @return the first array
846         */
847        public static long[] sum(final long[] a1, final long[] a2) {
848                for (int j = 0; j < a1.length; j++) {
849                        a1[j] += a2[j];
850                }
851                return a1;
852        }
853
854    
855        /**
856         * Element-wise summation of two arrays, output writes over first array
857         * 
858         * @param a1
859         *            first array
860         * @param a2
861         *            second array
862         * @return the first array
863         */
864        public static byte[][] sum(final byte[][] a1, final byte[][] a2) {
865                for (int j = 0; j < a1.length; j++) {
866                        sum(a1[j], a2[j]);
867                }
868                return a1;
869        }
870
871        /**
872         * Element-wise summation of two arrays, output writes over first array
873         * 
874         * @param a1
875         *            first array
876         * @param a2
877         *            second array
878         * @return the first array
879         */
880        public static byte[] sum(final byte[] a1, final byte[] a2) {
881                for (int j = 0; j < a1.length; j++) {
882                        a1[j] += a2[j];
883                }
884                return a1;
885        }
886
887    
888        /**
889         * Element-wise summation of two arrays, output writes over first array
890         * 
891         * @param a1
892         *            first array
893         * @param a2
894         *            second array
895         * @return the first array
896         */
897        public static short[][] sum(final short[][] a1, final short[][] a2) {
898                for (int j = 0; j < a1.length; j++) {
899                        sum(a1[j], a2[j]);
900                }
901                return a1;
902        }
903
904        /**
905         * Element-wise summation of two arrays, output writes over first array
906         * 
907         * @param a1
908         *            first array
909         * @param a2
910         *            second array
911         * @return the first array
912         */
913        public static short[] sum(final short[] a1, final short[] a2) {
914                for (int j = 0; j < a1.length; j++) {
915                        a1[j] += a2[j];
916                }
917                return a1;
918        }
919
920    
921        /**
922         * Element-wise subtraction of two arrays. Second array is subtracted from
923         * first, overwriting the first array
924         * 
925         * @param a1
926         *            first array
927         * @param a2
928         *            second array
929         * @return the first array
930         */
931        public static double[][] subtract(final double[][] a1, final double[][] a2) {
932                for (int j = 0; j < a1.length; j++) {
933                        subtract(a1[j], a2[j]);
934                }
935                return a1;
936        }
937
938        /**
939         * Element-wise subtraction of two arrays. Second array is subtracted from
940         * first, overwriting the first array
941         * 
942         * @param a1
943         *            first array
944         * @param a2
945         *            second array
946         * @return the first array
947         */
948        public static double[] subtract(final double[] a1, final double[] a2) {
949                for (int j = 0; j < a1.length; j++) {
950                        a1[j] -= a2[j];
951                }
952                return a1;
953        }
954
955        
956        /**
957         * Element-wise subtraction of two arrays. Second array is subtracted from
958         * first, overwriting the first array
959         * 
960         * @param a1
961         *            first array
962         * @param a2
963         *            second array
964         * @return the first array
965         */
966        public static float[][] subtract(final float[][] a1, final float[][] a2) {
967                for (int j = 0; j < a1.length; j++) {
968                        subtract(a1[j], a2[j]);
969                }
970                return a1;
971        }
972
973        /**
974         * Element-wise subtraction of two arrays. Second array is subtracted from
975         * first, overwriting the first array
976         * 
977         * @param a1
978         *            first array
979         * @param a2
980         *            second array
981         * @return the first array
982         */
983        public static float[] subtract(final float[] a1, final float[] a2) {
984                for (int j = 0; j < a1.length; j++) {
985                        a1[j] -= a2[j];
986                }
987                return a1;
988        }
989
990        
991        /**
992         * Element-wise subtraction of two arrays. Second array is subtracted from
993         * first, overwriting the first array
994         * 
995         * @param a1
996         *            first array
997         * @param a2
998         *            second array
999         * @return the first array
1000         */
1001        public static int[][] subtract(final int[][] a1, final int[][] a2) {
1002                for (int j = 0; j < a1.length; j++) {
1003                        subtract(a1[j], a2[j]);
1004                }
1005                return a1;
1006        }
1007
1008        /**
1009         * Element-wise subtraction of two arrays. Second array is subtracted from
1010         * first, overwriting the first array
1011         * 
1012         * @param a1
1013         *            first array
1014         * @param a2
1015         *            second array
1016         * @return the first array
1017         */
1018        public static int[] subtract(final int[] a1, final int[] a2) {
1019                for (int j = 0; j < a1.length; j++) {
1020                        a1[j] -= a2[j];
1021                }
1022                return a1;
1023        }
1024
1025        
1026        /**
1027         * Element-wise subtraction of two arrays. Second array is subtracted from
1028         * first, overwriting the first array
1029         * 
1030         * @param a1
1031         *            first array
1032         * @param a2
1033         *            second array
1034         * @return the first array
1035         */
1036        public static long[][] subtract(final long[][] a1, final long[][] a2) {
1037                for (int j = 0; j < a1.length; j++) {
1038                        subtract(a1[j], a2[j]);
1039                }
1040                return a1;
1041        }
1042
1043        /**
1044         * Element-wise subtraction of two arrays. Second array is subtracted from
1045         * first, overwriting the first array
1046         * 
1047         * @param a1
1048         *            first array
1049         * @param a2
1050         *            second array
1051         * @return the first array
1052         */
1053        public static long[] subtract(final long[] a1, final long[] a2) {
1054                for (int j = 0; j < a1.length; j++) {
1055                        a1[j] -= a2[j];
1056                }
1057                return a1;
1058        }
1059
1060        
1061        /**
1062         * Element-wise subtraction of two arrays. Second array is subtracted from
1063         * first, overwriting the first array
1064         * 
1065         * @param a1
1066         *            first array
1067         * @param a2
1068         *            second array
1069         * @return the first array
1070         */
1071        public static byte[][] subtract(final byte[][] a1, final byte[][] a2) {
1072                for (int j = 0; j < a1.length; j++) {
1073                        subtract(a1[j], a2[j]);
1074                }
1075                return a1;
1076        }
1077
1078        /**
1079         * Element-wise subtraction of two arrays. Second array is subtracted from
1080         * first, overwriting the first array
1081         * 
1082         * @param a1
1083         *            first array
1084         * @param a2
1085         *            second array
1086         * @return the first array
1087         */
1088        public static byte[] subtract(final byte[] a1, final byte[] a2) {
1089                for (int j = 0; j < a1.length; j++) {
1090                        a1[j] -= a2[j];
1091                }
1092                return a1;
1093        }
1094
1095        
1096        /**
1097         * Element-wise subtraction of two arrays. Second array is subtracted from
1098         * first, overwriting the first array
1099         * 
1100         * @param a1
1101         *            first array
1102         * @param a2
1103         *            second array
1104         * @return the first array
1105         */
1106        public static short[][] subtract(final short[][] a1, final short[][] a2) {
1107                for (int j = 0; j < a1.length; j++) {
1108                        subtract(a1[j], a2[j]);
1109                }
1110                return a1;
1111        }
1112
1113        /**
1114         * Element-wise subtraction of two arrays. Second array is subtracted from
1115         * first, overwriting the first array
1116         * 
1117         * @param a1
1118         *            first array
1119         * @param a2
1120         *            second array
1121         * @return the first array
1122         */
1123        public static short[] subtract(final short[] a1, final short[] a2) {
1124                for (int j = 0; j < a1.length; j++) {
1125                        a1[j] -= a2[j];
1126                }
1127                return a1;
1128        }
1129
1130        
1131        /**
1132         * Subtracts <code>s</code> from all elements in <code>a1</code> overwriting
1133         * the array. This is syntactic sugar for <code>add( a1, -s )</code>.
1134         * 
1135         * @param a1
1136         *            The array
1137         * @param s
1138         *            The scalar
1139         * @return the array
1140         */
1141        public static double[] subtract(final double[] a1, final double s)
1142        {
1143                return add(a1, (double)(-s));
1144        }
1145
1146    
1147        /**
1148         * Subtracts <code>s</code> from all elements in <code>a1</code> overwriting
1149         * the array. This is syntactic sugar for <code>add( a1, -s )</code>.
1150         * 
1151         * @param a1
1152         *            The array
1153         * @param s
1154         *            The scalar
1155         * @return the array
1156         */
1157        public static float[] subtract(final float[] a1, final float s)
1158        {
1159                return add(a1, (float)(-s));
1160        }
1161
1162    
1163        /**
1164         * Subtracts <code>s</code> from all elements in <code>a1</code> overwriting
1165         * the array. This is syntactic sugar for <code>add( a1, -s )</code>.
1166         * 
1167         * @param a1
1168         *            The array
1169         * @param s
1170         *            The scalar
1171         * @return the array
1172         */
1173        public static int[] subtract(final int[] a1, final int s)
1174        {
1175                return add(a1, (int)(-s));
1176        }
1177
1178    
1179        /**
1180         * Subtracts <code>s</code> from all elements in <code>a1</code> overwriting
1181         * the array. This is syntactic sugar for <code>add( a1, -s )</code>.
1182         * 
1183         * @param a1
1184         *            The array
1185         * @param s
1186         *            The scalar
1187         * @return the array
1188         */
1189        public static long[] subtract(final long[] a1, final long s)
1190        {
1191                return add(a1, (long)(-s));
1192        }
1193
1194    
1195        /**
1196         * Subtracts <code>s</code> from all elements in <code>a1</code> overwriting
1197         * the array. This is syntactic sugar for <code>add( a1, -s )</code>.
1198         * 
1199         * @param a1
1200         *            The array
1201         * @param s
1202         *            The scalar
1203         * @return the array
1204         */
1205        public static byte[] subtract(final byte[] a1, final byte s)
1206        {
1207                return add(a1, (byte)(-s));
1208        }
1209
1210    
1211        /**
1212         * Subtracts <code>s</code> from all elements in <code>a1</code> overwriting
1213         * the array. This is syntactic sugar for <code>add( a1, -s )</code>.
1214         * 
1215         * @param a1
1216         *            The array
1217         * @param s
1218         *            The scalar
1219         * @return the array
1220         */
1221        public static short[] subtract(final short[] a1, final short s)
1222        {
1223                return add(a1, (short)(-s));
1224        }
1225
1226    
1227        /**
1228         * Add a constant to all elements and return the input
1229         * 
1230         * @param ds
1231         *            input array
1232         * @param x
1233         *            constant to add
1234         * @return the input array
1235         */
1236        public static double[] add(final double[] ds, final double x) {
1237                for (int i = 0; i < ds.length; i++) {
1238                        ds[i] += x;
1239                }
1240                return ds;
1241        }
1242
1243    
1244        /**
1245         * Add a constant to all elements and return the input
1246         * 
1247         * @param ds
1248         *            input array
1249         * @param x
1250         *            constant to add
1251         * @return the input array
1252         */
1253        public static float[] add(final float[] ds, final float x) {
1254                for (int i = 0; i < ds.length; i++) {
1255                        ds[i] += x;
1256                }
1257                return ds;
1258        }
1259
1260    
1261        /**
1262         * Add a constant to all elements and return the input
1263         * 
1264         * @param ds
1265         *            input array
1266         * @param x
1267         *            constant to add
1268         * @return the input array
1269         */
1270        public static int[] add(final int[] ds, final int x) {
1271                for (int i = 0; i < ds.length; i++) {
1272                        ds[i] += x;
1273                }
1274                return ds;
1275        }
1276
1277    
1278        /**
1279         * Add a constant to all elements and return the input
1280         * 
1281         * @param ds
1282         *            input array
1283         * @param x
1284         *            constant to add
1285         * @return the input array
1286         */
1287        public static long[] add(final long[] ds, final long x) {
1288                for (int i = 0; i < ds.length; i++) {
1289                        ds[i] += x;
1290                }
1291                return ds;
1292        }
1293
1294    
1295        /**
1296         * Add a constant to all elements and return the input
1297         * 
1298         * @param ds
1299         *            input array
1300         * @param x
1301         *            constant to add
1302         * @return the input array
1303         */
1304        public static byte[] add(final byte[] ds, final byte x) {
1305                for (int i = 0; i < ds.length; i++) {
1306                        ds[i] += x;
1307                }
1308                return ds;
1309        }
1310
1311    
1312        /**
1313         * Add a constant to all elements and return the input
1314         * 
1315         * @param ds
1316         *            input array
1317         * @param x
1318         *            constant to add
1319         * @return the input array
1320         */
1321        public static short[] add(final short[] ds, final short x) {
1322                for (int i = 0; i < ds.length; i++) {
1323                        ds[i] += x;
1324                }
1325                return ds;
1326        }
1327
1328    
1329    /**
1330         * Multiply by a constant all elements and return the input
1331         * 
1332         * @param ds
1333         *            input array
1334         * @param x
1335         *            constant to multiply by
1336         * @return input
1337         */
1338        public static double[] multiply(final double[] ds, final double x) {
1339                for (int i = 0; i < ds.length; i++) {
1340                        ds[i] *= x;
1341                }
1342                return ds;
1343        }
1344        
1345        /**
1346         * Multiply by a constant all elements and return the input
1347         * 
1348         * @param ds
1349         *            input array
1350         * @param x
1351         *            constant to multiply by
1352         * @return input
1353         */
1354        public static double[][] multiply(final double[][] ds, final double x) {
1355                for (int i = 0; i < ds.length; i++) {
1356                        multiply(ds[i], x);
1357                }
1358                return ds;
1359        }
1360
1361    
1362    /**
1363         * Multiply by a constant all elements and return the input
1364         * 
1365         * @param ds
1366         *            input array
1367         * @param x
1368         *            constant to multiply by
1369         * @return input
1370         */
1371        public static float[] multiply(final float[] ds, final float x) {
1372                for (int i = 0; i < ds.length; i++) {
1373                        ds[i] *= x;
1374                }
1375                return ds;
1376        }
1377        
1378        /**
1379         * Multiply by a constant all elements and return the input
1380         * 
1381         * @param ds
1382         *            input array
1383         * @param x
1384         *            constant to multiply by
1385         * @return input
1386         */
1387        public static float[][] multiply(final float[][] ds, final float x) {
1388                for (int i = 0; i < ds.length; i++) {
1389                        multiply(ds[i], x);
1390                }
1391                return ds;
1392        }
1393
1394    
1395    /**
1396         * Multiply by a constant all elements and return the input
1397         * 
1398         * @param ds
1399         *            input array
1400         * @param x
1401         *            constant to multiply by
1402         * @return input
1403         */
1404        public static int[] multiply(final int[] ds, final int x) {
1405                for (int i = 0; i < ds.length; i++) {
1406                        ds[i] *= x;
1407                }
1408                return ds;
1409        }
1410        
1411        /**
1412         * Multiply by a constant all elements and return the input
1413         * 
1414         * @param ds
1415         *            input array
1416         * @param x
1417         *            constant to multiply by
1418         * @return input
1419         */
1420        public static int[][] multiply(final int[][] ds, final int x) {
1421                for (int i = 0; i < ds.length; i++) {
1422                        multiply(ds[i], x);
1423                }
1424                return ds;
1425        }
1426
1427    
1428    /**
1429         * Multiply by a constant all elements and return the input
1430         * 
1431         * @param ds
1432         *            input array
1433         * @param x
1434         *            constant to multiply by
1435         * @return input
1436         */
1437        public static long[] multiply(final long[] ds, final long x) {
1438                for (int i = 0; i < ds.length; i++) {
1439                        ds[i] *= x;
1440                }
1441                return ds;
1442        }
1443        
1444        /**
1445         * Multiply by a constant all elements and return the input
1446         * 
1447         * @param ds
1448         *            input array
1449         * @param x
1450         *            constant to multiply by
1451         * @return input
1452         */
1453        public static long[][] multiply(final long[][] ds, final long x) {
1454                for (int i = 0; i < ds.length; i++) {
1455                        multiply(ds[i], x);
1456                }
1457                return ds;
1458        }
1459
1460    
1461    /**
1462         * Multiply by a constant all elements and return the input
1463         * 
1464         * @param ds
1465         *            input array
1466         * @param x
1467         *            constant to multiply by
1468         * @return input
1469         */
1470        public static byte[] multiply(final byte[] ds, final byte x) {
1471                for (int i = 0; i < ds.length; i++) {
1472                        ds[i] *= x;
1473                }
1474                return ds;
1475        }
1476        
1477        /**
1478         * Multiply by a constant all elements and return the input
1479         * 
1480         * @param ds
1481         *            input array
1482         * @param x
1483         *            constant to multiply by
1484         * @return input
1485         */
1486        public static byte[][] multiply(final byte[][] ds, final byte x) {
1487                for (int i = 0; i < ds.length; i++) {
1488                        multiply(ds[i], x);
1489                }
1490                return ds;
1491        }
1492
1493    
1494    /**
1495         * Multiply by a constant all elements and return the input
1496         * 
1497         * @param ds
1498         *            input array
1499         * @param x
1500         *            constant to multiply by
1501         * @return input
1502         */
1503        public static short[] multiply(final short[] ds, final short x) {
1504                for (int i = 0; i < ds.length; i++) {
1505                        ds[i] *= x;
1506                }
1507                return ds;
1508        }
1509        
1510        /**
1511         * Multiply by a constant all elements and return the input
1512         * 
1513         * @param ds
1514         *            input array
1515         * @param x
1516         *            constant to multiply by
1517         * @return input
1518         */
1519        public static short[][] multiply(final short[][] ds, final short x) {
1520                for (int i = 0; i < ds.length; i++) {
1521                        multiply(ds[i], x);
1522                }
1523                return ds;
1524        }
1525
1526    
1527        /**
1528         * Element-wise multiplication, overwriting a1
1529         * 
1530         * @param a1
1531         *            The first array
1532         * @param a2
1533         *            the second array
1534         * @return The first array
1535         */
1536        public static double[] multiply(final double[] a1, final double[] a2)
1537        {
1538                for (int j = 0; j < a1.length; j++)
1539                        a1[j] *= a2[j];
1540                return a1;
1541        }
1542
1543        /**
1544         * Element-wise multiplication, overwriting a1.
1545         * 
1546         * @param a1
1547         *            First array
1548         * @param a2
1549         *            second array
1550         * @return Updated first array
1551         */
1552        public static double[][] multiply(final double[][] a1, final double[][] a2)
1553        {
1554                for (int j = 0; j < a1.length; j++)
1555                        multiply(a1[j], a2[j]);
1556                return a1;
1557        }
1558
1559    
1560        /**
1561         * Element-wise multiplication, overwriting a1
1562         * 
1563         * @param a1
1564         *            The first array
1565         * @param a2
1566         *            the second array
1567         * @return The first array
1568         */
1569        public static float[] multiply(final float[] a1, final float[] a2)
1570        {
1571                for (int j = 0; j < a1.length; j++)
1572                        a1[j] *= a2[j];
1573                return a1;
1574        }
1575
1576        /**
1577         * Element-wise multiplication, overwriting a1.
1578         * 
1579         * @param a1
1580         *            First array
1581         * @param a2
1582         *            second array
1583         * @return Updated first array
1584         */
1585        public static float[][] multiply(final float[][] a1, final float[][] a2)
1586        {
1587                for (int j = 0; j < a1.length; j++)
1588                        multiply(a1[j], a2[j]);
1589                return a1;
1590        }
1591
1592    
1593        /**
1594         * Element-wise multiplication, overwriting a1
1595         * 
1596         * @param a1
1597         *            The first array
1598         * @param a2
1599         *            the second array
1600         * @return The first array
1601         */
1602        public static int[] multiply(final int[] a1, final int[] a2)
1603        {
1604                for (int j = 0; j < a1.length; j++)
1605                        a1[j] *= a2[j];
1606                return a1;
1607        }
1608
1609        /**
1610         * Element-wise multiplication, overwriting a1.
1611         * 
1612         * @param a1
1613         *            First array
1614         * @param a2
1615         *            second array
1616         * @return Updated first array
1617         */
1618        public static int[][] multiply(final int[][] a1, final int[][] a2)
1619        {
1620                for (int j = 0; j < a1.length; j++)
1621                        multiply(a1[j], a2[j]);
1622                return a1;
1623        }
1624
1625    
1626        /**
1627         * Element-wise multiplication, overwriting a1
1628         * 
1629         * @param a1
1630         *            The first array
1631         * @param a2
1632         *            the second array
1633         * @return The first array
1634         */
1635        public static long[] multiply(final long[] a1, final long[] a2)
1636        {
1637                for (int j = 0; j < a1.length; j++)
1638                        a1[j] *= a2[j];
1639                return a1;
1640        }
1641
1642        /**
1643         * Element-wise multiplication, overwriting a1.
1644         * 
1645         * @param a1
1646         *            First array
1647         * @param a2
1648         *            second array
1649         * @return Updated first array
1650         */
1651        public static long[][] multiply(final long[][] a1, final long[][] a2)
1652        {
1653                for (int j = 0; j < a1.length; j++)
1654                        multiply(a1[j], a2[j]);
1655                return a1;
1656        }
1657
1658    
1659        /**
1660         * Element-wise multiplication, overwriting a1
1661         * 
1662         * @param a1
1663         *            The first array
1664         * @param a2
1665         *            the second array
1666         * @return The first array
1667         */
1668        public static byte[] multiply(final byte[] a1, final byte[] a2)
1669        {
1670                for (int j = 0; j < a1.length; j++)
1671                        a1[j] *= a2[j];
1672                return a1;
1673        }
1674
1675        /**
1676         * Element-wise multiplication, overwriting a1.
1677         * 
1678         * @param a1
1679         *            First array
1680         * @param a2
1681         *            second array
1682         * @return Updated first array
1683         */
1684        public static byte[][] multiply(final byte[][] a1, final byte[][] a2)
1685        {
1686                for (int j = 0; j < a1.length; j++)
1687                        multiply(a1[j], a2[j]);
1688                return a1;
1689        }
1690
1691    
1692        /**
1693         * Element-wise multiplication, overwriting a1
1694         * 
1695         * @param a1
1696         *            The first array
1697         * @param a2
1698         *            the second array
1699         * @return The first array
1700         */
1701        public static short[] multiply(final short[] a1, final short[] a2)
1702        {
1703                for (int j = 0; j < a1.length; j++)
1704                        a1[j] *= a2[j];
1705                return a1;
1706        }
1707
1708        /**
1709         * Element-wise multiplication, overwriting a1.
1710         * 
1711         * @param a1
1712         *            First array
1713         * @param a2
1714         *            second array
1715         * @return Updated first array
1716         */
1717        public static short[][] multiply(final short[][] a1, final short[][] a2)
1718        {
1719                for (int j = 0; j < a1.length; j++)
1720                        multiply(a1[j], a2[j]);
1721                return a1;
1722        }
1723
1724    
1725        /**
1726         * Divide by a constant, all elements and return the input
1727         * 
1728         * @param fs
1729         *            The input array
1730         * @param x
1731         *            the constant to divide by
1732         * @return THe input
1733         */
1734        public static double[] divide(final double[] fs, final double x)
1735        {
1736                for (int i = 0; i < fs.length; i++)
1737                        fs[i] /= x;
1738                return fs;
1739        }
1740
1741    
1742        /**
1743         * Divide by a constant, all elements and return the input
1744         * 
1745         * @param fs
1746         *            The input array
1747         * @param x
1748         *            the constant to divide by
1749         * @return THe input
1750         */
1751        public static float[] divide(final float[] fs, final float x)
1752        {
1753                for (int i = 0; i < fs.length; i++)
1754                        fs[i] /= x;
1755                return fs;
1756        }
1757
1758    
1759        /**
1760         * Divide by a constant, all elements and return the input
1761         * 
1762         * @param fs
1763         *            The input array
1764         * @param x
1765         *            the constant to divide by
1766         * @return THe input
1767         */
1768        public static int[] divide(final int[] fs, final int x)
1769        {
1770                for (int i = 0; i < fs.length; i++)
1771                        fs[i] /= x;
1772                return fs;
1773        }
1774
1775    
1776        /**
1777         * Divide by a constant, all elements and return the input
1778         * 
1779         * @param fs
1780         *            The input array
1781         * @param x
1782         *            the constant to divide by
1783         * @return THe input
1784         */
1785        public static long[] divide(final long[] fs, final long x)
1786        {
1787                for (int i = 0; i < fs.length; i++)
1788                        fs[i] /= x;
1789                return fs;
1790        }
1791
1792    
1793        /**
1794         * Divide by a constant, all elements and return the input
1795         * 
1796         * @param fs
1797         *            The input array
1798         * @param x
1799         *            the constant to divide by
1800         * @return THe input
1801         */
1802        public static byte[] divide(final byte[] fs, final byte x)
1803        {
1804                for (int i = 0; i < fs.length; i++)
1805                        fs[i] /= x;
1806                return fs;
1807        }
1808
1809    
1810        /**
1811         * Divide by a constant, all elements and return the input
1812         * 
1813         * @param fs
1814         *            The input array
1815         * @param x
1816         *            the constant to divide by
1817         * @return THe input
1818         */
1819        public static short[] divide(final short[] fs, final short x)
1820        {
1821                for (int i = 0; i < fs.length; i++)
1822                        fs[i] /= x;
1823                return fs;
1824        }
1825
1826    
1827        /**
1828         * Normalise length of array to 1.0. Writes over array. If the array is all
1829         * zeros, it will be unchanged.
1830         * 
1831         * @param array
1832         *            the array
1833         * @return the array
1834         */
1835        public static float[] normalise(final float[] array) {
1836                float sumsq = 0.0f;
1837                for (int i = 0; i < array.length; i++)
1838                        sumsq += array[i] * array[i];
1839
1840                if (sumsq == 0)
1841                        return array;
1842
1843                final float weight = 1.0f / (float) Math.sqrt(sumsq);
1844                for (int i = 0; i < array.length; i++)
1845                        array[i] *= weight;
1846                return array;
1847        }
1848
1849        /**
1850         * Normalise length of array to 1.0. Writes over array. If the array is all
1851         * zeros, it will be unchanged.
1852         * 
1853         * @param array
1854         *            the array
1855         * @return the array
1856         */
1857        public static double[] normalise(final double[] array) {
1858                double sumsq = 0.0f;
1859                for (int i = 0; i < array.length; i++)
1860                        sumsq += array[i] * array[i];
1861
1862                if (sumsq == 0)
1863                        return array;
1864
1865                final double weight = 1.0f / Math.sqrt(sumsq);
1866                for (int i = 0; i < array.length; i++)
1867                        array[i] *= weight;
1868                return array;
1869        }
1870
1871    
1872        /**
1873         * Reverse the elements in the input and return the input.
1874         * 
1875         * @param ds
1876         *            input array
1877         * @return input
1878         */
1879        public static double[] reverse(final double[] ds) {
1880                final int len = ds.length;
1881                final int hlen = len / 2;
1882
1883                for (int i = 0; i < hlen; i++) {
1884                        final double tmp = ds[i];
1885                        ds[i] = ds[len - i - 1];
1886                        ds[len - i - 1] = tmp;
1887                }
1888                return ds;
1889        }
1890
1891    
1892        /**
1893         * Reverse the elements in the input and return the input.
1894         * 
1895         * @param ds
1896         *            input array
1897         * @return input
1898         */
1899        public static float[] reverse(final float[] ds) {
1900                final int len = ds.length;
1901                final int hlen = len / 2;
1902
1903                for (int i = 0; i < hlen; i++) {
1904                        final float tmp = ds[i];
1905                        ds[i] = ds[len - i - 1];
1906                        ds[len - i - 1] = tmp;
1907                }
1908                return ds;
1909        }
1910
1911    
1912        /**
1913         * Reverse the elements in the input and return the input.
1914         * 
1915         * @param ds
1916         *            input array
1917         * @return input
1918         */
1919        public static int[] reverse(final int[] ds) {
1920                final int len = ds.length;
1921                final int hlen = len / 2;
1922
1923                for (int i = 0; i < hlen; i++) {
1924                        final int tmp = ds[i];
1925                        ds[i] = ds[len - i - 1];
1926                        ds[len - i - 1] = tmp;
1927                }
1928                return ds;
1929        }
1930
1931    
1932        /**
1933         * Reverse the elements in the input and return the input.
1934         * 
1935         * @param ds
1936         *            input array
1937         * @return input
1938         */
1939        public static long[] reverse(final long[] ds) {
1940                final int len = ds.length;
1941                final int hlen = len / 2;
1942
1943                for (int i = 0; i < hlen; i++) {
1944                        final long tmp = ds[i];
1945                        ds[i] = ds[len - i - 1];
1946                        ds[len - i - 1] = tmp;
1947                }
1948                return ds;
1949        }
1950
1951    
1952        /**
1953         * Reverse the elements in the input and return the input.
1954         * 
1955         * @param ds
1956         *            input array
1957         * @return input
1958         */
1959        public static byte[] reverse(final byte[] ds) {
1960                final int len = ds.length;
1961                final int hlen = len / 2;
1962
1963                for (int i = 0; i < hlen; i++) {
1964                        final byte tmp = ds[i];
1965                        ds[i] = ds[len - i - 1];
1966                        ds[len - i - 1] = tmp;
1967                }
1968                return ds;
1969        }
1970
1971    
1972        /**
1973         * Reverse the elements in the input and return the input.
1974         * 
1975         * @param ds
1976         *            input array
1977         * @return input
1978         */
1979        public static short[] reverse(final short[] ds) {
1980                final int len = ds.length;
1981                final int hlen = len / 2;
1982
1983                for (int i = 0; i < hlen; i++) {
1984                        final short tmp = ds[i];
1985                        ds[i] = ds[len - i - 1];
1986                        ds[len - i - 1] = tmp;
1987                }
1988                return ds;
1989        }
1990
1991    
1992        /**
1993         * Convert a double array to a double array.
1994         * 
1995         * @param array
1996         *            array of doubles to convert
1997         * @return array of doubles
1998         */
1999        public static double[] convertToDouble(final double[] array) {
2000                final double[] darr = new double[array.length];
2001
2002                for (int i = 0; i < array.length; i++) {
2003                        darr[i] = array[i];
2004                }
2005                return darr;
2006        }
2007
2008        /**
2009         * Convert a double array to a double array.
2010         * 
2011         * @param array
2012         *            array of doubles to convert
2013         * @return array of doubles
2014         */
2015        public static double[][] convertToDouble(final double[][] array)
2016        {
2017                final double[][] darr = new double[array.length][];
2018                for (int i = 0; i < array.length; i++)
2019                        darr[i] = convertToDouble(array[i]);
2020                return darr;
2021        }
2022
2023    
2024        /**
2025         * Convert a float array to a double array.
2026         * 
2027         * @param array
2028         *            array of floats to convert
2029         * @return array of doubles
2030         */
2031        public static double[] convertToDouble(final float[] array) {
2032                final double[] darr = new double[array.length];
2033
2034                for (int i = 0; i < array.length; i++) {
2035                        darr[i] = array[i];
2036                }
2037                return darr;
2038        }
2039
2040        /**
2041         * Convert a float array to a double array.
2042         * 
2043         * @param array
2044         *            array of floats to convert
2045         * @return array of doubles
2046         */
2047        public static double[][] convertToDouble(final float[][] array)
2048        {
2049                final double[][] darr = new double[array.length][];
2050                for (int i = 0; i < array.length; i++)
2051                        darr[i] = convertToDouble(array[i]);
2052                return darr;
2053        }
2054
2055    
2056        /**
2057         * Convert a int array to a double array.
2058         * 
2059         * @param array
2060         *            array of ints to convert
2061         * @return array of doubles
2062         */
2063        public static double[] convertToDouble(final int[] array) {
2064                final double[] darr = new double[array.length];
2065
2066                for (int i = 0; i < array.length; i++) {
2067                        darr[i] = array[i];
2068                }
2069                return darr;
2070        }
2071
2072        /**
2073         * Convert a int array to a double array.
2074         * 
2075         * @param array
2076         *            array of ints to convert
2077         * @return array of doubles
2078         */
2079        public static double[][] convertToDouble(final int[][] array)
2080        {
2081                final double[][] darr = new double[array.length][];
2082                for (int i = 0; i < array.length; i++)
2083                        darr[i] = convertToDouble(array[i]);
2084                return darr;
2085        }
2086
2087    
2088        /**
2089         * Convert a long array to a double array.
2090         * 
2091         * @param array
2092         *            array of longs to convert
2093         * @return array of doubles
2094         */
2095        public static double[] convertToDouble(final long[] array) {
2096                final double[] darr = new double[array.length];
2097
2098                for (int i = 0; i < array.length; i++) {
2099                        darr[i] = array[i];
2100                }
2101                return darr;
2102        }
2103
2104        /**
2105         * Convert a long array to a double array.
2106         * 
2107         * @param array
2108         *            array of longs to convert
2109         * @return array of doubles
2110         */
2111        public static double[][] convertToDouble(final long[][] array)
2112        {
2113                final double[][] darr = new double[array.length][];
2114                for (int i = 0; i < array.length; i++)
2115                        darr[i] = convertToDouble(array[i]);
2116                return darr;
2117        }
2118
2119    
2120        /**
2121         * Convert a byte array to a double array.
2122         * 
2123         * @param array
2124         *            array of bytes to convert
2125         * @return array of doubles
2126         */
2127        public static double[] convertToDouble(final byte[] array) {
2128                final double[] darr = new double[array.length];
2129
2130                for (int i = 0; i < array.length; i++) {
2131                        darr[i] = array[i];
2132                }
2133                return darr;
2134        }
2135
2136        /**
2137         * Convert a byte array to a double array.
2138         * 
2139         * @param array
2140         *            array of bytes to convert
2141         * @return array of doubles
2142         */
2143        public static double[][] convertToDouble(final byte[][] array)
2144        {
2145                final double[][] darr = new double[array.length][];
2146                for (int i = 0; i < array.length; i++)
2147                        darr[i] = convertToDouble(array[i]);
2148                return darr;
2149        }
2150
2151    
2152        /**
2153         * Convert a short array to a double array.
2154         * 
2155         * @param array
2156         *            array of shorts to convert
2157         * @return array of doubles
2158         */
2159        public static double[] convertToDouble(final short[] array) {
2160                final double[] darr = new double[array.length];
2161
2162                for (int i = 0; i < array.length; i++) {
2163                        darr[i] = array[i];
2164                }
2165                return darr;
2166        }
2167
2168        /**
2169         * Convert a short array to a double array.
2170         * 
2171         * @param array
2172         *            array of shorts to convert
2173         * @return array of doubles
2174         */
2175        public static double[][] convertToDouble(final short[][] array)
2176        {
2177                final double[][] darr = new double[array.length][];
2178                for (int i = 0; i < array.length; i++)
2179                        darr[i] = convertToDouble(array[i]);
2180                return darr;
2181        }
2182
2183    
2184        /**
2185         * Convert a double array to a float array.
2186         * 
2187         * @param array
2188         *            array of doubles to convert
2189         * @return array of floats
2190         */
2191        public static float[] convertToFloat(final double[] array) {
2192                final float[] farr = new float[array.length];
2193
2194                for (int i = 0; i < array.length; i++) {
2195                        farr[i] = (float) array[i];
2196                }
2197                return farr;
2198        }
2199
2200    /**
2201         * Convert a double array to a float array.
2202         * 
2203         * @param array
2204         *            array of doubles to convert
2205         * @return array of doubles
2206         */
2207        public static float[][] convertToFloat(final double[][] array)
2208        {
2209                final float[][] darr = new float[array.length][];
2210                for (int i = 0; i < array.length; i++)
2211                        darr[i] = convertToFloat(array[i]);
2212                return darr;
2213        }
2214
2215    
2216        /**
2217         * Convert a float array to a float array.
2218         * 
2219         * @param array
2220         *            array of floats to convert
2221         * @return array of floats
2222         */
2223        public static float[] convertToFloat(final float[] array) {
2224                final float[] farr = new float[array.length];
2225
2226                for (int i = 0; i < array.length; i++) {
2227                        farr[i] = (float) array[i];
2228                }
2229                return farr;
2230        }
2231
2232    /**
2233         * Convert a float array to a float array.
2234         * 
2235         * @param array
2236         *            array of floats to convert
2237         * @return array of doubles
2238         */
2239        public static float[][] convertToFloat(final float[][] array)
2240        {
2241                final float[][] darr = new float[array.length][];
2242                for (int i = 0; i < array.length; i++)
2243                        darr[i] = convertToFloat(array[i]);
2244                return darr;
2245        }
2246
2247    
2248        /**
2249         * Convert a int array to a float array.
2250         * 
2251         * @param array
2252         *            array of ints to convert
2253         * @return array of floats
2254         */
2255        public static float[] convertToFloat(final int[] array) {
2256                final float[] farr = new float[array.length];
2257
2258                for (int i = 0; i < array.length; i++) {
2259                        farr[i] = (float) array[i];
2260                }
2261                return farr;
2262        }
2263
2264    /**
2265         * Convert a int array to a float array.
2266         * 
2267         * @param array
2268         *            array of ints to convert
2269         * @return array of doubles
2270         */
2271        public static float[][] convertToFloat(final int[][] array)
2272        {
2273                final float[][] darr = new float[array.length][];
2274                for (int i = 0; i < array.length; i++)
2275                        darr[i] = convertToFloat(array[i]);
2276                return darr;
2277        }
2278
2279    
2280        /**
2281         * Convert a long array to a float array.
2282         * 
2283         * @param array
2284         *            array of longs to convert
2285         * @return array of floats
2286         */
2287        public static float[] convertToFloat(final long[] array) {
2288                final float[] farr = new float[array.length];
2289
2290                for (int i = 0; i < array.length; i++) {
2291                        farr[i] = (float) array[i];
2292                }
2293                return farr;
2294        }
2295
2296    /**
2297         * Convert a long array to a float array.
2298         * 
2299         * @param array
2300         *            array of longs to convert
2301         * @return array of doubles
2302         */
2303        public static float[][] convertToFloat(final long[][] array)
2304        {
2305                final float[][] darr = new float[array.length][];
2306                for (int i = 0; i < array.length; i++)
2307                        darr[i] = convertToFloat(array[i]);
2308                return darr;
2309        }
2310
2311    
2312        /**
2313         * Convert a byte array to a float array.
2314         * 
2315         * @param array
2316         *            array of bytes to convert
2317         * @return array of floats
2318         */
2319        public static float[] convertToFloat(final byte[] array) {
2320                final float[] farr = new float[array.length];
2321
2322                for (int i = 0; i < array.length; i++) {
2323                        farr[i] = (float) array[i];
2324                }
2325                return farr;
2326        }
2327
2328    /**
2329         * Convert a byte array to a float array.
2330         * 
2331         * @param array
2332         *            array of bytes to convert
2333         * @return array of doubles
2334         */
2335        public static float[][] convertToFloat(final byte[][] array)
2336        {
2337                final float[][] darr = new float[array.length][];
2338                for (int i = 0; i < array.length; i++)
2339                        darr[i] = convertToFloat(array[i]);
2340                return darr;
2341        }
2342
2343    
2344        /**
2345         * Convert a short array to a float array.
2346         * 
2347         * @param array
2348         *            array of shorts to convert
2349         * @return array of floats
2350         */
2351        public static float[] convertToFloat(final short[] array) {
2352                final float[] farr = new float[array.length];
2353
2354                for (int i = 0; i < array.length; i++) {
2355                        farr[i] = (float) array[i];
2356                }
2357                return farr;
2358        }
2359
2360    /**
2361         * Convert a short array to a float array.
2362         * 
2363         * @param array
2364         *            array of shorts to convert
2365         * @return array of doubles
2366         */
2367        public static float[][] convertToFloat(final short[][] array)
2368        {
2369                final float[][] darr = new float[array.length][];
2370                for (int i = 0; i < array.length; i++)
2371                        darr[i] = convertToFloat(array[i]);
2372                return darr;
2373        }
2374
2375    
2376        /**
2377         * Return the first non-null item from an array.
2378         * 
2379         * @param <T>
2380         *            the type of the elements in the array
2381         * @param array
2382         *            the array
2383         * @return the first non-null object, or null if not found.
2384         */
2385        public static <T> T firstNonNull(final T[] array) {
2386                if (array == null)
2387                        return null;
2388
2389                for (final T obj : array) {
2390                        if (obj != null) {
2391                                return obj;
2392                        }
2393                }
2394
2395                return null;
2396        }
2397
2398    
2399        /**
2400         * Concatenate multiple arrays into a single new array.
2401         * 
2402         * @param <T>
2403         *            Type of elements in the array.
2404         * @param arrays
2405         *            the arrays to concatenate.
2406         * @return the new concatenated array
2407         */
2408        @SafeVarargs
2409        public static <T> T[] concatenate(final T[]... arrays) {
2410                int length = 0;
2411                Class<?> type = null;
2412
2413                for (final T[] arr : arrays) {
2414                        if (arr != null) {
2415                                length += arr.length;
2416
2417                                if (type == null) {
2418                                        type = arr.getClass().getComponentType();
2419                                }
2420                        }
2421                }
2422
2423                @SuppressWarnings("unchecked")
2424                final T[] concat = (T[]) Array.newInstance(type, length);
2425
2426                int current = 0;
2427                for (final T[] arr : arrays) {
2428                        System.arraycopy(arr, 0, concat, current, arr.length);
2429                        current += arr.length;
2430                }
2431
2432                return concat;
2433        }
2434
2435    
2436        /**
2437         * Concatenate multiple arrays into a single new array.
2438         * 
2439         * @param arrays
2440         *            the arrays to concatenate.
2441         * @return the new concatenated array
2442         */
2443        public static double[] concatenate(final double[]... arrays) {
2444                int length = 0;
2445                for (final double[] arr : arrays) {
2446                        length += (arr == null ? 0 : arr.length);
2447                }
2448
2449                final double[] concat = new double[length];
2450
2451                int current = 0;
2452                for (final double[] arr : arrays) {
2453                        System.arraycopy(arr, 0, concat, current, arr.length);
2454                        current += arr.length;
2455                }
2456
2457                return concat;
2458        }
2459        
2460         
2461        /**
2462         * Concatenate multiple arrays into a single new array.
2463         * 
2464         * @param arrays
2465         *            the arrays to concatenate.
2466         * @return the new concatenated array
2467         */
2468        public static float[] concatenate(final float[]... arrays) {
2469                int length = 0;
2470                for (final float[] arr : arrays) {
2471                        length += (arr == null ? 0 : arr.length);
2472                }
2473
2474                final float[] concat = new float[length];
2475
2476                int current = 0;
2477                for (final float[] arr : arrays) {
2478                        System.arraycopy(arr, 0, concat, current, arr.length);
2479                        current += arr.length;
2480                }
2481
2482                return concat;
2483        }
2484        
2485         
2486        /**
2487         * Concatenate multiple arrays into a single new array.
2488         * 
2489         * @param arrays
2490         *            the arrays to concatenate.
2491         * @return the new concatenated array
2492         */
2493        public static int[] concatenate(final int[]... arrays) {
2494                int length = 0;
2495                for (final int[] arr : arrays) {
2496                        length += (arr == null ? 0 : arr.length);
2497                }
2498
2499                final int[] concat = new int[length];
2500
2501                int current = 0;
2502                for (final int[] arr : arrays) {
2503                        System.arraycopy(arr, 0, concat, current, arr.length);
2504                        current += arr.length;
2505                }
2506
2507                return concat;
2508        }
2509        
2510         
2511        /**
2512         * Concatenate multiple arrays into a single new array.
2513         * 
2514         * @param arrays
2515         *            the arrays to concatenate.
2516         * @return the new concatenated array
2517         */
2518        public static long[] concatenate(final long[]... arrays) {
2519                int length = 0;
2520                for (final long[] arr : arrays) {
2521                        length += (arr == null ? 0 : arr.length);
2522                }
2523
2524                final long[] concat = new long[length];
2525
2526                int current = 0;
2527                for (final long[] arr : arrays) {
2528                        System.arraycopy(arr, 0, concat, current, arr.length);
2529                        current += arr.length;
2530                }
2531
2532                return concat;
2533        }
2534        
2535         
2536        /**
2537         * Concatenate multiple arrays into a single new array.
2538         * 
2539         * @param arrays
2540         *            the arrays to concatenate.
2541         * @return the new concatenated array
2542         */
2543        public static byte[] concatenate(final byte[]... arrays) {
2544                int length = 0;
2545                for (final byte[] arr : arrays) {
2546                        length += (arr == null ? 0 : arr.length);
2547                }
2548
2549                final byte[] concat = new byte[length];
2550
2551                int current = 0;
2552                for (final byte[] arr : arrays) {
2553                        System.arraycopy(arr, 0, concat, current, arr.length);
2554                        current += arr.length;
2555                }
2556
2557                return concat;
2558        }
2559        
2560         
2561        /**
2562         * Concatenate multiple arrays into a single new array.
2563         * 
2564         * @param arrays
2565         *            the arrays to concatenate.
2566         * @return the new concatenated array
2567         */
2568        public static short[] concatenate(final short[]... arrays) {
2569                int length = 0;
2570                for (final short[] arr : arrays) {
2571                        length += (arr == null ? 0 : arr.length);
2572                }
2573
2574                final short[] concat = new short[length];
2575
2576                int current = 0;
2577                for (final short[] arr : arrays) {
2578                        System.arraycopy(arr, 0, concat, current, arr.length);
2579                        current += arr.length;
2580                }
2581
2582                return concat;
2583        }
2584        
2585         
2586        /**
2587         * Concatenate multiple arrays into a single new array.
2588         * 
2589         * @param arrays
2590         *            the arrays to concatenate.
2591         * @return the new concatenated array
2592         */
2593        public static double[][] concatenate(final double[][]... arrays) {
2594                final double[][] concat = new double[arrays[0].length][];
2595                for(int i = 0; i < concat.length; i++){
2596                        final double[][] row = new double[arrays.length][];
2597                        for(int j = 0; j < row.length; j++){
2598                                row[j] = arrays[j][i];
2599                        } 
2600                        concat[i] = concatenate(row);
2601                }
2602                
2603                return concat;
2604        }
2605
2606        
2607        /**
2608         * Concatenate multiple arrays into a single new array.
2609         * 
2610         * @param arrays
2611         *            the arrays to concatenate.
2612         * @return the new concatenated array
2613         */
2614        public static float[][] concatenate(final float[][]... arrays) {
2615                final float[][] concat = new float[arrays[0].length][];
2616                for(int i = 0; i < concat.length; i++){
2617                        final float[][] row = new float[arrays.length][];
2618                        for(int j = 0; j < row.length; j++){
2619                                row[j] = arrays[j][i];
2620                        } 
2621                        concat[i] = concatenate(row);
2622                }
2623                
2624                return concat;
2625        }
2626
2627        
2628        /**
2629         * Concatenate multiple arrays into a single new array.
2630         * 
2631         * @param arrays
2632         *            the arrays to concatenate.
2633         * @return the new concatenated array
2634         */
2635        public static int[][] concatenate(final int[][]... arrays) {
2636                final int[][] concat = new int[arrays[0].length][];
2637                for(int i = 0; i < concat.length; i++){
2638                        final int[][] row = new int[arrays.length][];
2639                        for(int j = 0; j < row.length; j++){
2640                                row[j] = arrays[j][i];
2641                        } 
2642                        concat[i] = concatenate(row);
2643                }
2644                
2645                return concat;
2646        }
2647
2648        
2649        /**
2650         * Concatenate multiple arrays into a single new array.
2651         * 
2652         * @param arrays
2653         *            the arrays to concatenate.
2654         * @return the new concatenated array
2655         */
2656        public static long[][] concatenate(final long[][]... arrays) {
2657                final long[][] concat = new long[arrays[0].length][];
2658                for(int i = 0; i < concat.length; i++){
2659                        final long[][] row = new long[arrays.length][];
2660                        for(int j = 0; j < row.length; j++){
2661                                row[j] = arrays[j][i];
2662                        } 
2663                        concat[i] = concatenate(row);
2664                }
2665                
2666                return concat;
2667        }
2668
2669        
2670        /**
2671         * Concatenate multiple arrays into a single new array.
2672         * 
2673         * @param arrays
2674         *            the arrays to concatenate.
2675         * @return the new concatenated array
2676         */
2677        public static byte[][] concatenate(final byte[][]... arrays) {
2678                final byte[][] concat = new byte[arrays[0].length][];
2679                for(int i = 0; i < concat.length; i++){
2680                        final byte[][] row = new byte[arrays.length][];
2681                        for(int j = 0; j < row.length; j++){
2682                                row[j] = arrays[j][i];
2683                        } 
2684                        concat[i] = concatenate(row);
2685                }
2686                
2687                return concat;
2688        }
2689
2690        
2691        /**
2692         * Concatenate multiple arrays into a single new array.
2693         * 
2694         * @param arrays
2695         *            the arrays to concatenate.
2696         * @return the new concatenated array
2697         */
2698        public static short[][] concatenate(final short[][]... arrays) {
2699                final short[][] concat = new short[arrays[0].length][];
2700                for(int i = 0; i < concat.length; i++){
2701                        final short[][] row = new short[arrays.length][];
2702                        for(int j = 0; j < row.length; j++){
2703                                row[j] = arrays[j][i];
2704                        } 
2705                        concat[i] = concatenate(row);
2706                }
2707                
2708                return concat;
2709        }
2710
2711        
2712        /*** 
2713        { m -> 
2714                if (m['T'] == DOUBLE) {
2715                        return (m['R'] == DOUBLE);              
2716                }
2717                if (m['T'] == LONG) {
2718                        return (m['R'] == LONG);
2719                }
2720                if (m['T'] == INT) {
2721                        return (m['R'] == LONG);
2722                }
2723                if (m['T'] == SHORT) {
2724                        return (m['R'] == INT);
2725                }
2726                if (m['T'] == BYTE) {
2727                        return (m['R'] == INT);
2728                }
2729                return (m['R'] == FLOAT);
2730        }
2731    ***/
2732        /**
2733         * Compute the sum of values in an array
2734         * 
2735         * @param vector
2736         * @return the sum of all values
2737         */
2738        public static double sumValues(final double[] vector) {
2739                double sum = 0;
2740
2741                for (final double v : vector)
2742                        sum += v;
2743
2744                return sum;
2745        }
2746        
2747        
2748        /*** 
2749        { m -> 
2750                if (m['T'] == DOUBLE) {
2751                        return (m['R'] == DOUBLE);              
2752                }
2753                if (m['T'] == LONG) {
2754                        return (m['R'] == LONG);
2755                }
2756                if (m['T'] == INT) {
2757                        return (m['R'] == LONG);
2758                }
2759                if (m['T'] == SHORT) {
2760                        return (m['R'] == INT);
2761                }
2762                if (m['T'] == BYTE) {
2763                        return (m['R'] == INT);
2764                }
2765                return (m['R'] == FLOAT);
2766        }
2767    ***/
2768        /**
2769         * Compute the sum of values in an array
2770         * 
2771         * @param vector
2772         * @return the sum of all values
2773         */
2774        public static float sumValues(final float[] vector) {
2775                float sum = 0;
2776
2777                for (final float v : vector)
2778                        sum += v;
2779
2780                return sum;
2781        }
2782        
2783        
2784        /*** 
2785        { m -> 
2786                if (m['T'] == DOUBLE) {
2787                        return (m['R'] == DOUBLE);              
2788                }
2789                if (m['T'] == LONG) {
2790                        return (m['R'] == LONG);
2791                }
2792                if (m['T'] == INT) {
2793                        return (m['R'] == LONG);
2794                }
2795                if (m['T'] == SHORT) {
2796                        return (m['R'] == INT);
2797                }
2798                if (m['T'] == BYTE) {
2799                        return (m['R'] == INT);
2800                }
2801                return (m['R'] == FLOAT);
2802        }
2803    ***/
2804        /**
2805         * Compute the sum of values in an array
2806         * 
2807         * @param vector
2808         * @return the sum of all values
2809         */
2810        public static long sumValues(final int[] vector) {
2811                long sum = 0;
2812
2813                for (final int v : vector)
2814                        sum += v;
2815
2816                return sum;
2817        }
2818        
2819        
2820        /*** 
2821        { m -> 
2822                if (m['T'] == DOUBLE) {
2823                        return (m['R'] == DOUBLE);              
2824                }
2825                if (m['T'] == LONG) {
2826                        return (m['R'] == LONG);
2827                }
2828                if (m['T'] == INT) {
2829                        return (m['R'] == LONG);
2830                }
2831                if (m['T'] == SHORT) {
2832                        return (m['R'] == INT);
2833                }
2834                if (m['T'] == BYTE) {
2835                        return (m['R'] == INT);
2836                }
2837                return (m['R'] == FLOAT);
2838        }
2839    ***/
2840        /**
2841         * Compute the sum of values in an array
2842         * 
2843         * @param vector
2844         * @return the sum of all values
2845         */
2846        public static long sumValues(final long[] vector) {
2847                long sum = 0;
2848
2849                for (final long v : vector)
2850                        sum += v;
2851
2852                return sum;
2853        }
2854        
2855        
2856        /*** 
2857        { m -> 
2858                if (m['T'] == DOUBLE) {
2859                        return (m['R'] == DOUBLE);              
2860                }
2861                if (m['T'] == LONG) {
2862                        return (m['R'] == LONG);
2863                }
2864                if (m['T'] == INT) {
2865                        return (m['R'] == LONG);
2866                }
2867                if (m['T'] == SHORT) {
2868                        return (m['R'] == INT);
2869                }
2870                if (m['T'] == BYTE) {
2871                        return (m['R'] == INT);
2872                }
2873                return (m['R'] == FLOAT);
2874        }
2875    ***/
2876        /**
2877         * Compute the sum of values in an array
2878         * 
2879         * @param vector
2880         * @return the sum of all values
2881         */
2882        public static int sumValues(final byte[] vector) {
2883                int sum = 0;
2884
2885                for (final byte v : vector)
2886                        sum += v;
2887
2888                return sum;
2889        }
2890        
2891        
2892        /*** 
2893        { m -> 
2894                if (m['T'] == DOUBLE) {
2895                        return (m['R'] == DOUBLE);              
2896                }
2897                if (m['T'] == LONG) {
2898                        return (m['R'] == LONG);
2899                }
2900                if (m['T'] == INT) {
2901                        return (m['R'] == LONG);
2902                }
2903                if (m['T'] == SHORT) {
2904                        return (m['R'] == INT);
2905                }
2906                if (m['T'] == BYTE) {
2907                        return (m['R'] == INT);
2908                }
2909                return (m['R'] == FLOAT);
2910        }
2911    ***/
2912        /**
2913         * Compute the sum of values in an array
2914         * 
2915         * @param vector
2916         * @return the sum of all values
2917         */
2918        public static int sumValues(final short[] vector) {
2919                int sum = 0;
2920
2921                for (final short v : vector)
2922                        sum += v;
2923
2924                return sum;
2925        }
2926        
2927        
2928        /*** 
2929        { m -> 
2930                if (m['T'] == DOUBLE) {
2931                        return (m['R'] == DOUBLE);              
2932                }
2933                if (m['T'] == LONG) {
2934                        return (m['R'] == LONG);
2935                }
2936                if (m['T'] == INT) {
2937                        return (m['R'] == LONG);
2938                }
2939                if (m['T'] == SHORT) {
2940                        return (m['R'] == INT);
2941                }
2942                if (m['T'] == BYTE) {
2943                        return (m['R'] == INT);
2944                }
2945                return (m['R'] == FLOAT);
2946        }
2947    ***/
2948        /**
2949         * Compute the sum of values in a 2d array
2950         * 
2951         * @param array
2952         * @return the sum of all values
2953         */
2954        public static double sumValues(final double[][] array) {
2955                double sum = 0;
2956
2957                for (int i=0; i<array.length; i++)
2958                        for (int j=0; j<array[i].length; j++)
2959                                sum += array[i][j];
2960
2961                return sum;
2962        }
2963
2964    
2965        /*** 
2966        { m -> 
2967                if (m['T'] == DOUBLE) {
2968                        return (m['R'] == DOUBLE);              
2969                }
2970                if (m['T'] == LONG) {
2971                        return (m['R'] == LONG);
2972                }
2973                if (m['T'] == INT) {
2974                        return (m['R'] == LONG);
2975                }
2976                if (m['T'] == SHORT) {
2977                        return (m['R'] == INT);
2978                }
2979                if (m['T'] == BYTE) {
2980                        return (m['R'] == INT);
2981                }
2982                return (m['R'] == FLOAT);
2983        }
2984    ***/
2985        /**
2986         * Compute the sum of values in a 2d array
2987         * 
2988         * @param array
2989         * @return the sum of all values
2990         */
2991        public static float sumValues(final float[][] array) {
2992                float sum = 0;
2993
2994                for (int i=0; i<array.length; i++)
2995                        for (int j=0; j<array[i].length; j++)
2996                                sum += array[i][j];
2997
2998                return sum;
2999        }
3000
3001    
3002        /*** 
3003        { m -> 
3004                if (m['T'] == DOUBLE) {
3005                        return (m['R'] == DOUBLE);              
3006                }
3007                if (m['T'] == LONG) {
3008                        return (m['R'] == LONG);
3009                }
3010                if (m['T'] == INT) {
3011                        return (m['R'] == LONG);
3012                }
3013                if (m['T'] == SHORT) {
3014                        return (m['R'] == INT);
3015                }
3016                if (m['T'] == BYTE) {
3017                        return (m['R'] == INT);
3018                }
3019                return (m['R'] == FLOAT);
3020        }
3021    ***/
3022        /**
3023         * Compute the sum of values in a 2d array
3024         * 
3025         * @param array
3026         * @return the sum of all values
3027         */
3028        public static long sumValues(final int[][] array) {
3029                long sum = 0;
3030
3031                for (int i=0; i<array.length; i++)
3032                        for (int j=0; j<array[i].length; j++)
3033                                sum += array[i][j];
3034
3035                return sum;
3036        }
3037
3038    
3039        /*** 
3040        { m -> 
3041                if (m['T'] == DOUBLE) {
3042                        return (m['R'] == DOUBLE);              
3043                }
3044                if (m['T'] == LONG) {
3045                        return (m['R'] == LONG);
3046                }
3047                if (m['T'] == INT) {
3048                        return (m['R'] == LONG);
3049                }
3050                if (m['T'] == SHORT) {
3051                        return (m['R'] == INT);
3052                }
3053                if (m['T'] == BYTE) {
3054                        return (m['R'] == INT);
3055                }
3056                return (m['R'] == FLOAT);
3057        }
3058    ***/
3059        /**
3060         * Compute the sum of values in a 2d array
3061         * 
3062         * @param array
3063         * @return the sum of all values
3064         */
3065        public static long sumValues(final long[][] array) {
3066                long sum = 0;
3067
3068                for (int i=0; i<array.length; i++)
3069                        for (int j=0; j<array[i].length; j++)
3070                                sum += array[i][j];
3071
3072                return sum;
3073        }
3074
3075    
3076        /*** 
3077        { m -> 
3078                if (m['T'] == DOUBLE) {
3079                        return (m['R'] == DOUBLE);              
3080                }
3081                if (m['T'] == LONG) {
3082                        return (m['R'] == LONG);
3083                }
3084                if (m['T'] == INT) {
3085                        return (m['R'] == LONG);
3086                }
3087                if (m['T'] == SHORT) {
3088                        return (m['R'] == INT);
3089                }
3090                if (m['T'] == BYTE) {
3091                        return (m['R'] == INT);
3092                }
3093                return (m['R'] == FLOAT);
3094        }
3095    ***/
3096        /**
3097         * Compute the sum of values in a 2d array
3098         * 
3099         * @param array
3100         * @return the sum of all values
3101         */
3102        public static int sumValues(final byte[][] array) {
3103                int sum = 0;
3104
3105                for (int i=0; i<array.length; i++)
3106                        for (int j=0; j<array[i].length; j++)
3107                                sum += array[i][j];
3108
3109                return sum;
3110        }
3111
3112    
3113        /*** 
3114        { m -> 
3115                if (m['T'] == DOUBLE) {
3116                        return (m['R'] == DOUBLE);              
3117                }
3118                if (m['T'] == LONG) {
3119                        return (m['R'] == LONG);
3120                }
3121                if (m['T'] == INT) {
3122                        return (m['R'] == LONG);
3123                }
3124                if (m['T'] == SHORT) {
3125                        return (m['R'] == INT);
3126                }
3127                if (m['T'] == BYTE) {
3128                        return (m['R'] == INT);
3129                }
3130                return (m['R'] == FLOAT);
3131        }
3132    ***/
3133        /**
3134         * Compute the sum of values in a 2d array
3135         * 
3136         * @param array
3137         * @return the sum of all values
3138         */
3139        public static int sumValues(final short[][] array) {
3140                int sum = 0;
3141
3142                for (int i=0; i<array.length; i++)
3143                        for (int j=0; j<array[i].length; j++)
3144                                sum += array[i][j];
3145
3146                return sum;
3147        }
3148
3149    
3150        /*** 
3151        { m -> 
3152                if (m['T'] == DOUBLE) {
3153                        return (m['R'] == DOUBLE);              
3154                }
3155                if (m['T'] == LONG) {
3156                        return (m['R'] == LONG);
3157                }
3158                if (m['T'] == INT) {
3159                        return (m['R'] == LONG);
3160                }
3161                if (m['T'] == SHORT) {
3162                        return (m['R'] == INT);
3163                }
3164                if (m['T'] == BYTE) {
3165                        return (m['R'] == INT);
3166                }
3167                return (m['R'] == FLOAT);
3168        }
3169    ***/
3170        /**
3171         * Compute the sum of values squared in an array
3172         * 
3173         * @param vector
3174         * @return the sum of all values
3175         */
3176        public static double sumValuesSquared(final double[] vector) {
3177                double sum = 0;
3178
3179                for (final double v : vector)
3180                        sum += v * v;
3181
3182                return sum;
3183        }
3184
3185        
3186        /*** 
3187        { m -> 
3188                if (m['T'] == DOUBLE) {
3189                        return (m['R'] == DOUBLE);              
3190                }
3191                if (m['T'] == LONG) {
3192                        return (m['R'] == LONG);
3193                }
3194                if (m['T'] == INT) {
3195                        return (m['R'] == LONG);
3196                }
3197                if (m['T'] == SHORT) {
3198                        return (m['R'] == INT);
3199                }
3200                if (m['T'] == BYTE) {
3201                        return (m['R'] == INT);
3202                }
3203                return (m['R'] == FLOAT);
3204        }
3205    ***/
3206        /**
3207         * Compute the sum of values squared in an array
3208         * 
3209         * @param vector
3210         * @return the sum of all values
3211         */
3212        public static float sumValuesSquared(final float[] vector) {
3213                float sum = 0;
3214
3215                for (final float v : vector)
3216                        sum += v * v;
3217
3218                return sum;
3219        }
3220
3221        
3222        /*** 
3223        { m -> 
3224                if (m['T'] == DOUBLE) {
3225                        return (m['R'] == DOUBLE);              
3226                }
3227                if (m['T'] == LONG) {
3228                        return (m['R'] == LONG);
3229                }
3230                if (m['T'] == INT) {
3231                        return (m['R'] == LONG);
3232                }
3233                if (m['T'] == SHORT) {
3234                        return (m['R'] == INT);
3235                }
3236                if (m['T'] == BYTE) {
3237                        return (m['R'] == INT);
3238                }
3239                return (m['R'] == FLOAT);
3240        }
3241    ***/
3242        /**
3243         * Compute the sum of values squared in an array
3244         * 
3245         * @param vector
3246         * @return the sum of all values
3247         */
3248        public static long sumValuesSquared(final int[] vector) {
3249                long sum = 0;
3250
3251                for (final int v : vector)
3252                        sum += v * v;
3253
3254                return sum;
3255        }
3256
3257        
3258        /*** 
3259        { m -> 
3260                if (m['T'] == DOUBLE) {
3261                        return (m['R'] == DOUBLE);              
3262                }
3263                if (m['T'] == LONG) {
3264                        return (m['R'] == LONG);
3265                }
3266                if (m['T'] == INT) {
3267                        return (m['R'] == LONG);
3268                }
3269                if (m['T'] == SHORT) {
3270                        return (m['R'] == INT);
3271                }
3272                if (m['T'] == BYTE) {
3273                        return (m['R'] == INT);
3274                }
3275                return (m['R'] == FLOAT);
3276        }
3277    ***/
3278        /**
3279         * Compute the sum of values squared in an array
3280         * 
3281         * @param vector
3282         * @return the sum of all values
3283         */
3284        public static long sumValuesSquared(final long[] vector) {
3285                long sum = 0;
3286
3287                for (final long v : vector)
3288                        sum += v * v;
3289
3290                return sum;
3291        }
3292
3293        
3294        /*** 
3295        { m -> 
3296                if (m['T'] == DOUBLE) {
3297                        return (m['R'] == DOUBLE);              
3298                }
3299                if (m['T'] == LONG) {
3300                        return (m['R'] == LONG);
3301                }
3302                if (m['T'] == INT) {
3303                        return (m['R'] == LONG);
3304                }
3305                if (m['T'] == SHORT) {
3306                        return (m['R'] == INT);
3307                }
3308                if (m['T'] == BYTE) {
3309                        return (m['R'] == INT);
3310                }
3311                return (m['R'] == FLOAT);
3312        }
3313    ***/
3314        /**
3315         * Compute the sum of values squared in an array
3316         * 
3317         * @param vector
3318         * @return the sum of all values
3319         */
3320        public static int sumValuesSquared(final byte[] vector) {
3321                int sum = 0;
3322
3323                for (final byte v : vector)
3324                        sum += v * v;
3325
3326                return sum;
3327        }
3328
3329        
3330        /*** 
3331        { m -> 
3332                if (m['T'] == DOUBLE) {
3333                        return (m['R'] == DOUBLE);              
3334                }
3335                if (m['T'] == LONG) {
3336                        return (m['R'] == LONG);
3337                }
3338                if (m['T'] == INT) {
3339                        return (m['R'] == LONG);
3340                }
3341                if (m['T'] == SHORT) {
3342                        return (m['R'] == INT);
3343                }
3344                if (m['T'] == BYTE) {
3345                        return (m['R'] == INT);
3346                }
3347                return (m['R'] == FLOAT);
3348        }
3349    ***/
3350        /**
3351         * Compute the sum of values squared in an array
3352         * 
3353         * @param vector
3354         * @return the sum of all values
3355         */
3356        public static int sumValuesSquared(final short[] vector) {
3357                int sum = 0;
3358
3359                for (final short v : vector)
3360                        sum += v * v;
3361
3362                return sum;
3363        }
3364
3365        
3366        /*** 
3367        { m -> 
3368                if (m['T'] == DOUBLE) {
3369                        return (m['R'] == DOUBLE);              
3370                }
3371                if (m['T'] == LONG) {
3372                        return (m['R'] == LONG);
3373                }
3374                if (m['T'] == INT) {
3375                        return (m['R'] == LONG);
3376                }
3377                if (m['T'] == SHORT) {
3378                        return (m['R'] == INT);
3379                }
3380                if (m['T'] == BYTE) {
3381                        return (m['R'] == INT);
3382                }
3383                return (m['R'] == FLOAT);
3384        }
3385    ***/
3386        /**
3387         * Compute the cumulative sum of values in an array
3388         * 
3389         * @param vector
3390         * @return the sum of all values
3391         */
3392        public static double[] cumulativeSum(final double[] vector) {
3393                double[] sum = new double[vector.length];
3394
3395                if (vector.length == 0) return sum;
3396
3397                sum[0] = vector[0];
3398                for (int i=1; i<vector.length; i++)
3399                        sum[i] = vector[i] + sum[i-1];
3400
3401                return sum;
3402        }
3403        
3404        
3405        /*** 
3406        { m -> 
3407                if (m['T'] == DOUBLE) {
3408                        return (m['R'] == DOUBLE);              
3409                }
3410                if (m['T'] == LONG) {
3411                        return (m['R'] == LONG);
3412                }
3413                if (m['T'] == INT) {
3414                        return (m['R'] == LONG);
3415                }
3416                if (m['T'] == SHORT) {
3417                        return (m['R'] == INT);
3418                }
3419                if (m['T'] == BYTE) {
3420                        return (m['R'] == INT);
3421                }
3422                return (m['R'] == FLOAT);
3423        }
3424    ***/
3425        /**
3426         * Compute the cumulative sum of values in an array
3427         * 
3428         * @param vector
3429         * @return the sum of all values
3430         */
3431        public static float[] cumulativeSum(final float[] vector) {
3432                float[] sum = new float[vector.length];
3433
3434                if (vector.length == 0) return sum;
3435
3436                sum[0] = vector[0];
3437                for (int i=1; i<vector.length; i++)
3438                        sum[i] = vector[i] + sum[i-1];
3439
3440                return sum;
3441        }
3442        
3443        
3444        /*** 
3445        { m -> 
3446                if (m['T'] == DOUBLE) {
3447                        return (m['R'] == DOUBLE);              
3448                }
3449                if (m['T'] == LONG) {
3450                        return (m['R'] == LONG);
3451                }
3452                if (m['T'] == INT) {
3453                        return (m['R'] == LONG);
3454                }
3455                if (m['T'] == SHORT) {
3456                        return (m['R'] == INT);
3457                }
3458                if (m['T'] == BYTE) {
3459                        return (m['R'] == INT);
3460                }
3461                return (m['R'] == FLOAT);
3462        }
3463    ***/
3464        /**
3465         * Compute the cumulative sum of values in an array
3466         * 
3467         * @param vector
3468         * @return the sum of all values
3469         */
3470        public static long[] cumulativeSum(final int[] vector) {
3471                long[] sum = new long[vector.length];
3472
3473                if (vector.length == 0) return sum;
3474
3475                sum[0] = vector[0];
3476                for (int i=1; i<vector.length; i++)
3477                        sum[i] = vector[i] + sum[i-1];
3478
3479                return sum;
3480        }
3481        
3482        
3483        /*** 
3484        { m -> 
3485                if (m['T'] == DOUBLE) {
3486                        return (m['R'] == DOUBLE);              
3487                }
3488                if (m['T'] == LONG) {
3489                        return (m['R'] == LONG);
3490                }
3491                if (m['T'] == INT) {
3492                        return (m['R'] == LONG);
3493                }
3494                if (m['T'] == SHORT) {
3495                        return (m['R'] == INT);
3496                }
3497                if (m['T'] == BYTE) {
3498                        return (m['R'] == INT);
3499                }
3500                return (m['R'] == FLOAT);
3501        }
3502    ***/
3503        /**
3504         * Compute the cumulative sum of values in an array
3505         * 
3506         * @param vector
3507         * @return the sum of all values
3508         */
3509        public static long[] cumulativeSum(final long[] vector) {
3510                long[] sum = new long[vector.length];
3511
3512                if (vector.length == 0) return sum;
3513
3514                sum[0] = vector[0];
3515                for (int i=1; i<vector.length; i++)
3516                        sum[i] = vector[i] + sum[i-1];
3517
3518                return sum;
3519        }
3520        
3521        
3522        /*** 
3523        { m -> 
3524                if (m['T'] == DOUBLE) {
3525                        return (m['R'] == DOUBLE);              
3526                }
3527                if (m['T'] == LONG) {
3528                        return (m['R'] == LONG);
3529                }
3530                if (m['T'] == INT) {
3531                        return (m['R'] == LONG);
3532                }
3533                if (m['T'] == SHORT) {
3534                        return (m['R'] == INT);
3535                }
3536                if (m['T'] == BYTE) {
3537                        return (m['R'] == INT);
3538                }
3539                return (m['R'] == FLOAT);
3540        }
3541    ***/
3542        /**
3543         * Compute the cumulative sum of values in an array
3544         * 
3545         * @param vector
3546         * @return the sum of all values
3547         */
3548        public static int[] cumulativeSum(final byte[] vector) {
3549                int[] sum = new int[vector.length];
3550
3551                if (vector.length == 0) return sum;
3552
3553                sum[0] = vector[0];
3554                for (int i=1; i<vector.length; i++)
3555                        sum[i] = vector[i] + sum[i-1];
3556
3557                return sum;
3558        }
3559        
3560        
3561        /*** 
3562        { m -> 
3563                if (m['T'] == DOUBLE) {
3564                        return (m['R'] == DOUBLE);              
3565                }
3566                if (m['T'] == LONG) {
3567                        return (m['R'] == LONG);
3568                }
3569                if (m['T'] == INT) {
3570                        return (m['R'] == LONG);
3571                }
3572                if (m['T'] == SHORT) {
3573                        return (m['R'] == INT);
3574                }
3575                if (m['T'] == BYTE) {
3576                        return (m['R'] == INT);
3577                }
3578                return (m['R'] == FLOAT);
3579        }
3580    ***/
3581        /**
3582         * Compute the cumulative sum of values in an array
3583         * 
3584         * @param vector
3585         * @return the sum of all values
3586         */
3587        public static int[] cumulativeSum(final short[] vector) {
3588                int[] sum = new int[vector.length];
3589
3590                if (vector.length == 0) return sum;
3591
3592                sum[0] = vector[0];
3593                for (int i=1; i<vector.length; i++)
3594                        sum[i] = vector[i] + sum[i-1];
3595
3596                return sum;
3597        }
3598        
3599        
3600        /*** 
3601        { m -> 
3602                if (m['T'] == DOUBLE) {
3603                        return (m['R'] == DOUBLE);              
3604                }
3605                if (m['T'] == LONG) {
3606                        return (m['R'] == LONG);
3607                }
3608                if (m['T'] == INT) {
3609                        return (m['R'] == LONG);
3610                }
3611                if (m['T'] == SHORT) {
3612                        return (m['R'] == INT);
3613                }
3614                if (m['T'] == BYTE) {
3615                        return (m['R'] == INT);
3616                }
3617                return (m['R'] == FLOAT);
3618        }
3619    ***/
3620        /**
3621         * Compute the sum of values in each row of a 2d array
3622         * 
3623         * @param array the array 
3624         * @return the sum of each row
3625         */
3626        public static double[] rowSum(final double[][] array) {
3627                double[] sum = new double[array.length];
3628
3629                for (int i=0; i<array.length; i++)
3630                        for (int j=0; j<array[i].length; j++)
3631                                sum[i] += array[i][j];
3632
3633                return sum;
3634        }
3635        
3636        
3637        /*** 
3638        { m -> 
3639                if (m['T'] == DOUBLE) {
3640                        return (m['R'] == DOUBLE);              
3641                }
3642                if (m['T'] == LONG) {
3643                        return (m['R'] == LONG);
3644                }
3645                if (m['T'] == INT) {
3646                        return (m['R'] == LONG);
3647                }
3648                if (m['T'] == SHORT) {
3649                        return (m['R'] == INT);
3650                }
3651                if (m['T'] == BYTE) {
3652                        return (m['R'] == INT);
3653                }
3654                return (m['R'] == FLOAT);
3655        }
3656    ***/
3657        /**
3658         * Compute the sum of values in each row of a 2d array
3659         * 
3660         * @param array the array 
3661         * @return the sum of each row
3662         */
3663        public static float[] rowSum(final float[][] array) {
3664                float[] sum = new float[array.length];
3665
3666                for (int i=0; i<array.length; i++)
3667                        for (int j=0; j<array[i].length; j++)
3668                                sum[i] += array[i][j];
3669
3670                return sum;
3671        }
3672        
3673        
3674        /*** 
3675        { m -> 
3676                if (m['T'] == DOUBLE) {
3677                        return (m['R'] == DOUBLE);              
3678                }
3679                if (m['T'] == LONG) {
3680                        return (m['R'] == LONG);
3681                }
3682                if (m['T'] == INT) {
3683                        return (m['R'] == LONG);
3684                }
3685                if (m['T'] == SHORT) {
3686                        return (m['R'] == INT);
3687                }
3688                if (m['T'] == BYTE) {
3689                        return (m['R'] == INT);
3690                }
3691                return (m['R'] == FLOAT);
3692        }
3693    ***/
3694        /**
3695         * Compute the sum of values in each row of a 2d array
3696         * 
3697         * @param array the array 
3698         * @return the sum of each row
3699         */
3700        public static long[] rowSum(final int[][] array) {
3701                long[] sum = new long[array.length];
3702
3703                for (int i=0; i<array.length; i++)
3704                        for (int j=0; j<array[i].length; j++)
3705                                sum[i] += array[i][j];
3706
3707                return sum;
3708        }
3709        
3710        
3711        /*** 
3712        { m -> 
3713                if (m['T'] == DOUBLE) {
3714                        return (m['R'] == DOUBLE);              
3715                }
3716                if (m['T'] == LONG) {
3717                        return (m['R'] == LONG);
3718                }
3719                if (m['T'] == INT) {
3720                        return (m['R'] == LONG);
3721                }
3722                if (m['T'] == SHORT) {
3723                        return (m['R'] == INT);
3724                }
3725                if (m['T'] == BYTE) {
3726                        return (m['R'] == INT);
3727                }
3728                return (m['R'] == FLOAT);
3729        }
3730    ***/
3731        /**
3732         * Compute the sum of values in each row of a 2d array
3733         * 
3734         * @param array the array 
3735         * @return the sum of each row
3736         */
3737        public static long[] rowSum(final long[][] array) {
3738                long[] sum = new long[array.length];
3739
3740                for (int i=0; i<array.length; i++)
3741                        for (int j=0; j<array[i].length; j++)
3742                                sum[i] += array[i][j];
3743
3744                return sum;
3745        }
3746        
3747        
3748        /*** 
3749        { m -> 
3750                if (m['T'] == DOUBLE) {
3751                        return (m['R'] == DOUBLE);              
3752                }
3753                if (m['T'] == LONG) {
3754                        return (m['R'] == LONG);
3755                }
3756                if (m['T'] == INT) {
3757                        return (m['R'] == LONG);
3758                }
3759                if (m['T'] == SHORT) {
3760                        return (m['R'] == INT);
3761                }
3762                if (m['T'] == BYTE) {
3763                        return (m['R'] == INT);
3764                }
3765                return (m['R'] == FLOAT);
3766        }
3767    ***/
3768        /**
3769         * Compute the sum of values in each row of a 2d array
3770         * 
3771         * @param array the array 
3772         * @return the sum of each row
3773         */
3774        public static int[] rowSum(final byte[][] array) {
3775                int[] sum = new int[array.length];
3776
3777                for (int i=0; i<array.length; i++)
3778                        for (int j=0; j<array[i].length; j++)
3779                                sum[i] += array[i][j];
3780
3781                return sum;
3782        }
3783        
3784        
3785        /*** 
3786        { m -> 
3787                if (m['T'] == DOUBLE) {
3788                        return (m['R'] == DOUBLE);              
3789                }
3790                if (m['T'] == LONG) {
3791                        return (m['R'] == LONG);
3792                }
3793                if (m['T'] == INT) {
3794                        return (m['R'] == LONG);
3795                }
3796                if (m['T'] == SHORT) {
3797                        return (m['R'] == INT);
3798                }
3799                if (m['T'] == BYTE) {
3800                        return (m['R'] == INT);
3801                }
3802                return (m['R'] == FLOAT);
3803        }
3804    ***/
3805        /**
3806         * Compute the sum of values in each row of a 2d array
3807         * 
3808         * @param array the array 
3809         * @return the sum of each row
3810         */
3811        public static int[] rowSum(final short[][] array) {
3812                int[] sum = new int[array.length];
3813
3814                for (int i=0; i<array.length; i++)
3815                        for (int j=0; j<array[i].length; j++)
3816                                sum[i] += array[i][j];
3817
3818                return sum;
3819        }
3820        
3821        
3822        /*** 
3823        { m -> 
3824                if (m['T'] == DOUBLE) {
3825                        return (m['R'] == DOUBLE);              
3826                }
3827                if (m['T'] == LONG) {
3828                        return (m['R'] == LONG);
3829                }
3830                if (m['T'] == INT) {
3831                        return (m['R'] == LONG);
3832                }
3833                if (m['T'] == SHORT) {
3834                        return (m['R'] == INT);
3835                }
3836                if (m['T'] == BYTE) {
3837                        return (m['R'] == INT);
3838                }
3839                return (m['R'] == FLOAT);
3840        }
3841    ***/
3842        /**
3843         * Compute the sum of values in each column of a 2d array
3844         * 
3845         * @param array the array 
3846         * @return the sum of each column
3847         */
3848        public static double[] colSum(final double[][] array) {
3849                double[] sum = new double[array[0].length];
3850
3851                for (int i=0; i<array.length; i++)
3852                        for (int j=0; j<array[0].length; j++)
3853                                sum[j] += array[i][j];
3854
3855                return sum;
3856        }
3857
3858    
3859        /*** 
3860        { m -> 
3861                if (m['T'] == DOUBLE) {
3862                        return (m['R'] == DOUBLE);              
3863                }
3864                if (m['T'] == LONG) {
3865                        return (m['R'] == LONG);
3866                }
3867                if (m['T'] == INT) {
3868                        return (m['R'] == LONG);
3869                }
3870                if (m['T'] == SHORT) {
3871                        return (m['R'] == INT);
3872                }
3873                if (m['T'] == BYTE) {
3874                        return (m['R'] == INT);
3875                }
3876                return (m['R'] == FLOAT);
3877        }
3878    ***/
3879        /**
3880         * Compute the sum of values in each column of a 2d array
3881         * 
3882         * @param array the array 
3883         * @return the sum of each column
3884         */
3885        public static float[] colSum(final float[][] array) {
3886                float[] sum = new float[array[0].length];
3887
3888                for (int i=0; i<array.length; i++)
3889                        for (int j=0; j<array[0].length; j++)
3890                                sum[j] += array[i][j];
3891
3892                return sum;
3893        }
3894
3895    
3896        /*** 
3897        { m -> 
3898                if (m['T'] == DOUBLE) {
3899                        return (m['R'] == DOUBLE);              
3900                }
3901                if (m['T'] == LONG) {
3902                        return (m['R'] == LONG);
3903                }
3904                if (m['T'] == INT) {
3905                        return (m['R'] == LONG);
3906                }
3907                if (m['T'] == SHORT) {
3908                        return (m['R'] == INT);
3909                }
3910                if (m['T'] == BYTE) {
3911                        return (m['R'] == INT);
3912                }
3913                return (m['R'] == FLOAT);
3914        }
3915    ***/
3916        /**
3917         * Compute the sum of values in each column of a 2d array
3918         * 
3919         * @param array the array 
3920         * @return the sum of each column
3921         */
3922        public static long[] colSum(final int[][] array) {
3923                long[] sum = new long[array[0].length];
3924
3925                for (int i=0; i<array.length; i++)
3926                        for (int j=0; j<array[0].length; j++)
3927                                sum[j] += array[i][j];
3928
3929                return sum;
3930        }
3931
3932    
3933        /*** 
3934        { m -> 
3935                if (m['T'] == DOUBLE) {
3936                        return (m['R'] == DOUBLE);              
3937                }
3938                if (m['T'] == LONG) {
3939                        return (m['R'] == LONG);
3940                }
3941                if (m['T'] == INT) {
3942                        return (m['R'] == LONG);
3943                }
3944                if (m['T'] == SHORT) {
3945                        return (m['R'] == INT);
3946                }
3947                if (m['T'] == BYTE) {
3948                        return (m['R'] == INT);
3949                }
3950                return (m['R'] == FLOAT);
3951        }
3952    ***/
3953        /**
3954         * Compute the sum of values in each column of a 2d array
3955         * 
3956         * @param array the array 
3957         * @return the sum of each column
3958         */
3959        public static long[] colSum(final long[][] array) {
3960                long[] sum = new long[array[0].length];
3961
3962                for (int i=0; i<array.length; i++)
3963                        for (int j=0; j<array[0].length; j++)
3964                                sum[j] += array[i][j];
3965
3966                return sum;
3967        }
3968
3969    
3970        /*** 
3971        { m -> 
3972                if (m['T'] == DOUBLE) {
3973                        return (m['R'] == DOUBLE);              
3974                }
3975                if (m['T'] == LONG) {
3976                        return (m['R'] == LONG);
3977                }
3978                if (m['T'] == INT) {
3979                        return (m['R'] == LONG);
3980                }
3981                if (m['T'] == SHORT) {
3982                        return (m['R'] == INT);
3983                }
3984                if (m['T'] == BYTE) {
3985                        return (m['R'] == INT);
3986                }
3987                return (m['R'] == FLOAT);
3988        }
3989    ***/
3990        /**
3991         * Compute the sum of values in each column of a 2d array
3992         * 
3993         * @param array the array 
3994         * @return the sum of each column
3995         */
3996        public static int[] colSum(final byte[][] array) {
3997                int[] sum = new int[array[0].length];
3998
3999                for (int i=0; i<array.length; i++)
4000                        for (int j=0; j<array[0].length; j++)
4001                                sum[j] += array[i][j];
4002
4003                return sum;
4004        }
4005
4006    
4007        /*** 
4008        { m -> 
4009                if (m['T'] == DOUBLE) {
4010                        return (m['R'] == DOUBLE);              
4011                }
4012                if (m['T'] == LONG) {
4013                        return (m['R'] == LONG);
4014                }
4015                if (m['T'] == INT) {
4016                        return (m['R'] == LONG);
4017                }
4018                if (m['T'] == SHORT) {
4019                        return (m['R'] == INT);
4020                }
4021                if (m['T'] == BYTE) {
4022                        return (m['R'] == INT);
4023                }
4024                return (m['R'] == FLOAT);
4025        }
4026    ***/
4027        /**
4028         * Compute the sum of values in each column of a 2d array
4029         * 
4030         * @param array the array 
4031         * @return the sum of each column
4032         */
4033        public static int[] colSum(final short[][] array) {
4034                int[] sum = new int[array[0].length];
4035
4036                for (int i=0; i<array.length; i++)
4037                        for (int j=0; j<array[0].length; j++)
4038                                sum[j] += array[i][j];
4039
4040                return sum;
4041        }
4042
4043    
4044        /**
4045         * Extract a range
4046         * 
4047         * @param start
4048         * @param length
4049         * @return [start...length] (inclusive)
4050         */
4051        public static int[] range(final int start, final int length) {
4052                final int[] range = new int[length - start + 1];
4053                for (int i = start; i <= length; i++) {
4054                        range[i - start] = i;
4055                }
4056                return range;
4057        }
4058
4059    
4060        /**
4061         * Find the given value in the array, and return all indices at which it occurs.
4062         * 
4063         * @param a
4064         *            array to search
4065         * @param value
4066         *                        value to search for
4067         * @return the found values
4068         */
4069        public static int[] search(final double[] a, double value) {
4070                int count = 0;
4071
4072                for (int i = 0; i < a.length; i++)
4073                        if (a[i] == value) 
4074                                count++;
4075                
4076                int [] ret = new int[count];
4077                for (int i = 0, j=0; i < a.length; i++)
4078                        if (a[i] == value) ret[j++] = i;
4079                
4080                return ret;
4081        }
4082
4083    
4084        /**
4085         * Find the given value in the array, and return all indices at which it occurs.
4086         * 
4087         * @param a
4088         *            array to search
4089         * @param value
4090         *                        value to search for
4091         * @return the found values
4092         */
4093        public static int[] search(final float[] a, float value) {
4094                int count = 0;
4095
4096                for (int i = 0; i < a.length; i++)
4097                        if (a[i] == value) 
4098                                count++;
4099                
4100                int [] ret = new int[count];
4101                for (int i = 0, j=0; i < a.length; i++)
4102                        if (a[i] == value) ret[j++] = i;
4103                
4104                return ret;
4105        }
4106
4107    
4108        /**
4109         * Find the given value in the array, and return all indices at which it occurs.
4110         * 
4111         * @param a
4112         *            array to search
4113         * @param value
4114         *                        value to search for
4115         * @return the found values
4116         */
4117        public static int[] search(final int[] a, int value) {
4118                int count = 0;
4119
4120                for (int i = 0; i < a.length; i++)
4121                        if (a[i] == value) 
4122                                count++;
4123                
4124                int [] ret = new int[count];
4125                for (int i = 0, j=0; i < a.length; i++)
4126                        if (a[i] == value) ret[j++] = i;
4127                
4128                return ret;
4129        }
4130
4131    
4132        /**
4133         * Find the given value in the array, and return all indices at which it occurs.
4134         * 
4135         * @param a
4136         *            array to search
4137         * @param value
4138         *                        value to search for
4139         * @return the found values
4140         */
4141        public static int[] search(final long[] a, long value) {
4142                int count = 0;
4143
4144                for (int i = 0; i < a.length; i++)
4145                        if (a[i] == value) 
4146                                count++;
4147                
4148                int [] ret = new int[count];
4149                for (int i = 0, j=0; i < a.length; i++)
4150                        if (a[i] == value) ret[j++] = i;
4151                
4152                return ret;
4153        }
4154
4155    
4156        /**
4157         * Find the given value in the array, and return all indices at which it occurs.
4158         * 
4159         * @param a
4160         *            array to search
4161         * @param value
4162         *                        value to search for
4163         * @return the found values
4164         */
4165        public static int[] search(final byte[] a, byte value) {
4166                int count = 0;
4167
4168                for (int i = 0; i < a.length; i++)
4169                        if (a[i] == value) 
4170                                count++;
4171                
4172                int [] ret = new int[count];
4173                for (int i = 0, j=0; i < a.length; i++)
4174                        if (a[i] == value) ret[j++] = i;
4175                
4176                return ret;
4177        }
4178
4179    
4180        /**
4181         * Find the given value in the array, and return all indices at which it occurs.
4182         * 
4183         * @param a
4184         *            array to search
4185         * @param value
4186         *                        value to search for
4187         * @return the found values
4188         */
4189        public static int[] search(final short[] a, short value) {
4190                int count = 0;
4191
4192                for (int i = 0; i < a.length; i++)
4193                        if (a[i] == value) 
4194                                count++;
4195                
4196                int [] ret = new int[count];
4197                for (int i = 0, j=0; i < a.length; i++)
4198                        if (a[i] == value) ret[j++] = i;
4199                
4200                return ret;
4201        }
4202
4203    
4204        /**
4205         * Reshape a 2D array into a 1D array
4206         * 
4207         * @param a
4208         *            array to reshape
4209         * @return the reshaped array
4210         */
4211        public static double[] reshape(final double[][] a) {
4212                final double[] ret = new double[a.length * a[0].length];
4213
4214                for (int r = 0, i = 0; r < a.length; r++)
4215                        for (int c = 0; c < a[0].length; c++, i++)
4216                                ret[i] = a[r][c];
4217
4218                return ret;
4219        }
4220
4221    
4222        /**
4223         * Reshape a 2D array into a 1D array
4224         * 
4225         * @param a
4226         *            array to reshape
4227         * @return the reshaped array
4228         */
4229        public static float[] reshape(final float[][] a) {
4230                final float[] ret = new float[a.length * a[0].length];
4231
4232                for (int r = 0, i = 0; r < a.length; r++)
4233                        for (int c = 0; c < a[0].length; c++, i++)
4234                                ret[i] = a[r][c];
4235
4236                return ret;
4237        }
4238
4239    
4240        /**
4241         * Reshape a 2D array into a 1D array
4242         * 
4243         * @param a
4244         *            array to reshape
4245         * @return the reshaped array
4246         */
4247        public static int[] reshape(final int[][] a) {
4248                final int[] ret = new int[a.length * a[0].length];
4249
4250                for (int r = 0, i = 0; r < a.length; r++)
4251                        for (int c = 0; c < a[0].length; c++, i++)
4252                                ret[i] = a[r][c];
4253
4254                return ret;
4255        }
4256
4257    
4258        /**
4259         * Reshape a 2D array into a 1D array
4260         * 
4261         * @param a
4262         *            array to reshape
4263         * @return the reshaped array
4264         */
4265        public static long[] reshape(final long[][] a) {
4266                final long[] ret = new long[a.length * a[0].length];
4267
4268                for (int r = 0, i = 0; r < a.length; r++)
4269                        for (int c = 0; c < a[0].length; c++, i++)
4270                                ret[i] = a[r][c];
4271
4272                return ret;
4273        }
4274
4275    
4276        /**
4277         * Reshape a 2D array into a 1D array
4278         * 
4279         * @param a
4280         *            array to reshape
4281         * @return the reshaped array
4282         */
4283        public static byte[] reshape(final byte[][] a) {
4284                final byte[] ret = new byte[a.length * a[0].length];
4285
4286                for (int r = 0, i = 0; r < a.length; r++)
4287                        for (int c = 0; c < a[0].length; c++, i++)
4288                                ret[i] = a[r][c];
4289
4290                return ret;
4291        }
4292
4293    
4294        /**
4295         * Reshape a 2D array into a 1D array
4296         * 
4297         * @param a
4298         *            array to reshape
4299         * @return the reshaped array
4300         */
4301        public static short[] reshape(final short[][] a) {
4302                final short[] ret = new short[a.length * a[0].length];
4303
4304                for (int r = 0, i = 0; r < a.length; r++)
4305                        for (int c = 0; c < a[0].length; c++, i++)
4306                                ret[i] = a[r][c];
4307
4308                return ret;
4309        }
4310
4311    
4312        /**
4313         * Reshape a 2D array into a 1D array of doubles
4314         * 
4315         * @param a
4316         *            array to reshape
4317         * @return the reshaped array
4318         */
4319        public static double[] reshapeDouble(final double[][] a) {
4320                final double[] ret = new double[a.length * a[0].length];
4321
4322                for (int r = 0, i = 0; r < a.length; r++)
4323                        for (int c = 0; c < a[0].length; c++, i++)
4324                                ret[i] = a[r][c];
4325
4326                return ret;
4327        }
4328
4329    
4330        /**
4331         * Reshape a 2D array into a 1D array of doubles
4332         * 
4333         * @param a
4334         *            array to reshape
4335         * @return the reshaped array
4336         */
4337        public static double[] reshapeDouble(final float[][] a) {
4338                final double[] ret = new double[a.length * a[0].length];
4339
4340                for (int r = 0, i = 0; r < a.length; r++)
4341                        for (int c = 0; c < a[0].length; c++, i++)
4342                                ret[i] = a[r][c];
4343
4344                return ret;
4345        }
4346
4347    
4348        /**
4349         * Reshape a 2D array into a 1D array of doubles
4350         * 
4351         * @param a
4352         *            array to reshape
4353         * @return the reshaped array
4354         */
4355        public static double[] reshapeDouble(final int[][] a) {
4356                final double[] ret = new double[a.length * a[0].length];
4357
4358                for (int r = 0, i = 0; r < a.length; r++)
4359                        for (int c = 0; c < a[0].length; c++, i++)
4360                                ret[i] = a[r][c];
4361
4362                return ret;
4363        }
4364
4365    
4366        /**
4367         * Reshape a 2D array into a 1D array of doubles
4368         * 
4369         * @param a
4370         *            array to reshape
4371         * @return the reshaped array
4372         */
4373        public static double[] reshapeDouble(final long[][] a) {
4374                final double[] ret = new double[a.length * a[0].length];
4375
4376                for (int r = 0, i = 0; r < a.length; r++)
4377                        for (int c = 0; c < a[0].length; c++, i++)
4378                                ret[i] = a[r][c];
4379
4380                return ret;
4381        }
4382
4383    
4384        /**
4385         * Reshape a 2D array into a 1D array of doubles
4386         * 
4387         * @param a
4388         *            array to reshape
4389         * @return the reshaped array
4390         */
4391        public static double[] reshapeDouble(final byte[][] a) {
4392                final double[] ret = new double[a.length * a[0].length];
4393
4394                for (int r = 0, i = 0; r < a.length; r++)
4395                        for (int c = 0; c < a[0].length; c++, i++)
4396                                ret[i] = a[r][c];
4397
4398                return ret;
4399        }
4400
4401    
4402        /**
4403         * Reshape a 2D array into a 1D array of doubles
4404         * 
4405         * @param a
4406         *            array to reshape
4407         * @return the reshaped array
4408         */
4409        public static double[] reshapeDouble(final short[][] a) {
4410                final double[] ret = new double[a.length * a[0].length];
4411
4412                for (int r = 0, i = 0; r < a.length; r++)
4413                        for (int c = 0; c < a[0].length; c++, i++)
4414                                ret[i] = a[r][c];
4415
4416                return ret;
4417        }
4418
4419    
4420        /**
4421         * Reshape a 1D array into a 2D array
4422         * 
4423         * @param a
4424         *            array to reshape
4425         * @param out
4426         *            the return array, correctly sized
4427         * @return the reshaped array
4428         */
4429        public static double[][] reshape(final double[] a, final double[][] out) {
4430                for (int r = 0, i = 0; r < out.length; r++)
4431                        for (int c = 0; c < out[0].length; c++, i++)
4432                                out[r][c] = a[i];
4433
4434                return out;
4435        }
4436
4437        /**
4438         * Reshape a 1D array into a 2D array
4439         * 
4440         * @param a
4441         *            array to reshape
4442         * @param width
4443         *            the width of the return array
4444         * @param height
4445         *            the height of the return array
4446         * @return the reshaped array
4447         */
4448        public static double[][] reshape(final double[] a, final int width, final int height) {
4449                final double[][] ret = new double[height][width];
4450                return reshape(a, ret);
4451        }
4452
4453    
4454        /**
4455         * Reshape a 1D array into a 2D array
4456         * 
4457         * @param a
4458         *            array to reshape
4459         * @param out
4460         *            the return array, correctly sized
4461         * @return the reshaped array
4462         */
4463        public static float[][] reshape(final float[] a, final float[][] out) {
4464                for (int r = 0, i = 0; r < out.length; r++)
4465                        for (int c = 0; c < out[0].length; c++, i++)
4466                                out[r][c] = a[i];
4467
4468                return out;
4469        }
4470
4471        /**
4472         * Reshape a 1D array into a 2D array
4473         * 
4474         * @param a
4475         *            array to reshape
4476         * @param width
4477         *            the width of the return array
4478         * @param height
4479         *            the height of the return array
4480         * @return the reshaped array
4481         */
4482        public static float[][] reshape(final float[] a, final int width, final int height) {
4483                final float[][] ret = new float[height][width];
4484                return reshape(a, ret);
4485        }
4486
4487    
4488        /**
4489         * Reshape a 1D array into a 2D array
4490         * 
4491         * @param a
4492         *            array to reshape
4493         * @param out
4494         *            the return array, correctly sized
4495         * @return the reshaped array
4496         */
4497        public static int[][] reshape(final int[] a, final int[][] out) {
4498                for (int r = 0, i = 0; r < out.length; r++)
4499                        for (int c = 0; c < out[0].length; c++, i++)
4500                                out[r][c] = a[i];
4501
4502                return out;
4503        }
4504
4505        /**
4506         * Reshape a 1D array into a 2D array
4507         * 
4508         * @param a
4509         *            array to reshape
4510         * @param width
4511         *            the width of the return array
4512         * @param height
4513         *            the height of the return array
4514         * @return the reshaped array
4515         */
4516        public static int[][] reshape(final int[] a, final int width, final int height) {
4517                final int[][] ret = new int[height][width];
4518                return reshape(a, ret);
4519        }
4520
4521    
4522        /**
4523         * Reshape a 1D array into a 2D array
4524         * 
4525         * @param a
4526         *            array to reshape
4527         * @param out
4528         *            the return array, correctly sized
4529         * @return the reshaped array
4530         */
4531        public static long[][] reshape(final long[] a, final long[][] out) {
4532                for (int r = 0, i = 0; r < out.length; r++)
4533                        for (int c = 0; c < out[0].length; c++, i++)
4534                                out[r][c] = a[i];
4535
4536                return out;
4537        }
4538
4539        /**
4540         * Reshape a 1D array into a 2D array
4541         * 
4542         * @param a
4543         *            array to reshape
4544         * @param width
4545         *            the width of the return array
4546         * @param height
4547         *            the height of the return array
4548         * @return the reshaped array
4549         */
4550        public static long[][] reshape(final long[] a, final int width, final int height) {
4551                final long[][] ret = new long[height][width];
4552                return reshape(a, ret);
4553        }
4554
4555    
4556        /**
4557         * Reshape a 1D array into a 2D array
4558         * 
4559         * @param a
4560         *            array to reshape
4561         * @param out
4562         *            the return array, correctly sized
4563         * @return the reshaped array
4564         */
4565        public static byte[][] reshape(final byte[] a, final byte[][] out) {
4566                for (int r = 0, i = 0; r < out.length; r++)
4567                        for (int c = 0; c < out[0].length; c++, i++)
4568                                out[r][c] = a[i];
4569
4570                return out;
4571        }
4572
4573        /**
4574         * Reshape a 1D array into a 2D array
4575         * 
4576         * @param a
4577         *            array to reshape
4578         * @param width
4579         *            the width of the return array
4580         * @param height
4581         *            the height of the return array
4582         * @return the reshaped array
4583         */
4584        public static byte[][] reshape(final byte[] a, final int width, final int height) {
4585                final byte[][] ret = new byte[height][width];
4586                return reshape(a, ret);
4587        }
4588
4589    
4590        /**
4591         * Reshape a 1D array into a 2D array
4592         * 
4593         * @param a
4594         *            array to reshape
4595         * @param out
4596         *            the return array, correctly sized
4597         * @return the reshaped array
4598         */
4599        public static short[][] reshape(final short[] a, final short[][] out) {
4600                for (int r = 0, i = 0; r < out.length; r++)
4601                        for (int c = 0; c < out[0].length; c++, i++)
4602                                out[r][c] = a[i];
4603
4604                return out;
4605        }
4606
4607        /**
4608         * Reshape a 1D array into a 2D array
4609         * 
4610         * @param a
4611         *            array to reshape
4612         * @param width
4613         *            the width of the return array
4614         * @param height
4615         *            the height of the return array
4616         * @return the reshaped array
4617         */
4618        public static short[][] reshape(final short[] a, final int width, final int height) {
4619                final short[][] ret = new short[height][width];
4620                return reshape(a, ret);
4621        }
4622
4623    
4624        /**
4625         * Reshape a 1D array into a 2D array
4626         * 
4627         * @param a
4628         *            array to reshape
4629         * @param out
4630         *            the return array, correctly sized
4631         * @return the reshaped array
4632         */
4633        public static float[][] reshapeFloat(final double[] a, final float[][] out) {
4634                for (int r = 0, i = 0; r < out.length; r++)
4635                        for (int c = 0; c < out[0].length; c++, i++)
4636                                out[r][c] = (float) a[i];
4637
4638                return out;
4639        }
4640
4641        /**
4642         * Reshape a 1D array into a 2D array
4643         * 
4644         * @param a
4645         *            array to reshape
4646         * @param width
4647         *            the width of the return array
4648         * @param height
4649         *            the height of the return array
4650         * @return the reshaped array
4651         */
4652        public static float[][] reshapeFloat(final double[] a, final int width, final int height) {
4653                final float[][] ret = new float[height][width];
4654                return reshapeFloat(a, ret);
4655        }
4656
4657    
4658        /**
4659         * Sort parallel arrays. Arrays are sorted in-place. The first array
4660         * determines the order, and is sorted into descending order.
4661         * <p>
4662         * Implementation inspired by this stackoverflow page: <a href=
4663         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
4664         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
4665         * get-a-sorted-list-of-indices-of-an-array </a>
4666         * 
4667         * @param main
4668         *            the values to use for determining the order
4669         * @param indices
4670         *            the second array
4671         */
4672        public static void parallelQuicksortDescending(final double[] main, final double[] indices) {
4673                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
4674        }
4675
4676        /**
4677         * Sort parallel arrays. Arrays are sorted in-place. The first array
4678         * determines the order, and is sorted into descending order.
4679         * <p>
4680         * Implementation inspired by this stackoverflow page: <a href=
4681         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
4682         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
4683         * get-a-sorted-list-of-indices-of-an-array </a>
4684         * 
4685         * @param main
4686         *            the values to use for determining the order
4687         * @param indices
4688         *            the second array
4689         * @param left
4690         *            the starting index
4691         * @param right
4692         *            the ending index
4693         */
4694        public static void parallelQuicksortDescending(final double[] main, final double[] indices, final int left,
4695                        final int right)
4696        {
4697                if (right <= left)
4698                        return;
4699
4700                final int i = partitionDesc(main, indices, left, right);
4701
4702                parallelQuicksortDescending(main, indices, left, i - 1);
4703                parallelQuicksortDescending(main, indices, i + 1, right);
4704        }
4705
4706        // partition a[left] to a[right], assumes left < right
4707        private static int partitionDesc(final double[] a, final double[] index, final int left, final int right) {
4708                int i = left - 1;
4709                int j = right;
4710                while (true) {
4711                        while (a[++i] > a[right])
4712                                // find item on left to swap
4713                                ; // a[right] acts as sentinel
4714                        while (a[right] > a[--j])
4715                                // find item on right to swap
4716                                if (j == left)
4717                                        break; // don't go out-of-bounds
4718                        if (i >= j)
4719                                break; // check if pointers cross
4720                        exch(a, index, i, j); // swap two elements into place
4721                }
4722                exch(a, index, i, right); // swap with partition element
4723                return i;
4724        }
4725        
4726        
4727        /**
4728         * Sort parallel arrays. Arrays are sorted in-place. The first array
4729         * determines the order, and is sorted into descending order.
4730         * <p>
4731         * Implementation inspired by this stackoverflow page: <a href=
4732         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
4733         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
4734         * get-a-sorted-list-of-indices-of-an-array </a>
4735         * 
4736         * @param main
4737         *            the values to use for determining the order
4738         * @param indices
4739         *            the second array
4740         */
4741        public static void parallelQuicksortDescending(final double[] main, final float[] indices) {
4742                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
4743        }
4744
4745        /**
4746         * Sort parallel arrays. Arrays are sorted in-place. The first array
4747         * determines the order, and is sorted into descending order.
4748         * <p>
4749         * Implementation inspired by this stackoverflow page: <a href=
4750         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
4751         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
4752         * get-a-sorted-list-of-indices-of-an-array </a>
4753         * 
4754         * @param main
4755         *            the values to use for determining the order
4756         * @param indices
4757         *            the second array
4758         * @param left
4759         *            the starting index
4760         * @param right
4761         *            the ending index
4762         */
4763        public static void parallelQuicksortDescending(final double[] main, final float[] indices, final int left,
4764                        final int right)
4765        {
4766                if (right <= left)
4767                        return;
4768
4769                final int i = partitionDesc(main, indices, left, right);
4770
4771                parallelQuicksortDescending(main, indices, left, i - 1);
4772                parallelQuicksortDescending(main, indices, i + 1, right);
4773        }
4774
4775        // partition a[left] to a[right], assumes left < right
4776        private static int partitionDesc(final double[] a, final float[] index, final int left, final int right) {
4777                int i = left - 1;
4778                int j = right;
4779                while (true) {
4780                        while (a[++i] > a[right])
4781                                // find item on left to swap
4782                                ; // a[right] acts as sentinel
4783                        while (a[right] > a[--j])
4784                                // find item on right to swap
4785                                if (j == left)
4786                                        break; // don't go out-of-bounds
4787                        if (i >= j)
4788                                break; // check if pointers cross
4789                        exch(a, index, i, j); // swap two elements into place
4790                }
4791                exch(a, index, i, right); // swap with partition element
4792                return i;
4793        }
4794        
4795        
4796        /**
4797         * Sort parallel arrays. Arrays are sorted in-place. The first array
4798         * determines the order, and is sorted into descending order.
4799         * <p>
4800         * Implementation inspired by this stackoverflow page: <a href=
4801         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
4802         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
4803         * get-a-sorted-list-of-indices-of-an-array </a>
4804         * 
4805         * @param main
4806         *            the values to use for determining the order
4807         * @param indices
4808         *            the second array
4809         */
4810        public static void parallelQuicksortDescending(final double[] main, final int[] indices) {
4811                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
4812        }
4813
4814        /**
4815         * Sort parallel arrays. Arrays are sorted in-place. The first array
4816         * determines the order, and is sorted into descending order.
4817         * <p>
4818         * Implementation inspired by this stackoverflow page: <a href=
4819         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
4820         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
4821         * get-a-sorted-list-of-indices-of-an-array </a>
4822         * 
4823         * @param main
4824         *            the values to use for determining the order
4825         * @param indices
4826         *            the second array
4827         * @param left
4828         *            the starting index
4829         * @param right
4830         *            the ending index
4831         */
4832        public static void parallelQuicksortDescending(final double[] main, final int[] indices, final int left,
4833                        final int right)
4834        {
4835                if (right <= left)
4836                        return;
4837
4838                final int i = partitionDesc(main, indices, left, right);
4839
4840                parallelQuicksortDescending(main, indices, left, i - 1);
4841                parallelQuicksortDescending(main, indices, i + 1, right);
4842        }
4843
4844        // partition a[left] to a[right], assumes left < right
4845        private static int partitionDesc(final double[] a, final int[] index, final int left, final int right) {
4846                int i = left - 1;
4847                int j = right;
4848                while (true) {
4849                        while (a[++i] > a[right])
4850                                // find item on left to swap
4851                                ; // a[right] acts as sentinel
4852                        while (a[right] > a[--j])
4853                                // find item on right to swap
4854                                if (j == left)
4855                                        break; // don't go out-of-bounds
4856                        if (i >= j)
4857                                break; // check if pointers cross
4858                        exch(a, index, i, j); // swap two elements into place
4859                }
4860                exch(a, index, i, right); // swap with partition element
4861                return i;
4862        }
4863        
4864        
4865        /**
4866         * Sort parallel arrays. Arrays are sorted in-place. The first array
4867         * determines the order, and is sorted into descending order.
4868         * <p>
4869         * Implementation inspired by this stackoverflow page: <a href=
4870         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
4871         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
4872         * get-a-sorted-list-of-indices-of-an-array </a>
4873         * 
4874         * @param main
4875         *            the values to use for determining the order
4876         * @param indices
4877         *            the second array
4878         */
4879        public static void parallelQuicksortDescending(final double[] main, final long[] indices) {
4880                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
4881        }
4882
4883        /**
4884         * Sort parallel arrays. Arrays are sorted in-place. The first array
4885         * determines the order, and is sorted into descending order.
4886         * <p>
4887         * Implementation inspired by this stackoverflow page: <a href=
4888         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
4889         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
4890         * get-a-sorted-list-of-indices-of-an-array </a>
4891         * 
4892         * @param main
4893         *            the values to use for determining the order
4894         * @param indices
4895         *            the second array
4896         * @param left
4897         *            the starting index
4898         * @param right
4899         *            the ending index
4900         */
4901        public static void parallelQuicksortDescending(final double[] main, final long[] indices, final int left,
4902                        final int right)
4903        {
4904                if (right <= left)
4905                        return;
4906
4907                final int i = partitionDesc(main, indices, left, right);
4908
4909                parallelQuicksortDescending(main, indices, left, i - 1);
4910                parallelQuicksortDescending(main, indices, i + 1, right);
4911        }
4912
4913        // partition a[left] to a[right], assumes left < right
4914        private static int partitionDesc(final double[] a, final long[] index, final int left, final int right) {
4915                int i = left - 1;
4916                int j = right;
4917                while (true) {
4918                        while (a[++i] > a[right])
4919                                // find item on left to swap
4920                                ; // a[right] acts as sentinel
4921                        while (a[right] > a[--j])
4922                                // find item on right to swap
4923                                if (j == left)
4924                                        break; // don't go out-of-bounds
4925                        if (i >= j)
4926                                break; // check if pointers cross
4927                        exch(a, index, i, j); // swap two elements into place
4928                }
4929                exch(a, index, i, right); // swap with partition element
4930                return i;
4931        }
4932        
4933        
4934        /**
4935         * Sort parallel arrays. Arrays are sorted in-place. The first array
4936         * determines the order, and is sorted into descending order.
4937         * <p>
4938         * Implementation inspired by this stackoverflow page: <a href=
4939         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
4940         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
4941         * get-a-sorted-list-of-indices-of-an-array </a>
4942         * 
4943         * @param main
4944         *            the values to use for determining the order
4945         * @param indices
4946         *            the second array
4947         */
4948        public static void parallelQuicksortDescending(final double[] main, final byte[] indices) {
4949                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
4950        }
4951
4952        /**
4953         * Sort parallel arrays. Arrays are sorted in-place. The first array
4954         * determines the order, and is sorted into descending order.
4955         * <p>
4956         * Implementation inspired by this stackoverflow page: <a href=
4957         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
4958         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
4959         * get-a-sorted-list-of-indices-of-an-array </a>
4960         * 
4961         * @param main
4962         *            the values to use for determining the order
4963         * @param indices
4964         *            the second array
4965         * @param left
4966         *            the starting index
4967         * @param right
4968         *            the ending index
4969         */
4970        public static void parallelQuicksortDescending(final double[] main, final byte[] indices, final int left,
4971                        final int right)
4972        {
4973                if (right <= left)
4974                        return;
4975
4976                final int i = partitionDesc(main, indices, left, right);
4977
4978                parallelQuicksortDescending(main, indices, left, i - 1);
4979                parallelQuicksortDescending(main, indices, i + 1, right);
4980        }
4981
4982        // partition a[left] to a[right], assumes left < right
4983        private static int partitionDesc(final double[] a, final byte[] index, final int left, final int right) {
4984                int i = left - 1;
4985                int j = right;
4986                while (true) {
4987                        while (a[++i] > a[right])
4988                                // find item on left to swap
4989                                ; // a[right] acts as sentinel
4990                        while (a[right] > a[--j])
4991                                // find item on right to swap
4992                                if (j == left)
4993                                        break; // don't go out-of-bounds
4994                        if (i >= j)
4995                                break; // check if pointers cross
4996                        exch(a, index, i, j); // swap two elements into place
4997                }
4998                exch(a, index, i, right); // swap with partition element
4999                return i;
5000        }
5001        
5002        
5003        /**
5004         * Sort parallel arrays. Arrays are sorted in-place. The first array
5005         * determines the order, and is sorted into descending order.
5006         * <p>
5007         * Implementation inspired by this stackoverflow page: <a href=
5008         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5009         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5010         * get-a-sorted-list-of-indices-of-an-array </a>
5011         * 
5012         * @param main
5013         *            the values to use for determining the order
5014         * @param indices
5015         *            the second array
5016         */
5017        public static void parallelQuicksortDescending(final double[] main, final short[] indices) {
5018                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
5019        }
5020
5021        /**
5022         * Sort parallel arrays. Arrays are sorted in-place. The first array
5023         * determines the order, and is sorted into descending order.
5024         * <p>
5025         * Implementation inspired by this stackoverflow page: <a href=
5026         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5027         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5028         * get-a-sorted-list-of-indices-of-an-array </a>
5029         * 
5030         * @param main
5031         *            the values to use for determining the order
5032         * @param indices
5033         *            the second array
5034         * @param left
5035         *            the starting index
5036         * @param right
5037         *            the ending index
5038         */
5039        public static void parallelQuicksortDescending(final double[] main, final short[] indices, final int left,
5040                        final int right)
5041        {
5042                if (right <= left)
5043                        return;
5044
5045                final int i = partitionDesc(main, indices, left, right);
5046
5047                parallelQuicksortDescending(main, indices, left, i - 1);
5048                parallelQuicksortDescending(main, indices, i + 1, right);
5049        }
5050
5051        // partition a[left] to a[right], assumes left < right
5052        private static int partitionDesc(final double[] a, final short[] index, final int left, final int right) {
5053                int i = left - 1;
5054                int j = right;
5055                while (true) {
5056                        while (a[++i] > a[right])
5057                                // find item on left to swap
5058                                ; // a[right] acts as sentinel
5059                        while (a[right] > a[--j])
5060                                // find item on right to swap
5061                                if (j == left)
5062                                        break; // don't go out-of-bounds
5063                        if (i >= j)
5064                                break; // check if pointers cross
5065                        exch(a, index, i, j); // swap two elements into place
5066                }
5067                exch(a, index, i, right); // swap with partition element
5068                return i;
5069        }
5070        
5071        
5072        /**
5073         * Sort parallel arrays. Arrays are sorted in-place. The first array
5074         * determines the order, and is sorted into descending order.
5075         * <p>
5076         * Implementation inspired by this stackoverflow page: <a href=
5077         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5078         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5079         * get-a-sorted-list-of-indices-of-an-array </a>
5080         * 
5081         * @param main
5082         *            the values to use for determining the order
5083         * @param indices
5084         *            the second array
5085         */
5086        public static void parallelQuicksortDescending(final float[] main, final double[] indices) {
5087                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
5088        }
5089
5090        /**
5091         * Sort parallel arrays. Arrays are sorted in-place. The first array
5092         * determines the order, and is sorted into descending order.
5093         * <p>
5094         * Implementation inspired by this stackoverflow page: <a href=
5095         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5096         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5097         * get-a-sorted-list-of-indices-of-an-array </a>
5098         * 
5099         * @param main
5100         *            the values to use for determining the order
5101         * @param indices
5102         *            the second array
5103         * @param left
5104         *            the starting index
5105         * @param right
5106         *            the ending index
5107         */
5108        public static void parallelQuicksortDescending(final float[] main, final double[] indices, final int left,
5109                        final int right)
5110        {
5111                if (right <= left)
5112                        return;
5113
5114                final int i = partitionDesc(main, indices, left, right);
5115
5116                parallelQuicksortDescending(main, indices, left, i - 1);
5117                parallelQuicksortDescending(main, indices, i + 1, right);
5118        }
5119
5120        // partition a[left] to a[right], assumes left < right
5121        private static int partitionDesc(final float[] a, final double[] index, final int left, final int right) {
5122                int i = left - 1;
5123                int j = right;
5124                while (true) {
5125                        while (a[++i] > a[right])
5126                                // find item on left to swap
5127                                ; // a[right] acts as sentinel
5128                        while (a[right] > a[--j])
5129                                // find item on right to swap
5130                                if (j == left)
5131                                        break; // don't go out-of-bounds
5132                        if (i >= j)
5133                                break; // check if pointers cross
5134                        exch(a, index, i, j); // swap two elements into place
5135                }
5136                exch(a, index, i, right); // swap with partition element
5137                return i;
5138        }
5139        
5140        
5141        /**
5142         * Sort parallel arrays. Arrays are sorted in-place. The first array
5143         * determines the order, and is sorted into descending order.
5144         * <p>
5145         * Implementation inspired by this stackoverflow page: <a href=
5146         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5147         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5148         * get-a-sorted-list-of-indices-of-an-array </a>
5149         * 
5150         * @param main
5151         *            the values to use for determining the order
5152         * @param indices
5153         *            the second array
5154         */
5155        public static void parallelQuicksortDescending(final float[] main, final float[] indices) {
5156                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
5157        }
5158
5159        /**
5160         * Sort parallel arrays. Arrays are sorted in-place. The first array
5161         * determines the order, and is sorted into descending order.
5162         * <p>
5163         * Implementation inspired by this stackoverflow page: <a href=
5164         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5165         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5166         * get-a-sorted-list-of-indices-of-an-array </a>
5167         * 
5168         * @param main
5169         *            the values to use for determining the order
5170         * @param indices
5171         *            the second array
5172         * @param left
5173         *            the starting index
5174         * @param right
5175         *            the ending index
5176         */
5177        public static void parallelQuicksortDescending(final float[] main, final float[] indices, final int left,
5178                        final int right)
5179        {
5180                if (right <= left)
5181                        return;
5182
5183                final int i = partitionDesc(main, indices, left, right);
5184
5185                parallelQuicksortDescending(main, indices, left, i - 1);
5186                parallelQuicksortDescending(main, indices, i + 1, right);
5187        }
5188
5189        // partition a[left] to a[right], assumes left < right
5190        private static int partitionDesc(final float[] a, final float[] index, final int left, final int right) {
5191                int i = left - 1;
5192                int j = right;
5193                while (true) {
5194                        while (a[++i] > a[right])
5195                                // find item on left to swap
5196                                ; // a[right] acts as sentinel
5197                        while (a[right] > a[--j])
5198                                // find item on right to swap
5199                                if (j == left)
5200                                        break; // don't go out-of-bounds
5201                        if (i >= j)
5202                                break; // check if pointers cross
5203                        exch(a, index, i, j); // swap two elements into place
5204                }
5205                exch(a, index, i, right); // swap with partition element
5206                return i;
5207        }
5208        
5209        
5210        /**
5211         * Sort parallel arrays. Arrays are sorted in-place. The first array
5212         * determines the order, and is sorted into descending order.
5213         * <p>
5214         * Implementation inspired by this stackoverflow page: <a href=
5215         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5216         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5217         * get-a-sorted-list-of-indices-of-an-array </a>
5218         * 
5219         * @param main
5220         *            the values to use for determining the order
5221         * @param indices
5222         *            the second array
5223         */
5224        public static void parallelQuicksortDescending(final float[] main, final int[] indices) {
5225                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
5226        }
5227
5228        /**
5229         * Sort parallel arrays. Arrays are sorted in-place. The first array
5230         * determines the order, and is sorted into descending order.
5231         * <p>
5232         * Implementation inspired by this stackoverflow page: <a href=
5233         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5234         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5235         * get-a-sorted-list-of-indices-of-an-array </a>
5236         * 
5237         * @param main
5238         *            the values to use for determining the order
5239         * @param indices
5240         *            the second array
5241         * @param left
5242         *            the starting index
5243         * @param right
5244         *            the ending index
5245         */
5246        public static void parallelQuicksortDescending(final float[] main, final int[] indices, final int left,
5247                        final int right)
5248        {
5249                if (right <= left)
5250                        return;
5251
5252                final int i = partitionDesc(main, indices, left, right);
5253
5254                parallelQuicksortDescending(main, indices, left, i - 1);
5255                parallelQuicksortDescending(main, indices, i + 1, right);
5256        }
5257
5258        // partition a[left] to a[right], assumes left < right
5259        private static int partitionDesc(final float[] a, final int[] index, final int left, final int right) {
5260                int i = left - 1;
5261                int j = right;
5262                while (true) {
5263                        while (a[++i] > a[right])
5264                                // find item on left to swap
5265                                ; // a[right] acts as sentinel
5266                        while (a[right] > a[--j])
5267                                // find item on right to swap
5268                                if (j == left)
5269                                        break; // don't go out-of-bounds
5270                        if (i >= j)
5271                                break; // check if pointers cross
5272                        exch(a, index, i, j); // swap two elements into place
5273                }
5274                exch(a, index, i, right); // swap with partition element
5275                return i;
5276        }
5277        
5278        
5279        /**
5280         * Sort parallel arrays. Arrays are sorted in-place. The first array
5281         * determines the order, and is sorted into descending order.
5282         * <p>
5283         * Implementation inspired by this stackoverflow page: <a href=
5284         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5285         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5286         * get-a-sorted-list-of-indices-of-an-array </a>
5287         * 
5288         * @param main
5289         *            the values to use for determining the order
5290         * @param indices
5291         *            the second array
5292         */
5293        public static void parallelQuicksortDescending(final float[] main, final long[] indices) {
5294                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
5295        }
5296
5297        /**
5298         * Sort parallel arrays. Arrays are sorted in-place. The first array
5299         * determines the order, and is sorted into descending order.
5300         * <p>
5301         * Implementation inspired by this stackoverflow page: <a href=
5302         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5303         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5304         * get-a-sorted-list-of-indices-of-an-array </a>
5305         * 
5306         * @param main
5307         *            the values to use for determining the order
5308         * @param indices
5309         *            the second array
5310         * @param left
5311         *            the starting index
5312         * @param right
5313         *            the ending index
5314         */
5315        public static void parallelQuicksortDescending(final float[] main, final long[] indices, final int left,
5316                        final int right)
5317        {
5318                if (right <= left)
5319                        return;
5320
5321                final int i = partitionDesc(main, indices, left, right);
5322
5323                parallelQuicksortDescending(main, indices, left, i - 1);
5324                parallelQuicksortDescending(main, indices, i + 1, right);
5325        }
5326
5327        // partition a[left] to a[right], assumes left < right
5328        private static int partitionDesc(final float[] a, final long[] index, final int left, final int right) {
5329                int i = left - 1;
5330                int j = right;
5331                while (true) {
5332                        while (a[++i] > a[right])
5333                                // find item on left to swap
5334                                ; // a[right] acts as sentinel
5335                        while (a[right] > a[--j])
5336                                // find item on right to swap
5337                                if (j == left)
5338                                        break; // don't go out-of-bounds
5339                        if (i >= j)
5340                                break; // check if pointers cross
5341                        exch(a, index, i, j); // swap two elements into place
5342                }
5343                exch(a, index, i, right); // swap with partition element
5344                return i;
5345        }
5346        
5347        
5348        /**
5349         * Sort parallel arrays. Arrays are sorted in-place. The first array
5350         * determines the order, and is sorted into descending order.
5351         * <p>
5352         * Implementation inspired by this stackoverflow page: <a href=
5353         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5354         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5355         * get-a-sorted-list-of-indices-of-an-array </a>
5356         * 
5357         * @param main
5358         *            the values to use for determining the order
5359         * @param indices
5360         *            the second array
5361         */
5362        public static void parallelQuicksortDescending(final float[] main, final byte[] indices) {
5363                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
5364        }
5365
5366        /**
5367         * Sort parallel arrays. Arrays are sorted in-place. The first array
5368         * determines the order, and is sorted into descending order.
5369         * <p>
5370         * Implementation inspired by this stackoverflow page: <a href=
5371         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5372         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5373         * get-a-sorted-list-of-indices-of-an-array </a>
5374         * 
5375         * @param main
5376         *            the values to use for determining the order
5377         * @param indices
5378         *            the second array
5379         * @param left
5380         *            the starting index
5381         * @param right
5382         *            the ending index
5383         */
5384        public static void parallelQuicksortDescending(final float[] main, final byte[] indices, final int left,
5385                        final int right)
5386        {
5387                if (right <= left)
5388                        return;
5389
5390                final int i = partitionDesc(main, indices, left, right);
5391
5392                parallelQuicksortDescending(main, indices, left, i - 1);
5393                parallelQuicksortDescending(main, indices, i + 1, right);
5394        }
5395
5396        // partition a[left] to a[right], assumes left < right
5397        private static int partitionDesc(final float[] a, final byte[] index, final int left, final int right) {
5398                int i = left - 1;
5399                int j = right;
5400                while (true) {
5401                        while (a[++i] > a[right])
5402                                // find item on left to swap
5403                                ; // a[right] acts as sentinel
5404                        while (a[right] > a[--j])
5405                                // find item on right to swap
5406                                if (j == left)
5407                                        break; // don't go out-of-bounds
5408                        if (i >= j)
5409                                break; // check if pointers cross
5410                        exch(a, index, i, j); // swap two elements into place
5411                }
5412                exch(a, index, i, right); // swap with partition element
5413                return i;
5414        }
5415        
5416        
5417        /**
5418         * Sort parallel arrays. Arrays are sorted in-place. The first array
5419         * determines the order, and is sorted into descending order.
5420         * <p>
5421         * Implementation inspired by this stackoverflow page: <a href=
5422         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5423         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5424         * get-a-sorted-list-of-indices-of-an-array </a>
5425         * 
5426         * @param main
5427         *            the values to use for determining the order
5428         * @param indices
5429         *            the second array
5430         */
5431        public static void parallelQuicksortDescending(final float[] main, final short[] indices) {
5432                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
5433        }
5434
5435        /**
5436         * Sort parallel arrays. Arrays are sorted in-place. The first array
5437         * determines the order, and is sorted into descending order.
5438         * <p>
5439         * Implementation inspired by this stackoverflow page: <a href=
5440         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5441         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5442         * get-a-sorted-list-of-indices-of-an-array </a>
5443         * 
5444         * @param main
5445         *            the values to use for determining the order
5446         * @param indices
5447         *            the second array
5448         * @param left
5449         *            the starting index
5450         * @param right
5451         *            the ending index
5452         */
5453        public static void parallelQuicksortDescending(final float[] main, final short[] indices, final int left,
5454                        final int right)
5455        {
5456                if (right <= left)
5457                        return;
5458
5459                final int i = partitionDesc(main, indices, left, right);
5460
5461                parallelQuicksortDescending(main, indices, left, i - 1);
5462                parallelQuicksortDescending(main, indices, i + 1, right);
5463        }
5464
5465        // partition a[left] to a[right], assumes left < right
5466        private static int partitionDesc(final float[] a, final short[] index, final int left, final int right) {
5467                int i = left - 1;
5468                int j = right;
5469                while (true) {
5470                        while (a[++i] > a[right])
5471                                // find item on left to swap
5472                                ; // a[right] acts as sentinel
5473                        while (a[right] > a[--j])
5474                                // find item on right to swap
5475                                if (j == left)
5476                                        break; // don't go out-of-bounds
5477                        if (i >= j)
5478                                break; // check if pointers cross
5479                        exch(a, index, i, j); // swap two elements into place
5480                }
5481                exch(a, index, i, right); // swap with partition element
5482                return i;
5483        }
5484        
5485        
5486        /**
5487         * Sort parallel arrays. Arrays are sorted in-place. The first array
5488         * determines the order, and is sorted into descending order.
5489         * <p>
5490         * Implementation inspired by this stackoverflow page: <a href=
5491         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5492         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5493         * get-a-sorted-list-of-indices-of-an-array </a>
5494         * 
5495         * @param main
5496         *            the values to use for determining the order
5497         * @param indices
5498         *            the second array
5499         */
5500        public static void parallelQuicksortDescending(final int[] main, final double[] indices) {
5501                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
5502        }
5503
5504        /**
5505         * Sort parallel arrays. Arrays are sorted in-place. The first array
5506         * determines the order, and is sorted into descending order.
5507         * <p>
5508         * Implementation inspired by this stackoverflow page: <a href=
5509         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5510         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5511         * get-a-sorted-list-of-indices-of-an-array </a>
5512         * 
5513         * @param main
5514         *            the values to use for determining the order
5515         * @param indices
5516         *            the second array
5517         * @param left
5518         *            the starting index
5519         * @param right
5520         *            the ending index
5521         */
5522        public static void parallelQuicksortDescending(final int[] main, final double[] indices, final int left,
5523                        final int right)
5524        {
5525                if (right <= left)
5526                        return;
5527
5528                final int i = partitionDesc(main, indices, left, right);
5529
5530                parallelQuicksortDescending(main, indices, left, i - 1);
5531                parallelQuicksortDescending(main, indices, i + 1, right);
5532        }
5533
5534        // partition a[left] to a[right], assumes left < right
5535        private static int partitionDesc(final int[] a, final double[] index, final int left, final int right) {
5536                int i = left - 1;
5537                int j = right;
5538                while (true) {
5539                        while (a[++i] > a[right])
5540                                // find item on left to swap
5541                                ; // a[right] acts as sentinel
5542                        while (a[right] > a[--j])
5543                                // find item on right to swap
5544                                if (j == left)
5545                                        break; // don't go out-of-bounds
5546                        if (i >= j)
5547                                break; // check if pointers cross
5548                        exch(a, index, i, j); // swap two elements into place
5549                }
5550                exch(a, index, i, right); // swap with partition element
5551                return i;
5552        }
5553        
5554        
5555        /**
5556         * Sort parallel arrays. Arrays are sorted in-place. The first array
5557         * determines the order, and is sorted into descending order.
5558         * <p>
5559         * Implementation inspired by this stackoverflow page: <a href=
5560         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5561         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5562         * get-a-sorted-list-of-indices-of-an-array </a>
5563         * 
5564         * @param main
5565         *            the values to use for determining the order
5566         * @param indices
5567         *            the second array
5568         */
5569        public static void parallelQuicksortDescending(final int[] main, final float[] indices) {
5570                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
5571        }
5572
5573        /**
5574         * Sort parallel arrays. Arrays are sorted in-place. The first array
5575         * determines the order, and is sorted into descending order.
5576         * <p>
5577         * Implementation inspired by this stackoverflow page: <a href=
5578         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5579         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5580         * get-a-sorted-list-of-indices-of-an-array </a>
5581         * 
5582         * @param main
5583         *            the values to use for determining the order
5584         * @param indices
5585         *            the second array
5586         * @param left
5587         *            the starting index
5588         * @param right
5589         *            the ending index
5590         */
5591        public static void parallelQuicksortDescending(final int[] main, final float[] indices, final int left,
5592                        final int right)
5593        {
5594                if (right <= left)
5595                        return;
5596
5597                final int i = partitionDesc(main, indices, left, right);
5598
5599                parallelQuicksortDescending(main, indices, left, i - 1);
5600                parallelQuicksortDescending(main, indices, i + 1, right);
5601        }
5602
5603        // partition a[left] to a[right], assumes left < right
5604        private static int partitionDesc(final int[] a, final float[] index, final int left, final int right) {
5605                int i = left - 1;
5606                int j = right;
5607                while (true) {
5608                        while (a[++i] > a[right])
5609                                // find item on left to swap
5610                                ; // a[right] acts as sentinel
5611                        while (a[right] > a[--j])
5612                                // find item on right to swap
5613                                if (j == left)
5614                                        break; // don't go out-of-bounds
5615                        if (i >= j)
5616                                break; // check if pointers cross
5617                        exch(a, index, i, j); // swap two elements into place
5618                }
5619                exch(a, index, i, right); // swap with partition element
5620                return i;
5621        }
5622        
5623        
5624        /**
5625         * Sort parallel arrays. Arrays are sorted in-place. The first array
5626         * determines the order, and is sorted into descending order.
5627         * <p>
5628         * Implementation inspired by this stackoverflow page: <a href=
5629         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5630         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5631         * get-a-sorted-list-of-indices-of-an-array </a>
5632         * 
5633         * @param main
5634         *            the values to use for determining the order
5635         * @param indices
5636         *            the second array
5637         */
5638        public static void parallelQuicksortDescending(final int[] main, final int[] indices) {
5639                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
5640        }
5641
5642        /**
5643         * Sort parallel arrays. Arrays are sorted in-place. The first array
5644         * determines the order, and is sorted into descending order.
5645         * <p>
5646         * Implementation inspired by this stackoverflow page: <a href=
5647         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5648         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5649         * get-a-sorted-list-of-indices-of-an-array </a>
5650         * 
5651         * @param main
5652         *            the values to use for determining the order
5653         * @param indices
5654         *            the second array
5655         * @param left
5656         *            the starting index
5657         * @param right
5658         *            the ending index
5659         */
5660        public static void parallelQuicksortDescending(final int[] main, final int[] indices, final int left,
5661                        final int right)
5662        {
5663                if (right <= left)
5664                        return;
5665
5666                final int i = partitionDesc(main, indices, left, right);
5667
5668                parallelQuicksortDescending(main, indices, left, i - 1);
5669                parallelQuicksortDescending(main, indices, i + 1, right);
5670        }
5671
5672        // partition a[left] to a[right], assumes left < right
5673        private static int partitionDesc(final int[] a, final int[] index, final int left, final int right) {
5674                int i = left - 1;
5675                int j = right;
5676                while (true) {
5677                        while (a[++i] > a[right])
5678                                // find item on left to swap
5679                                ; // a[right] acts as sentinel
5680                        while (a[right] > a[--j])
5681                                // find item on right to swap
5682                                if (j == left)
5683                                        break; // don't go out-of-bounds
5684                        if (i >= j)
5685                                break; // check if pointers cross
5686                        exch(a, index, i, j); // swap two elements into place
5687                }
5688                exch(a, index, i, right); // swap with partition element
5689                return i;
5690        }
5691        
5692        
5693        /**
5694         * Sort parallel arrays. Arrays are sorted in-place. The first array
5695         * determines the order, and is sorted into descending order.
5696         * <p>
5697         * Implementation inspired by this stackoverflow page: <a href=
5698         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5699         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5700         * get-a-sorted-list-of-indices-of-an-array </a>
5701         * 
5702         * @param main
5703         *            the values to use for determining the order
5704         * @param indices
5705         *            the second array
5706         */
5707        public static void parallelQuicksortDescending(final int[] main, final long[] indices) {
5708                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
5709        }
5710
5711        /**
5712         * Sort parallel arrays. Arrays are sorted in-place. The first array
5713         * determines the order, and is sorted into descending order.
5714         * <p>
5715         * Implementation inspired by this stackoverflow page: <a href=
5716         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5717         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5718         * get-a-sorted-list-of-indices-of-an-array </a>
5719         * 
5720         * @param main
5721         *            the values to use for determining the order
5722         * @param indices
5723         *            the second array
5724         * @param left
5725         *            the starting index
5726         * @param right
5727         *            the ending index
5728         */
5729        public static void parallelQuicksortDescending(final int[] main, final long[] indices, final int left,
5730                        final int right)
5731        {
5732                if (right <= left)
5733                        return;
5734
5735                final int i = partitionDesc(main, indices, left, right);
5736
5737                parallelQuicksortDescending(main, indices, left, i - 1);
5738                parallelQuicksortDescending(main, indices, i + 1, right);
5739        }
5740
5741        // partition a[left] to a[right], assumes left < right
5742        private static int partitionDesc(final int[] a, final long[] index, final int left, final int right) {
5743                int i = left - 1;
5744                int j = right;
5745                while (true) {
5746                        while (a[++i] > a[right])
5747                                // find item on left to swap
5748                                ; // a[right] acts as sentinel
5749                        while (a[right] > a[--j])
5750                                // find item on right to swap
5751                                if (j == left)
5752                                        break; // don't go out-of-bounds
5753                        if (i >= j)
5754                                break; // check if pointers cross
5755                        exch(a, index, i, j); // swap two elements into place
5756                }
5757                exch(a, index, i, right); // swap with partition element
5758                return i;
5759        }
5760        
5761        
5762        /**
5763         * Sort parallel arrays. Arrays are sorted in-place. The first array
5764         * determines the order, and is sorted into descending order.
5765         * <p>
5766         * Implementation inspired by this stackoverflow page: <a href=
5767         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5768         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5769         * get-a-sorted-list-of-indices-of-an-array </a>
5770         * 
5771         * @param main
5772         *            the values to use for determining the order
5773         * @param indices
5774         *            the second array
5775         */
5776        public static void parallelQuicksortDescending(final int[] main, final byte[] indices) {
5777                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
5778        }
5779
5780        /**
5781         * Sort parallel arrays. Arrays are sorted in-place. The first array
5782         * determines the order, and is sorted into descending order.
5783         * <p>
5784         * Implementation inspired by this stackoverflow page: <a href=
5785         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5786         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5787         * get-a-sorted-list-of-indices-of-an-array </a>
5788         * 
5789         * @param main
5790         *            the values to use for determining the order
5791         * @param indices
5792         *            the second array
5793         * @param left
5794         *            the starting index
5795         * @param right
5796         *            the ending index
5797         */
5798        public static void parallelQuicksortDescending(final int[] main, final byte[] indices, final int left,
5799                        final int right)
5800        {
5801                if (right <= left)
5802                        return;
5803
5804                final int i = partitionDesc(main, indices, left, right);
5805
5806                parallelQuicksortDescending(main, indices, left, i - 1);
5807                parallelQuicksortDescending(main, indices, i + 1, right);
5808        }
5809
5810        // partition a[left] to a[right], assumes left < right
5811        private static int partitionDesc(final int[] a, final byte[] index, final int left, final int right) {
5812                int i = left - 1;
5813                int j = right;
5814                while (true) {
5815                        while (a[++i] > a[right])
5816                                // find item on left to swap
5817                                ; // a[right] acts as sentinel
5818                        while (a[right] > a[--j])
5819                                // find item on right to swap
5820                                if (j == left)
5821                                        break; // don't go out-of-bounds
5822                        if (i >= j)
5823                                break; // check if pointers cross
5824                        exch(a, index, i, j); // swap two elements into place
5825                }
5826                exch(a, index, i, right); // swap with partition element
5827                return i;
5828        }
5829        
5830        
5831        /**
5832         * Sort parallel arrays. Arrays are sorted in-place. The first array
5833         * determines the order, and is sorted into descending order.
5834         * <p>
5835         * Implementation inspired by this stackoverflow page: <a href=
5836         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5837         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5838         * get-a-sorted-list-of-indices-of-an-array </a>
5839         * 
5840         * @param main
5841         *            the values to use for determining the order
5842         * @param indices
5843         *            the second array
5844         */
5845        public static void parallelQuicksortDescending(final int[] main, final short[] indices) {
5846                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
5847        }
5848
5849        /**
5850         * Sort parallel arrays. Arrays are sorted in-place. The first array
5851         * determines the order, and is sorted into descending order.
5852         * <p>
5853         * Implementation inspired by this stackoverflow page: <a href=
5854         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5855         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5856         * get-a-sorted-list-of-indices-of-an-array </a>
5857         * 
5858         * @param main
5859         *            the values to use for determining the order
5860         * @param indices
5861         *            the second array
5862         * @param left
5863         *            the starting index
5864         * @param right
5865         *            the ending index
5866         */
5867        public static void parallelQuicksortDescending(final int[] main, final short[] indices, final int left,
5868                        final int right)
5869        {
5870                if (right <= left)
5871                        return;
5872
5873                final int i = partitionDesc(main, indices, left, right);
5874
5875                parallelQuicksortDescending(main, indices, left, i - 1);
5876                parallelQuicksortDescending(main, indices, i + 1, right);
5877        }
5878
5879        // partition a[left] to a[right], assumes left < right
5880        private static int partitionDesc(final int[] a, final short[] index, final int left, final int right) {
5881                int i = left - 1;
5882                int j = right;
5883                while (true) {
5884                        while (a[++i] > a[right])
5885                                // find item on left to swap
5886                                ; // a[right] acts as sentinel
5887                        while (a[right] > a[--j])
5888                                // find item on right to swap
5889                                if (j == left)
5890                                        break; // don't go out-of-bounds
5891                        if (i >= j)
5892                                break; // check if pointers cross
5893                        exch(a, index, i, j); // swap two elements into place
5894                }
5895                exch(a, index, i, right); // swap with partition element
5896                return i;
5897        }
5898        
5899        
5900        /**
5901         * Sort parallel arrays. Arrays are sorted in-place. The first array
5902         * determines the order, and is sorted into descending order.
5903         * <p>
5904         * Implementation inspired by this stackoverflow page: <a href=
5905         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5906         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5907         * get-a-sorted-list-of-indices-of-an-array </a>
5908         * 
5909         * @param main
5910         *            the values to use for determining the order
5911         * @param indices
5912         *            the second array
5913         */
5914        public static void parallelQuicksortDescending(final long[] main, final double[] indices) {
5915                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
5916        }
5917
5918        /**
5919         * Sort parallel arrays. Arrays are sorted in-place. The first array
5920         * determines the order, and is sorted into descending order.
5921         * <p>
5922         * Implementation inspired by this stackoverflow page: <a href=
5923         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5924         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5925         * get-a-sorted-list-of-indices-of-an-array </a>
5926         * 
5927         * @param main
5928         *            the values to use for determining the order
5929         * @param indices
5930         *            the second array
5931         * @param left
5932         *            the starting index
5933         * @param right
5934         *            the ending index
5935         */
5936        public static void parallelQuicksortDescending(final long[] main, final double[] indices, final int left,
5937                        final int right)
5938        {
5939                if (right <= left)
5940                        return;
5941
5942                final int i = partitionDesc(main, indices, left, right);
5943
5944                parallelQuicksortDescending(main, indices, left, i - 1);
5945                parallelQuicksortDescending(main, indices, i + 1, right);
5946        }
5947
5948        // partition a[left] to a[right], assumes left < right
5949        private static int partitionDesc(final long[] a, final double[] index, final int left, final int right) {
5950                int i = left - 1;
5951                int j = right;
5952                while (true) {
5953                        while (a[++i] > a[right])
5954                                // find item on left to swap
5955                                ; // a[right] acts as sentinel
5956                        while (a[right] > a[--j])
5957                                // find item on right to swap
5958                                if (j == left)
5959                                        break; // don't go out-of-bounds
5960                        if (i >= j)
5961                                break; // check if pointers cross
5962                        exch(a, index, i, j); // swap two elements into place
5963                }
5964                exch(a, index, i, right); // swap with partition element
5965                return i;
5966        }
5967        
5968        
5969        /**
5970         * Sort parallel arrays. Arrays are sorted in-place. The first array
5971         * determines the order, and is sorted into descending order.
5972         * <p>
5973         * Implementation inspired by this stackoverflow page: <a href=
5974         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5975         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5976         * get-a-sorted-list-of-indices-of-an-array </a>
5977         * 
5978         * @param main
5979         *            the values to use for determining the order
5980         * @param indices
5981         *            the second array
5982         */
5983        public static void parallelQuicksortDescending(final long[] main, final float[] indices) {
5984                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
5985        }
5986
5987        /**
5988         * Sort parallel arrays. Arrays are sorted in-place. The first array
5989         * determines the order, and is sorted into descending order.
5990         * <p>
5991         * Implementation inspired by this stackoverflow page: <a href=
5992         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
5993         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
5994         * get-a-sorted-list-of-indices-of-an-array </a>
5995         * 
5996         * @param main
5997         *            the values to use for determining the order
5998         * @param indices
5999         *            the second array
6000         * @param left
6001         *            the starting index
6002         * @param right
6003         *            the ending index
6004         */
6005        public static void parallelQuicksortDescending(final long[] main, final float[] indices, final int left,
6006                        final int right)
6007        {
6008                if (right <= left)
6009                        return;
6010
6011                final int i = partitionDesc(main, indices, left, right);
6012
6013                parallelQuicksortDescending(main, indices, left, i - 1);
6014                parallelQuicksortDescending(main, indices, i + 1, right);
6015        }
6016
6017        // partition a[left] to a[right], assumes left < right
6018        private static int partitionDesc(final long[] a, final float[] index, final int left, final int right) {
6019                int i = left - 1;
6020                int j = right;
6021                while (true) {
6022                        while (a[++i] > a[right])
6023                                // find item on left to swap
6024                                ; // a[right] acts as sentinel
6025                        while (a[right] > a[--j])
6026                                // find item on right to swap
6027                                if (j == left)
6028                                        break; // don't go out-of-bounds
6029                        if (i >= j)
6030                                break; // check if pointers cross
6031                        exch(a, index, i, j); // swap two elements into place
6032                }
6033                exch(a, index, i, right); // swap with partition element
6034                return i;
6035        }
6036        
6037        
6038        /**
6039         * Sort parallel arrays. Arrays are sorted in-place. The first array
6040         * determines the order, and is sorted into descending order.
6041         * <p>
6042         * Implementation inspired by this stackoverflow page: <a href=
6043         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6044         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6045         * get-a-sorted-list-of-indices-of-an-array </a>
6046         * 
6047         * @param main
6048         *            the values to use for determining the order
6049         * @param indices
6050         *            the second array
6051         */
6052        public static void parallelQuicksortDescending(final long[] main, final int[] indices) {
6053                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
6054        }
6055
6056        /**
6057         * Sort parallel arrays. Arrays are sorted in-place. The first array
6058         * determines the order, and is sorted into descending order.
6059         * <p>
6060         * Implementation inspired by this stackoverflow page: <a href=
6061         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6062         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6063         * get-a-sorted-list-of-indices-of-an-array </a>
6064         * 
6065         * @param main
6066         *            the values to use for determining the order
6067         * @param indices
6068         *            the second array
6069         * @param left
6070         *            the starting index
6071         * @param right
6072         *            the ending index
6073         */
6074        public static void parallelQuicksortDescending(final long[] main, final int[] indices, final int left,
6075                        final int right)
6076        {
6077                if (right <= left)
6078                        return;
6079
6080                final int i = partitionDesc(main, indices, left, right);
6081
6082                parallelQuicksortDescending(main, indices, left, i - 1);
6083                parallelQuicksortDescending(main, indices, i + 1, right);
6084        }
6085
6086        // partition a[left] to a[right], assumes left < right
6087        private static int partitionDesc(final long[] a, final int[] index, final int left, final int right) {
6088                int i = left - 1;
6089                int j = right;
6090                while (true) {
6091                        while (a[++i] > a[right])
6092                                // find item on left to swap
6093                                ; // a[right] acts as sentinel
6094                        while (a[right] > a[--j])
6095                                // find item on right to swap
6096                                if (j == left)
6097                                        break; // don't go out-of-bounds
6098                        if (i >= j)
6099                                break; // check if pointers cross
6100                        exch(a, index, i, j); // swap two elements into place
6101                }
6102                exch(a, index, i, right); // swap with partition element
6103                return i;
6104        }
6105        
6106        
6107        /**
6108         * Sort parallel arrays. Arrays are sorted in-place. The first array
6109         * determines the order, and is sorted into descending order.
6110         * <p>
6111         * Implementation inspired by this stackoverflow page: <a href=
6112         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6113         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6114         * get-a-sorted-list-of-indices-of-an-array </a>
6115         * 
6116         * @param main
6117         *            the values to use for determining the order
6118         * @param indices
6119         *            the second array
6120         */
6121        public static void parallelQuicksortDescending(final long[] main, final long[] indices) {
6122                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
6123        }
6124
6125        /**
6126         * Sort parallel arrays. Arrays are sorted in-place. The first array
6127         * determines the order, and is sorted into descending order.
6128         * <p>
6129         * Implementation inspired by this stackoverflow page: <a href=
6130         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6131         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6132         * get-a-sorted-list-of-indices-of-an-array </a>
6133         * 
6134         * @param main
6135         *            the values to use for determining the order
6136         * @param indices
6137         *            the second array
6138         * @param left
6139         *            the starting index
6140         * @param right
6141         *            the ending index
6142         */
6143        public static void parallelQuicksortDescending(final long[] main, final long[] indices, final int left,
6144                        final int right)
6145        {
6146                if (right <= left)
6147                        return;
6148
6149                final int i = partitionDesc(main, indices, left, right);
6150
6151                parallelQuicksortDescending(main, indices, left, i - 1);
6152                parallelQuicksortDescending(main, indices, i + 1, right);
6153        }
6154
6155        // partition a[left] to a[right], assumes left < right
6156        private static int partitionDesc(final long[] a, final long[] index, final int left, final int right) {
6157                int i = left - 1;
6158                int j = right;
6159                while (true) {
6160                        while (a[++i] > a[right])
6161                                // find item on left to swap
6162                                ; // a[right] acts as sentinel
6163                        while (a[right] > a[--j])
6164                                // find item on right to swap
6165                                if (j == left)
6166                                        break; // don't go out-of-bounds
6167                        if (i >= j)
6168                                break; // check if pointers cross
6169                        exch(a, index, i, j); // swap two elements into place
6170                }
6171                exch(a, index, i, right); // swap with partition element
6172                return i;
6173        }
6174        
6175        
6176        /**
6177         * Sort parallel arrays. Arrays are sorted in-place. The first array
6178         * determines the order, and is sorted into descending order.
6179         * <p>
6180         * Implementation inspired by this stackoverflow page: <a href=
6181         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6182         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6183         * get-a-sorted-list-of-indices-of-an-array </a>
6184         * 
6185         * @param main
6186         *            the values to use for determining the order
6187         * @param indices
6188         *            the second array
6189         */
6190        public static void parallelQuicksortDescending(final long[] main, final byte[] indices) {
6191                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
6192        }
6193
6194        /**
6195         * Sort parallel arrays. Arrays are sorted in-place. The first array
6196         * determines the order, and is sorted into descending order.
6197         * <p>
6198         * Implementation inspired by this stackoverflow page: <a href=
6199         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6200         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6201         * get-a-sorted-list-of-indices-of-an-array </a>
6202         * 
6203         * @param main
6204         *            the values to use for determining the order
6205         * @param indices
6206         *            the second array
6207         * @param left
6208         *            the starting index
6209         * @param right
6210         *            the ending index
6211         */
6212        public static void parallelQuicksortDescending(final long[] main, final byte[] indices, final int left,
6213                        final int right)
6214        {
6215                if (right <= left)
6216                        return;
6217
6218                final int i = partitionDesc(main, indices, left, right);
6219
6220                parallelQuicksortDescending(main, indices, left, i - 1);
6221                parallelQuicksortDescending(main, indices, i + 1, right);
6222        }
6223
6224        // partition a[left] to a[right], assumes left < right
6225        private static int partitionDesc(final long[] a, final byte[] index, final int left, final int right) {
6226                int i = left - 1;
6227                int j = right;
6228                while (true) {
6229                        while (a[++i] > a[right])
6230                                // find item on left to swap
6231                                ; // a[right] acts as sentinel
6232                        while (a[right] > a[--j])
6233                                // find item on right to swap
6234                                if (j == left)
6235                                        break; // don't go out-of-bounds
6236                        if (i >= j)
6237                                break; // check if pointers cross
6238                        exch(a, index, i, j); // swap two elements into place
6239                }
6240                exch(a, index, i, right); // swap with partition element
6241                return i;
6242        }
6243        
6244        
6245        /**
6246         * Sort parallel arrays. Arrays are sorted in-place. The first array
6247         * determines the order, and is sorted into descending order.
6248         * <p>
6249         * Implementation inspired by this stackoverflow page: <a href=
6250         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6251         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6252         * get-a-sorted-list-of-indices-of-an-array </a>
6253         * 
6254         * @param main
6255         *            the values to use for determining the order
6256         * @param indices
6257         *            the second array
6258         */
6259        public static void parallelQuicksortDescending(final long[] main, final short[] indices) {
6260                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
6261        }
6262
6263        /**
6264         * Sort parallel arrays. Arrays are sorted in-place. The first array
6265         * determines the order, and is sorted into descending order.
6266         * <p>
6267         * Implementation inspired by this stackoverflow page: <a href=
6268         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6269         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6270         * get-a-sorted-list-of-indices-of-an-array </a>
6271         * 
6272         * @param main
6273         *            the values to use for determining the order
6274         * @param indices
6275         *            the second array
6276         * @param left
6277         *            the starting index
6278         * @param right
6279         *            the ending index
6280         */
6281        public static void parallelQuicksortDescending(final long[] main, final short[] indices, final int left,
6282                        final int right)
6283        {
6284                if (right <= left)
6285                        return;
6286
6287                final int i = partitionDesc(main, indices, left, right);
6288
6289                parallelQuicksortDescending(main, indices, left, i - 1);
6290                parallelQuicksortDescending(main, indices, i + 1, right);
6291        }
6292
6293        // partition a[left] to a[right], assumes left < right
6294        private static int partitionDesc(final long[] a, final short[] index, final int left, final int right) {
6295                int i = left - 1;
6296                int j = right;
6297                while (true) {
6298                        while (a[++i] > a[right])
6299                                // find item on left to swap
6300                                ; // a[right] acts as sentinel
6301                        while (a[right] > a[--j])
6302                                // find item on right to swap
6303                                if (j == left)
6304                                        break; // don't go out-of-bounds
6305                        if (i >= j)
6306                                break; // check if pointers cross
6307                        exch(a, index, i, j); // swap two elements into place
6308                }
6309                exch(a, index, i, right); // swap with partition element
6310                return i;
6311        }
6312        
6313        
6314        /**
6315         * Sort parallel arrays. Arrays are sorted in-place. The first array
6316         * determines the order, and is sorted into descending order.
6317         * <p>
6318         * Implementation inspired by this stackoverflow page: <a href=
6319         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6320         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6321         * get-a-sorted-list-of-indices-of-an-array </a>
6322         * 
6323         * @param main
6324         *            the values to use for determining the order
6325         * @param indices
6326         *            the second array
6327         */
6328        public static void parallelQuicksortDescending(final byte[] main, final double[] indices) {
6329                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
6330        }
6331
6332        /**
6333         * Sort parallel arrays. Arrays are sorted in-place. The first array
6334         * determines the order, and is sorted into descending order.
6335         * <p>
6336         * Implementation inspired by this stackoverflow page: <a href=
6337         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6338         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6339         * get-a-sorted-list-of-indices-of-an-array </a>
6340         * 
6341         * @param main
6342         *            the values to use for determining the order
6343         * @param indices
6344         *            the second array
6345         * @param left
6346         *            the starting index
6347         * @param right
6348         *            the ending index
6349         */
6350        public static void parallelQuicksortDescending(final byte[] main, final double[] indices, final int left,
6351                        final int right)
6352        {
6353                if (right <= left)
6354                        return;
6355
6356                final int i = partitionDesc(main, indices, left, right);
6357
6358                parallelQuicksortDescending(main, indices, left, i - 1);
6359                parallelQuicksortDescending(main, indices, i + 1, right);
6360        }
6361
6362        // partition a[left] to a[right], assumes left < right
6363        private static int partitionDesc(final byte[] a, final double[] index, final int left, final int right) {
6364                int i = left - 1;
6365                int j = right;
6366                while (true) {
6367                        while (a[++i] > a[right])
6368                                // find item on left to swap
6369                                ; // a[right] acts as sentinel
6370                        while (a[right] > a[--j])
6371                                // find item on right to swap
6372                                if (j == left)
6373                                        break; // don't go out-of-bounds
6374                        if (i >= j)
6375                                break; // check if pointers cross
6376                        exch(a, index, i, j); // swap two elements into place
6377                }
6378                exch(a, index, i, right); // swap with partition element
6379                return i;
6380        }
6381        
6382        
6383        /**
6384         * Sort parallel arrays. Arrays are sorted in-place. The first array
6385         * determines the order, and is sorted into descending order.
6386         * <p>
6387         * Implementation inspired by this stackoverflow page: <a href=
6388         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6389         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6390         * get-a-sorted-list-of-indices-of-an-array </a>
6391         * 
6392         * @param main
6393         *            the values to use for determining the order
6394         * @param indices
6395         *            the second array
6396         */
6397        public static void parallelQuicksortDescending(final byte[] main, final float[] indices) {
6398                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
6399        }
6400
6401        /**
6402         * Sort parallel arrays. Arrays are sorted in-place. The first array
6403         * determines the order, and is sorted into descending order.
6404         * <p>
6405         * Implementation inspired by this stackoverflow page: <a href=
6406         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6407         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6408         * get-a-sorted-list-of-indices-of-an-array </a>
6409         * 
6410         * @param main
6411         *            the values to use for determining the order
6412         * @param indices
6413         *            the second array
6414         * @param left
6415         *            the starting index
6416         * @param right
6417         *            the ending index
6418         */
6419        public static void parallelQuicksortDescending(final byte[] main, final float[] indices, final int left,
6420                        final int right)
6421        {
6422                if (right <= left)
6423                        return;
6424
6425                final int i = partitionDesc(main, indices, left, right);
6426
6427                parallelQuicksortDescending(main, indices, left, i - 1);
6428                parallelQuicksortDescending(main, indices, i + 1, right);
6429        }
6430
6431        // partition a[left] to a[right], assumes left < right
6432        private static int partitionDesc(final byte[] a, final float[] index, final int left, final int right) {
6433                int i = left - 1;
6434                int j = right;
6435                while (true) {
6436                        while (a[++i] > a[right])
6437                                // find item on left to swap
6438                                ; // a[right] acts as sentinel
6439                        while (a[right] > a[--j])
6440                                // find item on right to swap
6441                                if (j == left)
6442                                        break; // don't go out-of-bounds
6443                        if (i >= j)
6444                                break; // check if pointers cross
6445                        exch(a, index, i, j); // swap two elements into place
6446                }
6447                exch(a, index, i, right); // swap with partition element
6448                return i;
6449        }
6450        
6451        
6452        /**
6453         * Sort parallel arrays. Arrays are sorted in-place. The first array
6454         * determines the order, and is sorted into descending order.
6455         * <p>
6456         * Implementation inspired by this stackoverflow page: <a href=
6457         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6458         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6459         * get-a-sorted-list-of-indices-of-an-array </a>
6460         * 
6461         * @param main
6462         *            the values to use for determining the order
6463         * @param indices
6464         *            the second array
6465         */
6466        public static void parallelQuicksortDescending(final byte[] main, final int[] indices) {
6467                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
6468        }
6469
6470        /**
6471         * Sort parallel arrays. Arrays are sorted in-place. The first array
6472         * determines the order, and is sorted into descending order.
6473         * <p>
6474         * Implementation inspired by this stackoverflow page: <a href=
6475         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6476         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6477         * get-a-sorted-list-of-indices-of-an-array </a>
6478         * 
6479         * @param main
6480         *            the values to use for determining the order
6481         * @param indices
6482         *            the second array
6483         * @param left
6484         *            the starting index
6485         * @param right
6486         *            the ending index
6487         */
6488        public static void parallelQuicksortDescending(final byte[] main, final int[] indices, final int left,
6489                        final int right)
6490        {
6491                if (right <= left)
6492                        return;
6493
6494                final int i = partitionDesc(main, indices, left, right);
6495
6496                parallelQuicksortDescending(main, indices, left, i - 1);
6497                parallelQuicksortDescending(main, indices, i + 1, right);
6498        }
6499
6500        // partition a[left] to a[right], assumes left < right
6501        private static int partitionDesc(final byte[] a, final int[] index, final int left, final int right) {
6502                int i = left - 1;
6503                int j = right;
6504                while (true) {
6505                        while (a[++i] > a[right])
6506                                // find item on left to swap
6507                                ; // a[right] acts as sentinel
6508                        while (a[right] > a[--j])
6509                                // find item on right to swap
6510                                if (j == left)
6511                                        break; // don't go out-of-bounds
6512                        if (i >= j)
6513                                break; // check if pointers cross
6514                        exch(a, index, i, j); // swap two elements into place
6515                }
6516                exch(a, index, i, right); // swap with partition element
6517                return i;
6518        }
6519        
6520        
6521        /**
6522         * Sort parallel arrays. Arrays are sorted in-place. The first array
6523         * determines the order, and is sorted into descending order.
6524         * <p>
6525         * Implementation inspired by this stackoverflow page: <a href=
6526         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6527         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6528         * get-a-sorted-list-of-indices-of-an-array </a>
6529         * 
6530         * @param main
6531         *            the values to use for determining the order
6532         * @param indices
6533         *            the second array
6534         */
6535        public static void parallelQuicksortDescending(final byte[] main, final long[] indices) {
6536                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
6537        }
6538
6539        /**
6540         * Sort parallel arrays. Arrays are sorted in-place. The first array
6541         * determines the order, and is sorted into descending order.
6542         * <p>
6543         * Implementation inspired by this stackoverflow page: <a href=
6544         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6545         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6546         * get-a-sorted-list-of-indices-of-an-array </a>
6547         * 
6548         * @param main
6549         *            the values to use for determining the order
6550         * @param indices
6551         *            the second array
6552         * @param left
6553         *            the starting index
6554         * @param right
6555         *            the ending index
6556         */
6557        public static void parallelQuicksortDescending(final byte[] main, final long[] indices, final int left,
6558                        final int right)
6559        {
6560                if (right <= left)
6561                        return;
6562
6563                final int i = partitionDesc(main, indices, left, right);
6564
6565                parallelQuicksortDescending(main, indices, left, i - 1);
6566                parallelQuicksortDescending(main, indices, i + 1, right);
6567        }
6568
6569        // partition a[left] to a[right], assumes left < right
6570        private static int partitionDesc(final byte[] a, final long[] index, final int left, final int right) {
6571                int i = left - 1;
6572                int j = right;
6573                while (true) {
6574                        while (a[++i] > a[right])
6575                                // find item on left to swap
6576                                ; // a[right] acts as sentinel
6577                        while (a[right] > a[--j])
6578                                // find item on right to swap
6579                                if (j == left)
6580                                        break; // don't go out-of-bounds
6581                        if (i >= j)
6582                                break; // check if pointers cross
6583                        exch(a, index, i, j); // swap two elements into place
6584                }
6585                exch(a, index, i, right); // swap with partition element
6586                return i;
6587        }
6588        
6589        
6590        /**
6591         * Sort parallel arrays. Arrays are sorted in-place. The first array
6592         * determines the order, and is sorted into descending order.
6593         * <p>
6594         * Implementation inspired by this stackoverflow page: <a href=
6595         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6596         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6597         * get-a-sorted-list-of-indices-of-an-array </a>
6598         * 
6599         * @param main
6600         *            the values to use for determining the order
6601         * @param indices
6602         *            the second array
6603         */
6604        public static void parallelQuicksortDescending(final byte[] main, final byte[] indices) {
6605                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
6606        }
6607
6608        /**
6609         * Sort parallel arrays. Arrays are sorted in-place. The first array
6610         * determines the order, and is sorted into descending order.
6611         * <p>
6612         * Implementation inspired by this stackoverflow page: <a href=
6613         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6614         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6615         * get-a-sorted-list-of-indices-of-an-array </a>
6616         * 
6617         * @param main
6618         *            the values to use for determining the order
6619         * @param indices
6620         *            the second array
6621         * @param left
6622         *            the starting index
6623         * @param right
6624         *            the ending index
6625         */
6626        public static void parallelQuicksortDescending(final byte[] main, final byte[] indices, final int left,
6627                        final int right)
6628        {
6629                if (right <= left)
6630                        return;
6631
6632                final int i = partitionDesc(main, indices, left, right);
6633
6634                parallelQuicksortDescending(main, indices, left, i - 1);
6635                parallelQuicksortDescending(main, indices, i + 1, right);
6636        }
6637
6638        // partition a[left] to a[right], assumes left < right
6639        private static int partitionDesc(final byte[] a, final byte[] index, final int left, final int right) {
6640                int i = left - 1;
6641                int j = right;
6642                while (true) {
6643                        while (a[++i] > a[right])
6644                                // find item on left to swap
6645                                ; // a[right] acts as sentinel
6646                        while (a[right] > a[--j])
6647                                // find item on right to swap
6648                                if (j == left)
6649                                        break; // don't go out-of-bounds
6650                        if (i >= j)
6651                                break; // check if pointers cross
6652                        exch(a, index, i, j); // swap two elements into place
6653                }
6654                exch(a, index, i, right); // swap with partition element
6655                return i;
6656        }
6657        
6658        
6659        /**
6660         * Sort parallel arrays. Arrays are sorted in-place. The first array
6661         * determines the order, and is sorted into descending order.
6662         * <p>
6663         * Implementation inspired by this stackoverflow page: <a href=
6664         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6665         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6666         * get-a-sorted-list-of-indices-of-an-array </a>
6667         * 
6668         * @param main
6669         *            the values to use for determining the order
6670         * @param indices
6671         *            the second array
6672         */
6673        public static void parallelQuicksortDescending(final byte[] main, final short[] indices) {
6674                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
6675        }
6676
6677        /**
6678         * Sort parallel arrays. Arrays are sorted in-place. The first array
6679         * determines the order, and is sorted into descending order.
6680         * <p>
6681         * Implementation inspired by this stackoverflow page: <a href=
6682         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6683         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6684         * get-a-sorted-list-of-indices-of-an-array </a>
6685         * 
6686         * @param main
6687         *            the values to use for determining the order
6688         * @param indices
6689         *            the second array
6690         * @param left
6691         *            the starting index
6692         * @param right
6693         *            the ending index
6694         */
6695        public static void parallelQuicksortDescending(final byte[] main, final short[] indices, final int left,
6696                        final int right)
6697        {
6698                if (right <= left)
6699                        return;
6700
6701                final int i = partitionDesc(main, indices, left, right);
6702
6703                parallelQuicksortDescending(main, indices, left, i - 1);
6704                parallelQuicksortDescending(main, indices, i + 1, right);
6705        }
6706
6707        // partition a[left] to a[right], assumes left < right
6708        private static int partitionDesc(final byte[] a, final short[] index, final int left, final int right) {
6709                int i = left - 1;
6710                int j = right;
6711                while (true) {
6712                        while (a[++i] > a[right])
6713                                // find item on left to swap
6714                                ; // a[right] acts as sentinel
6715                        while (a[right] > a[--j])
6716                                // find item on right to swap
6717                                if (j == left)
6718                                        break; // don't go out-of-bounds
6719                        if (i >= j)
6720                                break; // check if pointers cross
6721                        exch(a, index, i, j); // swap two elements into place
6722                }
6723                exch(a, index, i, right); // swap with partition element
6724                return i;
6725        }
6726        
6727        
6728        /**
6729         * Sort parallel arrays. Arrays are sorted in-place. The first array
6730         * determines the order, and is sorted into descending order.
6731         * <p>
6732         * Implementation inspired by this stackoverflow page: <a href=
6733         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6734         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6735         * get-a-sorted-list-of-indices-of-an-array </a>
6736         * 
6737         * @param main
6738         *            the values to use for determining the order
6739         * @param indices
6740         *            the second array
6741         */
6742        public static void parallelQuicksortDescending(final short[] main, final double[] indices) {
6743                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
6744        }
6745
6746        /**
6747         * Sort parallel arrays. Arrays are sorted in-place. The first array
6748         * determines the order, and is sorted into descending order.
6749         * <p>
6750         * Implementation inspired by this stackoverflow page: <a href=
6751         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6752         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6753         * get-a-sorted-list-of-indices-of-an-array </a>
6754         * 
6755         * @param main
6756         *            the values to use for determining the order
6757         * @param indices
6758         *            the second array
6759         * @param left
6760         *            the starting index
6761         * @param right
6762         *            the ending index
6763         */
6764        public static void parallelQuicksortDescending(final short[] main, final double[] indices, final int left,
6765                        final int right)
6766        {
6767                if (right <= left)
6768                        return;
6769
6770                final int i = partitionDesc(main, indices, left, right);
6771
6772                parallelQuicksortDescending(main, indices, left, i - 1);
6773                parallelQuicksortDescending(main, indices, i + 1, right);
6774        }
6775
6776        // partition a[left] to a[right], assumes left < right
6777        private static int partitionDesc(final short[] a, final double[] index, final int left, final int right) {
6778                int i = left - 1;
6779                int j = right;
6780                while (true) {
6781                        while (a[++i] > a[right])
6782                                // find item on left to swap
6783                                ; // a[right] acts as sentinel
6784                        while (a[right] > a[--j])
6785                                // find item on right to swap
6786                                if (j == left)
6787                                        break; // don't go out-of-bounds
6788                        if (i >= j)
6789                                break; // check if pointers cross
6790                        exch(a, index, i, j); // swap two elements into place
6791                }
6792                exch(a, index, i, right); // swap with partition element
6793                return i;
6794        }
6795        
6796        
6797        /**
6798         * Sort parallel arrays. Arrays are sorted in-place. The first array
6799         * determines the order, and is sorted into descending order.
6800         * <p>
6801         * Implementation inspired by this stackoverflow page: <a href=
6802         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6803         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6804         * get-a-sorted-list-of-indices-of-an-array </a>
6805         * 
6806         * @param main
6807         *            the values to use for determining the order
6808         * @param indices
6809         *            the second array
6810         */
6811        public static void parallelQuicksortDescending(final short[] main, final float[] indices) {
6812                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
6813        }
6814
6815        /**
6816         * Sort parallel arrays. Arrays are sorted in-place. The first array
6817         * determines the order, and is sorted into descending order.
6818         * <p>
6819         * Implementation inspired by this stackoverflow page: <a href=
6820         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6821         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6822         * get-a-sorted-list-of-indices-of-an-array </a>
6823         * 
6824         * @param main
6825         *            the values to use for determining the order
6826         * @param indices
6827         *            the second array
6828         * @param left
6829         *            the starting index
6830         * @param right
6831         *            the ending index
6832         */
6833        public static void parallelQuicksortDescending(final short[] main, final float[] indices, final int left,
6834                        final int right)
6835        {
6836                if (right <= left)
6837                        return;
6838
6839                final int i = partitionDesc(main, indices, left, right);
6840
6841                parallelQuicksortDescending(main, indices, left, i - 1);
6842                parallelQuicksortDescending(main, indices, i + 1, right);
6843        }
6844
6845        // partition a[left] to a[right], assumes left < right
6846        private static int partitionDesc(final short[] a, final float[] index, final int left, final int right) {
6847                int i = left - 1;
6848                int j = right;
6849                while (true) {
6850                        while (a[++i] > a[right])
6851                                // find item on left to swap
6852                                ; // a[right] acts as sentinel
6853                        while (a[right] > a[--j])
6854                                // find item on right to swap
6855                                if (j == left)
6856                                        break; // don't go out-of-bounds
6857                        if (i >= j)
6858                                break; // check if pointers cross
6859                        exch(a, index, i, j); // swap two elements into place
6860                }
6861                exch(a, index, i, right); // swap with partition element
6862                return i;
6863        }
6864        
6865        
6866        /**
6867         * Sort parallel arrays. Arrays are sorted in-place. The first array
6868         * determines the order, and is sorted into descending order.
6869         * <p>
6870         * Implementation inspired by this stackoverflow page: <a href=
6871         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6872         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6873         * get-a-sorted-list-of-indices-of-an-array </a>
6874         * 
6875         * @param main
6876         *            the values to use for determining the order
6877         * @param indices
6878         *            the second array
6879         */
6880        public static void parallelQuicksortDescending(final short[] main, final int[] indices) {
6881                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
6882        }
6883
6884        /**
6885         * Sort parallel arrays. Arrays are sorted in-place. The first array
6886         * determines the order, and is sorted into descending order.
6887         * <p>
6888         * Implementation inspired by this stackoverflow page: <a href=
6889         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6890         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6891         * get-a-sorted-list-of-indices-of-an-array </a>
6892         * 
6893         * @param main
6894         *            the values to use for determining the order
6895         * @param indices
6896         *            the second array
6897         * @param left
6898         *            the starting index
6899         * @param right
6900         *            the ending index
6901         */
6902        public static void parallelQuicksortDescending(final short[] main, final int[] indices, final int left,
6903                        final int right)
6904        {
6905                if (right <= left)
6906                        return;
6907
6908                final int i = partitionDesc(main, indices, left, right);
6909
6910                parallelQuicksortDescending(main, indices, left, i - 1);
6911                parallelQuicksortDescending(main, indices, i + 1, right);
6912        }
6913
6914        // partition a[left] to a[right], assumes left < right
6915        private static int partitionDesc(final short[] a, final int[] index, final int left, final int right) {
6916                int i = left - 1;
6917                int j = right;
6918                while (true) {
6919                        while (a[++i] > a[right])
6920                                // find item on left to swap
6921                                ; // a[right] acts as sentinel
6922                        while (a[right] > a[--j])
6923                                // find item on right to swap
6924                                if (j == left)
6925                                        break; // don't go out-of-bounds
6926                        if (i >= j)
6927                                break; // check if pointers cross
6928                        exch(a, index, i, j); // swap two elements into place
6929                }
6930                exch(a, index, i, right); // swap with partition element
6931                return i;
6932        }
6933        
6934        
6935        /**
6936         * Sort parallel arrays. Arrays are sorted in-place. The first array
6937         * determines the order, and is sorted into descending order.
6938         * <p>
6939         * Implementation inspired by this stackoverflow page: <a href=
6940         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6941         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6942         * get-a-sorted-list-of-indices-of-an-array </a>
6943         * 
6944         * @param main
6945         *            the values to use for determining the order
6946         * @param indices
6947         *            the second array
6948         */
6949        public static void parallelQuicksortDescending(final short[] main, final long[] indices) {
6950                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
6951        }
6952
6953        /**
6954         * Sort parallel arrays. Arrays are sorted in-place. The first array
6955         * determines the order, and is sorted into descending order.
6956         * <p>
6957         * Implementation inspired by this stackoverflow page: <a href=
6958         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
6959         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
6960         * get-a-sorted-list-of-indices-of-an-array </a>
6961         * 
6962         * @param main
6963         *            the values to use for determining the order
6964         * @param indices
6965         *            the second array
6966         * @param left
6967         *            the starting index
6968         * @param right
6969         *            the ending index
6970         */
6971        public static void parallelQuicksortDescending(final short[] main, final long[] indices, final int left,
6972                        final int right)
6973        {
6974                if (right <= left)
6975                        return;
6976
6977                final int i = partitionDesc(main, indices, left, right);
6978
6979                parallelQuicksortDescending(main, indices, left, i - 1);
6980                parallelQuicksortDescending(main, indices, i + 1, right);
6981        }
6982
6983        // partition a[left] to a[right], assumes left < right
6984        private static int partitionDesc(final short[] a, final long[] index, final int left, final int right) {
6985                int i = left - 1;
6986                int j = right;
6987                while (true) {
6988                        while (a[++i] > a[right])
6989                                // find item on left to swap
6990                                ; // a[right] acts as sentinel
6991                        while (a[right] > a[--j])
6992                                // find item on right to swap
6993                                if (j == left)
6994                                        break; // don't go out-of-bounds
6995                        if (i >= j)
6996                                break; // check if pointers cross
6997                        exch(a, index, i, j); // swap two elements into place
6998                }
6999                exch(a, index, i, right); // swap with partition element
7000                return i;
7001        }
7002        
7003        
7004        /**
7005         * Sort parallel arrays. Arrays are sorted in-place. The first array
7006         * determines the order, and is sorted into descending order.
7007         * <p>
7008         * Implementation inspired by this stackoverflow page: <a href=
7009         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7010         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7011         * get-a-sorted-list-of-indices-of-an-array </a>
7012         * 
7013         * @param main
7014         *            the values to use for determining the order
7015         * @param indices
7016         *            the second array
7017         */
7018        public static void parallelQuicksortDescending(final short[] main, final byte[] indices) {
7019                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
7020        }
7021
7022        /**
7023         * Sort parallel arrays. Arrays are sorted in-place. The first array
7024         * determines the order, and is sorted into descending order.
7025         * <p>
7026         * Implementation inspired by this stackoverflow page: <a href=
7027         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7028         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7029         * get-a-sorted-list-of-indices-of-an-array </a>
7030         * 
7031         * @param main
7032         *            the values to use for determining the order
7033         * @param indices
7034         *            the second array
7035         * @param left
7036         *            the starting index
7037         * @param right
7038         *            the ending index
7039         */
7040        public static void parallelQuicksortDescending(final short[] main, final byte[] indices, final int left,
7041                        final int right)
7042        {
7043                if (right <= left)
7044                        return;
7045
7046                final int i = partitionDesc(main, indices, left, right);
7047
7048                parallelQuicksortDescending(main, indices, left, i - 1);
7049                parallelQuicksortDescending(main, indices, i + 1, right);
7050        }
7051
7052        // partition a[left] to a[right], assumes left < right
7053        private static int partitionDesc(final short[] a, final byte[] index, final int left, final int right) {
7054                int i = left - 1;
7055                int j = right;
7056                while (true) {
7057                        while (a[++i] > a[right])
7058                                // find item on left to swap
7059                                ; // a[right] acts as sentinel
7060                        while (a[right] > a[--j])
7061                                // find item on right to swap
7062                                if (j == left)
7063                                        break; // don't go out-of-bounds
7064                        if (i >= j)
7065                                break; // check if pointers cross
7066                        exch(a, index, i, j); // swap two elements into place
7067                }
7068                exch(a, index, i, right); // swap with partition element
7069                return i;
7070        }
7071        
7072        
7073        /**
7074         * Sort parallel arrays. Arrays are sorted in-place. The first array
7075         * determines the order, and is sorted into descending order.
7076         * <p>
7077         * Implementation inspired by this stackoverflow page: <a href=
7078         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7079         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7080         * get-a-sorted-list-of-indices-of-an-array </a>
7081         * 
7082         * @param main
7083         *            the values to use for determining the order
7084         * @param indices
7085         *            the second array
7086         */
7087        public static void parallelQuicksortDescending(final short[] main, final short[] indices) {
7088                parallelQuicksortDescending(main, indices, 0, indices.length - 1);
7089        }
7090
7091        /**
7092         * Sort parallel arrays. Arrays are sorted in-place. The first array
7093         * determines the order, and is sorted into descending order.
7094         * <p>
7095         * Implementation inspired by this stackoverflow page: <a href=
7096         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7097         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7098         * get-a-sorted-list-of-indices-of-an-array </a>
7099         * 
7100         * @param main
7101         *            the values to use for determining the order
7102         * @param indices
7103         *            the second array
7104         * @param left
7105         *            the starting index
7106         * @param right
7107         *            the ending index
7108         */
7109        public static void parallelQuicksortDescending(final short[] main, final short[] indices, final int left,
7110                        final int right)
7111        {
7112                if (right <= left)
7113                        return;
7114
7115                final int i = partitionDesc(main, indices, left, right);
7116
7117                parallelQuicksortDescending(main, indices, left, i - 1);
7118                parallelQuicksortDescending(main, indices, i + 1, right);
7119        }
7120
7121        // partition a[left] to a[right], assumes left < right
7122        private static int partitionDesc(final short[] a, final short[] index, final int left, final int right) {
7123                int i = left - 1;
7124                int j = right;
7125                while (true) {
7126                        while (a[++i] > a[right])
7127                                // find item on left to swap
7128                                ; // a[right] acts as sentinel
7129                        while (a[right] > a[--j])
7130                                // find item on right to swap
7131                                if (j == left)
7132                                        break; // don't go out-of-bounds
7133                        if (i >= j)
7134                                break; // check if pointers cross
7135                        exch(a, index, i, j); // swap two elements into place
7136                }
7137                exch(a, index, i, right); // swap with partition element
7138                return i;
7139        }
7140        
7141        
7142    /**
7143         * Sort parallel arrays. Arrays are sorted in-place. The first array
7144         * determines the order, and is sorted into ascending order.
7145         * <p>
7146         * Implementation inspired by this stackoverflow page: <a href=
7147         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7148         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7149         * get-a-sorted-list-of-indices-of-an-array </a>
7150         * 
7151         * @param main
7152         *            the values to use for determining the order
7153         * @param indices
7154         *            the second array
7155         */
7156        public static void parallelQuicksortAscending(final double[] main, final double[] indices) {
7157                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
7158        }
7159        
7160    /**
7161         * Sort parallel arrays. Arrays are sorted in-place. The first array
7162         * determines the order, and is sorted into ascending order.
7163         * <p>
7164         * Implementation inspired by this stackoverflow page: <a href=
7165         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7166         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7167         * get-a-sorted-list-of-indices-of-an-array </a>
7168         * 
7169         * @param main
7170         *            the values to use for determining the order
7171         * @param indices
7172         *            the second array
7173         * @param left
7174         *            the starting index
7175         * @param right
7176         *            the ending index
7177         */
7178        public static void
7179                        parallelQuicksortAscending(final double[] main, final double[] indices, final int left, final int right)
7180        {
7181                if (right <= left)
7182                        return;
7183
7184                final int i = partitionAsc(main, indices, left, right);
7185
7186                parallelQuicksortAscending(main, indices, left, i - 1);
7187                parallelQuicksortAscending(main, indices, i + 1, right);
7188        }
7189
7190        // partition a[left] to a[right], assumes left < right
7191        private static int partitionAsc(final double[] a, final double[] index, final int left, final int right) {
7192                int i = left - 1;
7193                int j = right;
7194                while (true) {
7195                        while (a[++i] < a[right])
7196                                // find item on left to swap
7197                                ; // a[right] acts as sentinel
7198                        while (a[right] < a[--j])
7199                                // find item on right to swap
7200                                if (j == left)
7201                                        break; // don't go out-of-bounds
7202                        if (i >= j)
7203                                break; // check if pointers cross
7204                        exch(a, index, i, j); // swap two elements into place
7205                }
7206                exch(a, index, i, right); // swap with partition element
7207                return i;
7208        }
7209
7210    
7211    /**
7212         * Sort parallel arrays. Arrays are sorted in-place. The first array
7213         * determines the order, and is sorted into ascending order.
7214         * <p>
7215         * Implementation inspired by this stackoverflow page: <a href=
7216         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7217         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7218         * get-a-sorted-list-of-indices-of-an-array </a>
7219         * 
7220         * @param main
7221         *            the values to use for determining the order
7222         * @param indices
7223         *            the second array
7224         */
7225        public static void parallelQuicksortAscending(final double[] main, final float[] indices) {
7226                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
7227        }
7228        
7229    /**
7230         * Sort parallel arrays. Arrays are sorted in-place. The first array
7231         * determines the order, and is sorted into ascending order.
7232         * <p>
7233         * Implementation inspired by this stackoverflow page: <a href=
7234         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7235         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7236         * get-a-sorted-list-of-indices-of-an-array </a>
7237         * 
7238         * @param main
7239         *            the values to use for determining the order
7240         * @param indices
7241         *            the second array
7242         * @param left
7243         *            the starting index
7244         * @param right
7245         *            the ending index
7246         */
7247        public static void
7248                        parallelQuicksortAscending(final double[] main, final float[] indices, final int left, final int right)
7249        {
7250                if (right <= left)
7251                        return;
7252
7253                final int i = partitionAsc(main, indices, left, right);
7254
7255                parallelQuicksortAscending(main, indices, left, i - 1);
7256                parallelQuicksortAscending(main, indices, i + 1, right);
7257        }
7258
7259        // partition a[left] to a[right], assumes left < right
7260        private static int partitionAsc(final double[] a, final float[] index, final int left, final int right) {
7261                int i = left - 1;
7262                int j = right;
7263                while (true) {
7264                        while (a[++i] < a[right])
7265                                // find item on left to swap
7266                                ; // a[right] acts as sentinel
7267                        while (a[right] < a[--j])
7268                                // find item on right to swap
7269                                if (j == left)
7270                                        break; // don't go out-of-bounds
7271                        if (i >= j)
7272                                break; // check if pointers cross
7273                        exch(a, index, i, j); // swap two elements into place
7274                }
7275                exch(a, index, i, right); // swap with partition element
7276                return i;
7277        }
7278
7279    
7280    /**
7281         * Sort parallel arrays. Arrays are sorted in-place. The first array
7282         * determines the order, and is sorted into ascending order.
7283         * <p>
7284         * Implementation inspired by this stackoverflow page: <a href=
7285         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7286         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7287         * get-a-sorted-list-of-indices-of-an-array </a>
7288         * 
7289         * @param main
7290         *            the values to use for determining the order
7291         * @param indices
7292         *            the second array
7293         */
7294        public static void parallelQuicksortAscending(final double[] main, final int[] indices) {
7295                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
7296        }
7297        
7298    /**
7299         * Sort parallel arrays. Arrays are sorted in-place. The first array
7300         * determines the order, and is sorted into ascending order.
7301         * <p>
7302         * Implementation inspired by this stackoverflow page: <a href=
7303         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7304         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7305         * get-a-sorted-list-of-indices-of-an-array </a>
7306         * 
7307         * @param main
7308         *            the values to use for determining the order
7309         * @param indices
7310         *            the second array
7311         * @param left
7312         *            the starting index
7313         * @param right
7314         *            the ending index
7315         */
7316        public static void
7317                        parallelQuicksortAscending(final double[] main, final int[] indices, final int left, final int right)
7318        {
7319                if (right <= left)
7320                        return;
7321
7322                final int i = partitionAsc(main, indices, left, right);
7323
7324                parallelQuicksortAscending(main, indices, left, i - 1);
7325                parallelQuicksortAscending(main, indices, i + 1, right);
7326        }
7327
7328        // partition a[left] to a[right], assumes left < right
7329        private static int partitionAsc(final double[] a, final int[] index, final int left, final int right) {
7330                int i = left - 1;
7331                int j = right;
7332                while (true) {
7333                        while (a[++i] < a[right])
7334                                // find item on left to swap
7335                                ; // a[right] acts as sentinel
7336                        while (a[right] < a[--j])
7337                                // find item on right to swap
7338                                if (j == left)
7339                                        break; // don't go out-of-bounds
7340                        if (i >= j)
7341                                break; // check if pointers cross
7342                        exch(a, index, i, j); // swap two elements into place
7343                }
7344                exch(a, index, i, right); // swap with partition element
7345                return i;
7346        }
7347
7348    
7349    /**
7350         * Sort parallel arrays. Arrays are sorted in-place. The first array
7351         * determines the order, and is sorted into ascending order.
7352         * <p>
7353         * Implementation inspired by this stackoverflow page: <a href=
7354         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7355         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7356         * get-a-sorted-list-of-indices-of-an-array </a>
7357         * 
7358         * @param main
7359         *            the values to use for determining the order
7360         * @param indices
7361         *            the second array
7362         */
7363        public static void parallelQuicksortAscending(final double[] main, final long[] indices) {
7364                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
7365        }
7366        
7367    /**
7368         * Sort parallel arrays. Arrays are sorted in-place. The first array
7369         * determines the order, and is sorted into ascending order.
7370         * <p>
7371         * Implementation inspired by this stackoverflow page: <a href=
7372         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7373         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7374         * get-a-sorted-list-of-indices-of-an-array </a>
7375         * 
7376         * @param main
7377         *            the values to use for determining the order
7378         * @param indices
7379         *            the second array
7380         * @param left
7381         *            the starting index
7382         * @param right
7383         *            the ending index
7384         */
7385        public static void
7386                        parallelQuicksortAscending(final double[] main, final long[] indices, final int left, final int right)
7387        {
7388                if (right <= left)
7389                        return;
7390
7391                final int i = partitionAsc(main, indices, left, right);
7392
7393                parallelQuicksortAscending(main, indices, left, i - 1);
7394                parallelQuicksortAscending(main, indices, i + 1, right);
7395        }
7396
7397        // partition a[left] to a[right], assumes left < right
7398        private static int partitionAsc(final double[] a, final long[] index, final int left, final int right) {
7399                int i = left - 1;
7400                int j = right;
7401                while (true) {
7402                        while (a[++i] < a[right])
7403                                // find item on left to swap
7404                                ; // a[right] acts as sentinel
7405                        while (a[right] < a[--j])
7406                                // find item on right to swap
7407                                if (j == left)
7408                                        break; // don't go out-of-bounds
7409                        if (i >= j)
7410                                break; // check if pointers cross
7411                        exch(a, index, i, j); // swap two elements into place
7412                }
7413                exch(a, index, i, right); // swap with partition element
7414                return i;
7415        }
7416
7417    
7418    /**
7419         * Sort parallel arrays. Arrays are sorted in-place. The first array
7420         * determines the order, and is sorted into ascending order.
7421         * <p>
7422         * Implementation inspired by this stackoverflow page: <a href=
7423         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7424         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7425         * get-a-sorted-list-of-indices-of-an-array </a>
7426         * 
7427         * @param main
7428         *            the values to use for determining the order
7429         * @param indices
7430         *            the second array
7431         */
7432        public static void parallelQuicksortAscending(final double[] main, final byte[] indices) {
7433                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
7434        }
7435        
7436    /**
7437         * Sort parallel arrays. Arrays are sorted in-place. The first array
7438         * determines the order, and is sorted into ascending order.
7439         * <p>
7440         * Implementation inspired by this stackoverflow page: <a href=
7441         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7442         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7443         * get-a-sorted-list-of-indices-of-an-array </a>
7444         * 
7445         * @param main
7446         *            the values to use for determining the order
7447         * @param indices
7448         *            the second array
7449         * @param left
7450         *            the starting index
7451         * @param right
7452         *            the ending index
7453         */
7454        public static void
7455                        parallelQuicksortAscending(final double[] main, final byte[] indices, final int left, final int right)
7456        {
7457                if (right <= left)
7458                        return;
7459
7460                final int i = partitionAsc(main, indices, left, right);
7461
7462                parallelQuicksortAscending(main, indices, left, i - 1);
7463                parallelQuicksortAscending(main, indices, i + 1, right);
7464        }
7465
7466        // partition a[left] to a[right], assumes left < right
7467        private static int partitionAsc(final double[] a, final byte[] index, final int left, final int right) {
7468                int i = left - 1;
7469                int j = right;
7470                while (true) {
7471                        while (a[++i] < a[right])
7472                                // find item on left to swap
7473                                ; // a[right] acts as sentinel
7474                        while (a[right] < a[--j])
7475                                // find item on right to swap
7476                                if (j == left)
7477                                        break; // don't go out-of-bounds
7478                        if (i >= j)
7479                                break; // check if pointers cross
7480                        exch(a, index, i, j); // swap two elements into place
7481                }
7482                exch(a, index, i, right); // swap with partition element
7483                return i;
7484        }
7485
7486    
7487    /**
7488         * Sort parallel arrays. Arrays are sorted in-place. The first array
7489         * determines the order, and is sorted into ascending order.
7490         * <p>
7491         * Implementation inspired by this stackoverflow page: <a href=
7492         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7493         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7494         * get-a-sorted-list-of-indices-of-an-array </a>
7495         * 
7496         * @param main
7497         *            the values to use for determining the order
7498         * @param indices
7499         *            the second array
7500         */
7501        public static void parallelQuicksortAscending(final double[] main, final short[] indices) {
7502                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
7503        }
7504        
7505    /**
7506         * Sort parallel arrays. Arrays are sorted in-place. The first array
7507         * determines the order, and is sorted into ascending order.
7508         * <p>
7509         * Implementation inspired by this stackoverflow page: <a href=
7510         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7511         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7512         * get-a-sorted-list-of-indices-of-an-array </a>
7513         * 
7514         * @param main
7515         *            the values to use for determining the order
7516         * @param indices
7517         *            the second array
7518         * @param left
7519         *            the starting index
7520         * @param right
7521         *            the ending index
7522         */
7523        public static void
7524                        parallelQuicksortAscending(final double[] main, final short[] indices, final int left, final int right)
7525        {
7526                if (right <= left)
7527                        return;
7528
7529                final int i = partitionAsc(main, indices, left, right);
7530
7531                parallelQuicksortAscending(main, indices, left, i - 1);
7532                parallelQuicksortAscending(main, indices, i + 1, right);
7533        }
7534
7535        // partition a[left] to a[right], assumes left < right
7536        private static int partitionAsc(final double[] a, final short[] index, final int left, final int right) {
7537                int i = left - 1;
7538                int j = right;
7539                while (true) {
7540                        while (a[++i] < a[right])
7541                                // find item on left to swap
7542                                ; // a[right] acts as sentinel
7543                        while (a[right] < a[--j])
7544                                // find item on right to swap
7545                                if (j == left)
7546                                        break; // don't go out-of-bounds
7547                        if (i >= j)
7548                                break; // check if pointers cross
7549                        exch(a, index, i, j); // swap two elements into place
7550                }
7551                exch(a, index, i, right); // swap with partition element
7552                return i;
7553        }
7554
7555    
7556    /**
7557         * Sort parallel arrays. Arrays are sorted in-place. The first array
7558         * determines the order, and is sorted into ascending order.
7559         * <p>
7560         * Implementation inspired by this stackoverflow page: <a href=
7561         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7562         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7563         * get-a-sorted-list-of-indices-of-an-array </a>
7564         * 
7565         * @param main
7566         *            the values to use for determining the order
7567         * @param indices
7568         *            the second array
7569         */
7570        public static void parallelQuicksortAscending(final float[] main, final double[] indices) {
7571                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
7572        }
7573        
7574    /**
7575         * Sort parallel arrays. Arrays are sorted in-place. The first array
7576         * determines the order, and is sorted into ascending order.
7577         * <p>
7578         * Implementation inspired by this stackoverflow page: <a href=
7579         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7580         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7581         * get-a-sorted-list-of-indices-of-an-array </a>
7582         * 
7583         * @param main
7584         *            the values to use for determining the order
7585         * @param indices
7586         *            the second array
7587         * @param left
7588         *            the starting index
7589         * @param right
7590         *            the ending index
7591         */
7592        public static void
7593                        parallelQuicksortAscending(final float[] main, final double[] indices, final int left, final int right)
7594        {
7595                if (right <= left)
7596                        return;
7597
7598                final int i = partitionAsc(main, indices, left, right);
7599
7600                parallelQuicksortAscending(main, indices, left, i - 1);
7601                parallelQuicksortAscending(main, indices, i + 1, right);
7602        }
7603
7604        // partition a[left] to a[right], assumes left < right
7605        private static int partitionAsc(final float[] a, final double[] index, final int left, final int right) {
7606                int i = left - 1;
7607                int j = right;
7608                while (true) {
7609                        while (a[++i] < a[right])
7610                                // find item on left to swap
7611                                ; // a[right] acts as sentinel
7612                        while (a[right] < a[--j])
7613                                // find item on right to swap
7614                                if (j == left)
7615                                        break; // don't go out-of-bounds
7616                        if (i >= j)
7617                                break; // check if pointers cross
7618                        exch(a, index, i, j); // swap two elements into place
7619                }
7620                exch(a, index, i, right); // swap with partition element
7621                return i;
7622        }
7623
7624    
7625    /**
7626         * Sort parallel arrays. Arrays are sorted in-place. The first array
7627         * determines the order, and is sorted into ascending order.
7628         * <p>
7629         * Implementation inspired by this stackoverflow page: <a href=
7630         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7631         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7632         * get-a-sorted-list-of-indices-of-an-array </a>
7633         * 
7634         * @param main
7635         *            the values to use for determining the order
7636         * @param indices
7637         *            the second array
7638         */
7639        public static void parallelQuicksortAscending(final float[] main, final float[] indices) {
7640                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
7641        }
7642        
7643    /**
7644         * Sort parallel arrays. Arrays are sorted in-place. The first array
7645         * determines the order, and is sorted into ascending order.
7646         * <p>
7647         * Implementation inspired by this stackoverflow page: <a href=
7648         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7649         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7650         * get-a-sorted-list-of-indices-of-an-array </a>
7651         * 
7652         * @param main
7653         *            the values to use for determining the order
7654         * @param indices
7655         *            the second array
7656         * @param left
7657         *            the starting index
7658         * @param right
7659         *            the ending index
7660         */
7661        public static void
7662                        parallelQuicksortAscending(final float[] main, final float[] indices, final int left, final int right)
7663        {
7664                if (right <= left)
7665                        return;
7666
7667                final int i = partitionAsc(main, indices, left, right);
7668
7669                parallelQuicksortAscending(main, indices, left, i - 1);
7670                parallelQuicksortAscending(main, indices, i + 1, right);
7671        }
7672
7673        // partition a[left] to a[right], assumes left < right
7674        private static int partitionAsc(final float[] a, final float[] index, final int left, final int right) {
7675                int i = left - 1;
7676                int j = right;
7677                while (true) {
7678                        while (a[++i] < a[right])
7679                                // find item on left to swap
7680                                ; // a[right] acts as sentinel
7681                        while (a[right] < a[--j])
7682                                // find item on right to swap
7683                                if (j == left)
7684                                        break; // don't go out-of-bounds
7685                        if (i >= j)
7686                                break; // check if pointers cross
7687                        exch(a, index, i, j); // swap two elements into place
7688                }
7689                exch(a, index, i, right); // swap with partition element
7690                return i;
7691        }
7692
7693    
7694    /**
7695         * Sort parallel arrays. Arrays are sorted in-place. The first array
7696         * determines the order, and is sorted into ascending order.
7697         * <p>
7698         * Implementation inspired by this stackoverflow page: <a href=
7699         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7700         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7701         * get-a-sorted-list-of-indices-of-an-array </a>
7702         * 
7703         * @param main
7704         *            the values to use for determining the order
7705         * @param indices
7706         *            the second array
7707         */
7708        public static void parallelQuicksortAscending(final float[] main, final int[] indices) {
7709                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
7710        }
7711        
7712    /**
7713         * Sort parallel arrays. Arrays are sorted in-place. The first array
7714         * determines the order, and is sorted into ascending order.
7715         * <p>
7716         * Implementation inspired by this stackoverflow page: <a href=
7717         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7718         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7719         * get-a-sorted-list-of-indices-of-an-array </a>
7720         * 
7721         * @param main
7722         *            the values to use for determining the order
7723         * @param indices
7724         *            the second array
7725         * @param left
7726         *            the starting index
7727         * @param right
7728         *            the ending index
7729         */
7730        public static void
7731                        parallelQuicksortAscending(final float[] main, final int[] indices, final int left, final int right)
7732        {
7733                if (right <= left)
7734                        return;
7735
7736                final int i = partitionAsc(main, indices, left, right);
7737
7738                parallelQuicksortAscending(main, indices, left, i - 1);
7739                parallelQuicksortAscending(main, indices, i + 1, right);
7740        }
7741
7742        // partition a[left] to a[right], assumes left < right
7743        private static int partitionAsc(final float[] a, final int[] index, final int left, final int right) {
7744                int i = left - 1;
7745                int j = right;
7746                while (true) {
7747                        while (a[++i] < a[right])
7748                                // find item on left to swap
7749                                ; // a[right] acts as sentinel
7750                        while (a[right] < a[--j])
7751                                // find item on right to swap
7752                                if (j == left)
7753                                        break; // don't go out-of-bounds
7754                        if (i >= j)
7755                                break; // check if pointers cross
7756                        exch(a, index, i, j); // swap two elements into place
7757                }
7758                exch(a, index, i, right); // swap with partition element
7759                return i;
7760        }
7761
7762    
7763    /**
7764         * Sort parallel arrays. Arrays are sorted in-place. The first array
7765         * determines the order, and is sorted into ascending order.
7766         * <p>
7767         * Implementation inspired by this stackoverflow page: <a href=
7768         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7769         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7770         * get-a-sorted-list-of-indices-of-an-array </a>
7771         * 
7772         * @param main
7773         *            the values to use for determining the order
7774         * @param indices
7775         *            the second array
7776         */
7777        public static void parallelQuicksortAscending(final float[] main, final long[] indices) {
7778                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
7779        }
7780        
7781    /**
7782         * Sort parallel arrays. Arrays are sorted in-place. The first array
7783         * determines the order, and is sorted into ascending order.
7784         * <p>
7785         * Implementation inspired by this stackoverflow page: <a href=
7786         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7787         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7788         * get-a-sorted-list-of-indices-of-an-array </a>
7789         * 
7790         * @param main
7791         *            the values to use for determining the order
7792         * @param indices
7793         *            the second array
7794         * @param left
7795         *            the starting index
7796         * @param right
7797         *            the ending index
7798         */
7799        public static void
7800                        parallelQuicksortAscending(final float[] main, final long[] indices, final int left, final int right)
7801        {
7802                if (right <= left)
7803                        return;
7804
7805                final int i = partitionAsc(main, indices, left, right);
7806
7807                parallelQuicksortAscending(main, indices, left, i - 1);
7808                parallelQuicksortAscending(main, indices, i + 1, right);
7809        }
7810
7811        // partition a[left] to a[right], assumes left < right
7812        private static int partitionAsc(final float[] a, final long[] index, final int left, final int right) {
7813                int i = left - 1;
7814                int j = right;
7815                while (true) {
7816                        while (a[++i] < a[right])
7817                                // find item on left to swap
7818                                ; // a[right] acts as sentinel
7819                        while (a[right] < a[--j])
7820                                // find item on right to swap
7821                                if (j == left)
7822                                        break; // don't go out-of-bounds
7823                        if (i >= j)
7824                                break; // check if pointers cross
7825                        exch(a, index, i, j); // swap two elements into place
7826                }
7827                exch(a, index, i, right); // swap with partition element
7828                return i;
7829        }
7830
7831    
7832    /**
7833         * Sort parallel arrays. Arrays are sorted in-place. The first array
7834         * determines the order, and is sorted into ascending order.
7835         * <p>
7836         * Implementation inspired by this stackoverflow page: <a href=
7837         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7838         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7839         * get-a-sorted-list-of-indices-of-an-array </a>
7840         * 
7841         * @param main
7842         *            the values to use for determining the order
7843         * @param indices
7844         *            the second array
7845         */
7846        public static void parallelQuicksortAscending(final float[] main, final byte[] indices) {
7847                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
7848        }
7849        
7850    /**
7851         * Sort parallel arrays. Arrays are sorted in-place. The first array
7852         * determines the order, and is sorted into ascending order.
7853         * <p>
7854         * Implementation inspired by this stackoverflow page: <a href=
7855         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7856         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7857         * get-a-sorted-list-of-indices-of-an-array </a>
7858         * 
7859         * @param main
7860         *            the values to use for determining the order
7861         * @param indices
7862         *            the second array
7863         * @param left
7864         *            the starting index
7865         * @param right
7866         *            the ending index
7867         */
7868        public static void
7869                        parallelQuicksortAscending(final float[] main, final byte[] indices, final int left, final int right)
7870        {
7871                if (right <= left)
7872                        return;
7873
7874                final int i = partitionAsc(main, indices, left, right);
7875
7876                parallelQuicksortAscending(main, indices, left, i - 1);
7877                parallelQuicksortAscending(main, indices, i + 1, right);
7878        }
7879
7880        // partition a[left] to a[right], assumes left < right
7881        private static int partitionAsc(final float[] a, final byte[] index, final int left, final int right) {
7882                int i = left - 1;
7883                int j = right;
7884                while (true) {
7885                        while (a[++i] < a[right])
7886                                // find item on left to swap
7887                                ; // a[right] acts as sentinel
7888                        while (a[right] < a[--j])
7889                                // find item on right to swap
7890                                if (j == left)
7891                                        break; // don't go out-of-bounds
7892                        if (i >= j)
7893                                break; // check if pointers cross
7894                        exch(a, index, i, j); // swap two elements into place
7895                }
7896                exch(a, index, i, right); // swap with partition element
7897                return i;
7898        }
7899
7900    
7901    /**
7902         * Sort parallel arrays. Arrays are sorted in-place. The first array
7903         * determines the order, and is sorted into ascending order.
7904         * <p>
7905         * Implementation inspired by this stackoverflow page: <a href=
7906         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7907         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7908         * get-a-sorted-list-of-indices-of-an-array </a>
7909         * 
7910         * @param main
7911         *            the values to use for determining the order
7912         * @param indices
7913         *            the second array
7914         */
7915        public static void parallelQuicksortAscending(final float[] main, final short[] indices) {
7916                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
7917        }
7918        
7919    /**
7920         * Sort parallel arrays. Arrays are sorted in-place. The first array
7921         * determines the order, and is sorted into ascending order.
7922         * <p>
7923         * Implementation inspired by this stackoverflow page: <a href=
7924         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7925         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7926         * get-a-sorted-list-of-indices-of-an-array </a>
7927         * 
7928         * @param main
7929         *            the values to use for determining the order
7930         * @param indices
7931         *            the second array
7932         * @param left
7933         *            the starting index
7934         * @param right
7935         *            the ending index
7936         */
7937        public static void
7938                        parallelQuicksortAscending(final float[] main, final short[] indices, final int left, final int right)
7939        {
7940                if (right <= left)
7941                        return;
7942
7943                final int i = partitionAsc(main, indices, left, right);
7944
7945                parallelQuicksortAscending(main, indices, left, i - 1);
7946                parallelQuicksortAscending(main, indices, i + 1, right);
7947        }
7948
7949        // partition a[left] to a[right], assumes left < right
7950        private static int partitionAsc(final float[] a, final short[] index, final int left, final int right) {
7951                int i = left - 1;
7952                int j = right;
7953                while (true) {
7954                        while (a[++i] < a[right])
7955                                // find item on left to swap
7956                                ; // a[right] acts as sentinel
7957                        while (a[right] < a[--j])
7958                                // find item on right to swap
7959                                if (j == left)
7960                                        break; // don't go out-of-bounds
7961                        if (i >= j)
7962                                break; // check if pointers cross
7963                        exch(a, index, i, j); // swap two elements into place
7964                }
7965                exch(a, index, i, right); // swap with partition element
7966                return i;
7967        }
7968
7969    
7970    /**
7971         * Sort parallel arrays. Arrays are sorted in-place. The first array
7972         * determines the order, and is sorted into ascending order.
7973         * <p>
7974         * Implementation inspired by this stackoverflow page: <a href=
7975         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7976         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7977         * get-a-sorted-list-of-indices-of-an-array </a>
7978         * 
7979         * @param main
7980         *            the values to use for determining the order
7981         * @param indices
7982         *            the second array
7983         */
7984        public static void parallelQuicksortAscending(final int[] main, final double[] indices) {
7985                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
7986        }
7987        
7988    /**
7989         * Sort parallel arrays. Arrays are sorted in-place. The first array
7990         * determines the order, and is sorted into ascending order.
7991         * <p>
7992         * Implementation inspired by this stackoverflow page: <a href=
7993         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
7994         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
7995         * get-a-sorted-list-of-indices-of-an-array </a>
7996         * 
7997         * @param main
7998         *            the values to use for determining the order
7999         * @param indices
8000         *            the second array
8001         * @param left
8002         *            the starting index
8003         * @param right
8004         *            the ending index
8005         */
8006        public static void
8007                        parallelQuicksortAscending(final int[] main, final double[] indices, final int left, final int right)
8008        {
8009                if (right <= left)
8010                        return;
8011
8012                final int i = partitionAsc(main, indices, left, right);
8013
8014                parallelQuicksortAscending(main, indices, left, i - 1);
8015                parallelQuicksortAscending(main, indices, i + 1, right);
8016        }
8017
8018        // partition a[left] to a[right], assumes left < right
8019        private static int partitionAsc(final int[] a, final double[] index, final int left, final int right) {
8020                int i = left - 1;
8021                int j = right;
8022                while (true) {
8023                        while (a[++i] < a[right])
8024                                // find item on left to swap
8025                                ; // a[right] acts as sentinel
8026                        while (a[right] < a[--j])
8027                                // find item on right to swap
8028                                if (j == left)
8029                                        break; // don't go out-of-bounds
8030                        if (i >= j)
8031                                break; // check if pointers cross
8032                        exch(a, index, i, j); // swap two elements into place
8033                }
8034                exch(a, index, i, right); // swap with partition element
8035                return i;
8036        }
8037
8038    
8039    /**
8040         * Sort parallel arrays. Arrays are sorted in-place. The first array
8041         * determines the order, and is sorted into ascending order.
8042         * <p>
8043         * Implementation inspired by this stackoverflow page: <a href=
8044         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8045         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8046         * get-a-sorted-list-of-indices-of-an-array </a>
8047         * 
8048         * @param main
8049         *            the values to use for determining the order
8050         * @param indices
8051         *            the second array
8052         */
8053        public static void parallelQuicksortAscending(final int[] main, final float[] indices) {
8054                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
8055        }
8056        
8057    /**
8058         * Sort parallel arrays. Arrays are sorted in-place. The first array
8059         * determines the order, and is sorted into ascending order.
8060         * <p>
8061         * Implementation inspired by this stackoverflow page: <a href=
8062         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8063         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8064         * get-a-sorted-list-of-indices-of-an-array </a>
8065         * 
8066         * @param main
8067         *            the values to use for determining the order
8068         * @param indices
8069         *            the second array
8070         * @param left
8071         *            the starting index
8072         * @param right
8073         *            the ending index
8074         */
8075        public static void
8076                        parallelQuicksortAscending(final int[] main, final float[] indices, final int left, final int right)
8077        {
8078                if (right <= left)
8079                        return;
8080
8081                final int i = partitionAsc(main, indices, left, right);
8082
8083                parallelQuicksortAscending(main, indices, left, i - 1);
8084                parallelQuicksortAscending(main, indices, i + 1, right);
8085        }
8086
8087        // partition a[left] to a[right], assumes left < right
8088        private static int partitionAsc(final int[] a, final float[] index, final int left, final int right) {
8089                int i = left - 1;
8090                int j = right;
8091                while (true) {
8092                        while (a[++i] < a[right])
8093                                // find item on left to swap
8094                                ; // a[right] acts as sentinel
8095                        while (a[right] < a[--j])
8096                                // find item on right to swap
8097                                if (j == left)
8098                                        break; // don't go out-of-bounds
8099                        if (i >= j)
8100                                break; // check if pointers cross
8101                        exch(a, index, i, j); // swap two elements into place
8102                }
8103                exch(a, index, i, right); // swap with partition element
8104                return i;
8105        }
8106
8107    
8108    /**
8109         * Sort parallel arrays. Arrays are sorted in-place. The first array
8110         * determines the order, and is sorted into ascending order.
8111         * <p>
8112         * Implementation inspired by this stackoverflow page: <a href=
8113         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8114         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8115         * get-a-sorted-list-of-indices-of-an-array </a>
8116         * 
8117         * @param main
8118         *            the values to use for determining the order
8119         * @param indices
8120         *            the second array
8121         */
8122        public static void parallelQuicksortAscending(final int[] main, final int[] indices) {
8123                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
8124        }
8125        
8126    /**
8127         * Sort parallel arrays. Arrays are sorted in-place. The first array
8128         * determines the order, and is sorted into ascending order.
8129         * <p>
8130         * Implementation inspired by this stackoverflow page: <a href=
8131         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8132         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8133         * get-a-sorted-list-of-indices-of-an-array </a>
8134         * 
8135         * @param main
8136         *            the values to use for determining the order
8137         * @param indices
8138         *            the second array
8139         * @param left
8140         *            the starting index
8141         * @param right
8142         *            the ending index
8143         */
8144        public static void
8145                        parallelQuicksortAscending(final int[] main, final int[] indices, final int left, final int right)
8146        {
8147                if (right <= left)
8148                        return;
8149
8150                final int i = partitionAsc(main, indices, left, right);
8151
8152                parallelQuicksortAscending(main, indices, left, i - 1);
8153                parallelQuicksortAscending(main, indices, i + 1, right);
8154        }
8155
8156        // partition a[left] to a[right], assumes left < right
8157        private static int partitionAsc(final int[] a, final int[] index, final int left, final int right) {
8158                int i = left - 1;
8159                int j = right;
8160                while (true) {
8161                        while (a[++i] < a[right])
8162                                // find item on left to swap
8163                                ; // a[right] acts as sentinel
8164                        while (a[right] < a[--j])
8165                                // find item on right to swap
8166                                if (j == left)
8167                                        break; // don't go out-of-bounds
8168                        if (i >= j)
8169                                break; // check if pointers cross
8170                        exch(a, index, i, j); // swap two elements into place
8171                }
8172                exch(a, index, i, right); // swap with partition element
8173                return i;
8174        }
8175
8176    
8177    /**
8178         * Sort parallel arrays. Arrays are sorted in-place. The first array
8179         * determines the order, and is sorted into ascending order.
8180         * <p>
8181         * Implementation inspired by this stackoverflow page: <a href=
8182         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8183         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8184         * get-a-sorted-list-of-indices-of-an-array </a>
8185         * 
8186         * @param main
8187         *            the values to use for determining the order
8188         * @param indices
8189         *            the second array
8190         */
8191        public static void parallelQuicksortAscending(final int[] main, final long[] indices) {
8192                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
8193        }
8194        
8195    /**
8196         * Sort parallel arrays. Arrays are sorted in-place. The first array
8197         * determines the order, and is sorted into ascending order.
8198         * <p>
8199         * Implementation inspired by this stackoverflow page: <a href=
8200         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8201         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8202         * get-a-sorted-list-of-indices-of-an-array </a>
8203         * 
8204         * @param main
8205         *            the values to use for determining the order
8206         * @param indices
8207         *            the second array
8208         * @param left
8209         *            the starting index
8210         * @param right
8211         *            the ending index
8212         */
8213        public static void
8214                        parallelQuicksortAscending(final int[] main, final long[] indices, final int left, final int right)
8215        {
8216                if (right <= left)
8217                        return;
8218
8219                final int i = partitionAsc(main, indices, left, right);
8220
8221                parallelQuicksortAscending(main, indices, left, i - 1);
8222                parallelQuicksortAscending(main, indices, i + 1, right);
8223        }
8224
8225        // partition a[left] to a[right], assumes left < right
8226        private static int partitionAsc(final int[] a, final long[] index, final int left, final int right) {
8227                int i = left - 1;
8228                int j = right;
8229                while (true) {
8230                        while (a[++i] < a[right])
8231                                // find item on left to swap
8232                                ; // a[right] acts as sentinel
8233                        while (a[right] < a[--j])
8234                                // find item on right to swap
8235                                if (j == left)
8236                                        break; // don't go out-of-bounds
8237                        if (i >= j)
8238                                break; // check if pointers cross
8239                        exch(a, index, i, j); // swap two elements into place
8240                }
8241                exch(a, index, i, right); // swap with partition element
8242                return i;
8243        }
8244
8245    
8246    /**
8247         * Sort parallel arrays. Arrays are sorted in-place. The first array
8248         * determines the order, and is sorted into ascending order.
8249         * <p>
8250         * Implementation inspired by this stackoverflow page: <a href=
8251         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8252         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8253         * get-a-sorted-list-of-indices-of-an-array </a>
8254         * 
8255         * @param main
8256         *            the values to use for determining the order
8257         * @param indices
8258         *            the second array
8259         */
8260        public static void parallelQuicksortAscending(final int[] main, final byte[] indices) {
8261                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
8262        }
8263        
8264    /**
8265         * Sort parallel arrays. Arrays are sorted in-place. The first array
8266         * determines the order, and is sorted into ascending order.
8267         * <p>
8268         * Implementation inspired by this stackoverflow page: <a href=
8269         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8270         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8271         * get-a-sorted-list-of-indices-of-an-array </a>
8272         * 
8273         * @param main
8274         *            the values to use for determining the order
8275         * @param indices
8276         *            the second array
8277         * @param left
8278         *            the starting index
8279         * @param right
8280         *            the ending index
8281         */
8282        public static void
8283                        parallelQuicksortAscending(final int[] main, final byte[] indices, final int left, final int right)
8284        {
8285                if (right <= left)
8286                        return;
8287
8288                final int i = partitionAsc(main, indices, left, right);
8289
8290                parallelQuicksortAscending(main, indices, left, i - 1);
8291                parallelQuicksortAscending(main, indices, i + 1, right);
8292        }
8293
8294        // partition a[left] to a[right], assumes left < right
8295        private static int partitionAsc(final int[] a, final byte[] index, final int left, final int right) {
8296                int i = left - 1;
8297                int j = right;
8298                while (true) {
8299                        while (a[++i] < a[right])
8300                                // find item on left to swap
8301                                ; // a[right] acts as sentinel
8302                        while (a[right] < a[--j])
8303                                // find item on right to swap
8304                                if (j == left)
8305                                        break; // don't go out-of-bounds
8306                        if (i >= j)
8307                                break; // check if pointers cross
8308                        exch(a, index, i, j); // swap two elements into place
8309                }
8310                exch(a, index, i, right); // swap with partition element
8311                return i;
8312        }
8313
8314    
8315    /**
8316         * Sort parallel arrays. Arrays are sorted in-place. The first array
8317         * determines the order, and is sorted into ascending order.
8318         * <p>
8319         * Implementation inspired by this stackoverflow page: <a href=
8320         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8321         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8322         * get-a-sorted-list-of-indices-of-an-array </a>
8323         * 
8324         * @param main
8325         *            the values to use for determining the order
8326         * @param indices
8327         *            the second array
8328         */
8329        public static void parallelQuicksortAscending(final int[] main, final short[] indices) {
8330                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
8331        }
8332        
8333    /**
8334         * Sort parallel arrays. Arrays are sorted in-place. The first array
8335         * determines the order, and is sorted into ascending order.
8336         * <p>
8337         * Implementation inspired by this stackoverflow page: <a href=
8338         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8339         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8340         * get-a-sorted-list-of-indices-of-an-array </a>
8341         * 
8342         * @param main
8343         *            the values to use for determining the order
8344         * @param indices
8345         *            the second array
8346         * @param left
8347         *            the starting index
8348         * @param right
8349         *            the ending index
8350         */
8351        public static void
8352                        parallelQuicksortAscending(final int[] main, final short[] indices, final int left, final int right)
8353        {
8354                if (right <= left)
8355                        return;
8356
8357                final int i = partitionAsc(main, indices, left, right);
8358
8359                parallelQuicksortAscending(main, indices, left, i - 1);
8360                parallelQuicksortAscending(main, indices, i + 1, right);
8361        }
8362
8363        // partition a[left] to a[right], assumes left < right
8364        private static int partitionAsc(final int[] a, final short[] index, final int left, final int right) {
8365                int i = left - 1;
8366                int j = right;
8367                while (true) {
8368                        while (a[++i] < a[right])
8369                                // find item on left to swap
8370                                ; // a[right] acts as sentinel
8371                        while (a[right] < a[--j])
8372                                // find item on right to swap
8373                                if (j == left)
8374                                        break; // don't go out-of-bounds
8375                        if (i >= j)
8376                                break; // check if pointers cross
8377                        exch(a, index, i, j); // swap two elements into place
8378                }
8379                exch(a, index, i, right); // swap with partition element
8380                return i;
8381        }
8382
8383    
8384    /**
8385         * Sort parallel arrays. Arrays are sorted in-place. The first array
8386         * determines the order, and is sorted into ascending order.
8387         * <p>
8388         * Implementation inspired by this stackoverflow page: <a href=
8389         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8390         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8391         * get-a-sorted-list-of-indices-of-an-array </a>
8392         * 
8393         * @param main
8394         *            the values to use for determining the order
8395         * @param indices
8396         *            the second array
8397         */
8398        public static void parallelQuicksortAscending(final long[] main, final double[] indices) {
8399                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
8400        }
8401        
8402    /**
8403         * Sort parallel arrays. Arrays are sorted in-place. The first array
8404         * determines the order, and is sorted into ascending order.
8405         * <p>
8406         * Implementation inspired by this stackoverflow page: <a href=
8407         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8408         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8409         * get-a-sorted-list-of-indices-of-an-array </a>
8410         * 
8411         * @param main
8412         *            the values to use for determining the order
8413         * @param indices
8414         *            the second array
8415         * @param left
8416         *            the starting index
8417         * @param right
8418         *            the ending index
8419         */
8420        public static void
8421                        parallelQuicksortAscending(final long[] main, final double[] indices, final int left, final int right)
8422        {
8423                if (right <= left)
8424                        return;
8425
8426                final int i = partitionAsc(main, indices, left, right);
8427
8428                parallelQuicksortAscending(main, indices, left, i - 1);
8429                parallelQuicksortAscending(main, indices, i + 1, right);
8430        }
8431
8432        // partition a[left] to a[right], assumes left < right
8433        private static int partitionAsc(final long[] a, final double[] index, final int left, final int right) {
8434                int i = left - 1;
8435                int j = right;
8436                while (true) {
8437                        while (a[++i] < a[right])
8438                                // find item on left to swap
8439                                ; // a[right] acts as sentinel
8440                        while (a[right] < a[--j])
8441                                // find item on right to swap
8442                                if (j == left)
8443                                        break; // don't go out-of-bounds
8444                        if (i >= j)
8445                                break; // check if pointers cross
8446                        exch(a, index, i, j); // swap two elements into place
8447                }
8448                exch(a, index, i, right); // swap with partition element
8449                return i;
8450        }
8451
8452    
8453    /**
8454         * Sort parallel arrays. Arrays are sorted in-place. The first array
8455         * determines the order, and is sorted into ascending order.
8456         * <p>
8457         * Implementation inspired by this stackoverflow page: <a href=
8458         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8459         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8460         * get-a-sorted-list-of-indices-of-an-array </a>
8461         * 
8462         * @param main
8463         *            the values to use for determining the order
8464         * @param indices
8465         *            the second array
8466         */
8467        public static void parallelQuicksortAscending(final long[] main, final float[] indices) {
8468                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
8469        }
8470        
8471    /**
8472         * Sort parallel arrays. Arrays are sorted in-place. The first array
8473         * determines the order, and is sorted into ascending order.
8474         * <p>
8475         * Implementation inspired by this stackoverflow page: <a href=
8476         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8477         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8478         * get-a-sorted-list-of-indices-of-an-array </a>
8479         * 
8480         * @param main
8481         *            the values to use for determining the order
8482         * @param indices
8483         *            the second array
8484         * @param left
8485         *            the starting index
8486         * @param right
8487         *            the ending index
8488         */
8489        public static void
8490                        parallelQuicksortAscending(final long[] main, final float[] indices, final int left, final int right)
8491        {
8492                if (right <= left)
8493                        return;
8494
8495                final int i = partitionAsc(main, indices, left, right);
8496
8497                parallelQuicksortAscending(main, indices, left, i - 1);
8498                parallelQuicksortAscending(main, indices, i + 1, right);
8499        }
8500
8501        // partition a[left] to a[right], assumes left < right
8502        private static int partitionAsc(final long[] a, final float[] index, final int left, final int right) {
8503                int i = left - 1;
8504                int j = right;
8505                while (true) {
8506                        while (a[++i] < a[right])
8507                                // find item on left to swap
8508                                ; // a[right] acts as sentinel
8509                        while (a[right] < a[--j])
8510                                // find item on right to swap
8511                                if (j == left)
8512                                        break; // don't go out-of-bounds
8513                        if (i >= j)
8514                                break; // check if pointers cross
8515                        exch(a, index, i, j); // swap two elements into place
8516                }
8517                exch(a, index, i, right); // swap with partition element
8518                return i;
8519        }
8520
8521    
8522    /**
8523         * Sort parallel arrays. Arrays are sorted in-place. The first array
8524         * determines the order, and is sorted into ascending order.
8525         * <p>
8526         * Implementation inspired by this stackoverflow page: <a href=
8527         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8528         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8529         * get-a-sorted-list-of-indices-of-an-array </a>
8530         * 
8531         * @param main
8532         *            the values to use for determining the order
8533         * @param indices
8534         *            the second array
8535         */
8536        public static void parallelQuicksortAscending(final long[] main, final int[] indices) {
8537                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
8538        }
8539        
8540    /**
8541         * Sort parallel arrays. Arrays are sorted in-place. The first array
8542         * determines the order, and is sorted into ascending order.
8543         * <p>
8544         * Implementation inspired by this stackoverflow page: <a href=
8545         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8546         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8547         * get-a-sorted-list-of-indices-of-an-array </a>
8548         * 
8549         * @param main
8550         *            the values to use for determining the order
8551         * @param indices
8552         *            the second array
8553         * @param left
8554         *            the starting index
8555         * @param right
8556         *            the ending index
8557         */
8558        public static void
8559                        parallelQuicksortAscending(final long[] main, final int[] indices, final int left, final int right)
8560        {
8561                if (right <= left)
8562                        return;
8563
8564                final int i = partitionAsc(main, indices, left, right);
8565
8566                parallelQuicksortAscending(main, indices, left, i - 1);
8567                parallelQuicksortAscending(main, indices, i + 1, right);
8568        }
8569
8570        // partition a[left] to a[right], assumes left < right
8571        private static int partitionAsc(final long[] a, final int[] index, final int left, final int right) {
8572                int i = left - 1;
8573                int j = right;
8574                while (true) {
8575                        while (a[++i] < a[right])
8576                                // find item on left to swap
8577                                ; // a[right] acts as sentinel
8578                        while (a[right] < a[--j])
8579                                // find item on right to swap
8580                                if (j == left)
8581                                        break; // don't go out-of-bounds
8582                        if (i >= j)
8583                                break; // check if pointers cross
8584                        exch(a, index, i, j); // swap two elements into place
8585                }
8586                exch(a, index, i, right); // swap with partition element
8587                return i;
8588        }
8589
8590    
8591    /**
8592         * Sort parallel arrays. Arrays are sorted in-place. The first array
8593         * determines the order, and is sorted into ascending order.
8594         * <p>
8595         * Implementation inspired by this stackoverflow page: <a href=
8596         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8597         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8598         * get-a-sorted-list-of-indices-of-an-array </a>
8599         * 
8600         * @param main
8601         *            the values to use for determining the order
8602         * @param indices
8603         *            the second array
8604         */
8605        public static void parallelQuicksortAscending(final long[] main, final long[] indices) {
8606                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
8607        }
8608        
8609    /**
8610         * Sort parallel arrays. Arrays are sorted in-place. The first array
8611         * determines the order, and is sorted into ascending order.
8612         * <p>
8613         * Implementation inspired by this stackoverflow page: <a href=
8614         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8615         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8616         * get-a-sorted-list-of-indices-of-an-array </a>
8617         * 
8618         * @param main
8619         *            the values to use for determining the order
8620         * @param indices
8621         *            the second array
8622         * @param left
8623         *            the starting index
8624         * @param right
8625         *            the ending index
8626         */
8627        public static void
8628                        parallelQuicksortAscending(final long[] main, final long[] indices, final int left, final int right)
8629        {
8630                if (right <= left)
8631                        return;
8632
8633                final int i = partitionAsc(main, indices, left, right);
8634
8635                parallelQuicksortAscending(main, indices, left, i - 1);
8636                parallelQuicksortAscending(main, indices, i + 1, right);
8637        }
8638
8639        // partition a[left] to a[right], assumes left < right
8640        private static int partitionAsc(final long[] a, final long[] index, final int left, final int right) {
8641                int i = left - 1;
8642                int j = right;
8643                while (true) {
8644                        while (a[++i] < a[right])
8645                                // find item on left to swap
8646                                ; // a[right] acts as sentinel
8647                        while (a[right] < a[--j])
8648                                // find item on right to swap
8649                                if (j == left)
8650                                        break; // don't go out-of-bounds
8651                        if (i >= j)
8652                                break; // check if pointers cross
8653                        exch(a, index, i, j); // swap two elements into place
8654                }
8655                exch(a, index, i, right); // swap with partition element
8656                return i;
8657        }
8658
8659    
8660    /**
8661         * Sort parallel arrays. Arrays are sorted in-place. The first array
8662         * determines the order, and is sorted into ascending order.
8663         * <p>
8664         * Implementation inspired by this stackoverflow page: <a href=
8665         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8666         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8667         * get-a-sorted-list-of-indices-of-an-array </a>
8668         * 
8669         * @param main
8670         *            the values to use for determining the order
8671         * @param indices
8672         *            the second array
8673         */
8674        public static void parallelQuicksortAscending(final long[] main, final byte[] indices) {
8675                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
8676        }
8677        
8678    /**
8679         * Sort parallel arrays. Arrays are sorted in-place. The first array
8680         * determines the order, and is sorted into ascending order.
8681         * <p>
8682         * Implementation inspired by this stackoverflow page: <a href=
8683         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8684         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8685         * get-a-sorted-list-of-indices-of-an-array </a>
8686         * 
8687         * @param main
8688         *            the values to use for determining the order
8689         * @param indices
8690         *            the second array
8691         * @param left
8692         *            the starting index
8693         * @param right
8694         *            the ending index
8695         */
8696        public static void
8697                        parallelQuicksortAscending(final long[] main, final byte[] indices, final int left, final int right)
8698        {
8699                if (right <= left)
8700                        return;
8701
8702                final int i = partitionAsc(main, indices, left, right);
8703
8704                parallelQuicksortAscending(main, indices, left, i - 1);
8705                parallelQuicksortAscending(main, indices, i + 1, right);
8706        }
8707
8708        // partition a[left] to a[right], assumes left < right
8709        private static int partitionAsc(final long[] a, final byte[] index, final int left, final int right) {
8710                int i = left - 1;
8711                int j = right;
8712                while (true) {
8713                        while (a[++i] < a[right])
8714                                // find item on left to swap
8715                                ; // a[right] acts as sentinel
8716                        while (a[right] < a[--j])
8717                                // find item on right to swap
8718                                if (j == left)
8719                                        break; // don't go out-of-bounds
8720                        if (i >= j)
8721                                break; // check if pointers cross
8722                        exch(a, index, i, j); // swap two elements into place
8723                }
8724                exch(a, index, i, right); // swap with partition element
8725                return i;
8726        }
8727
8728    
8729    /**
8730         * Sort parallel arrays. Arrays are sorted in-place. The first array
8731         * determines the order, and is sorted into ascending order.
8732         * <p>
8733         * Implementation inspired by this stackoverflow page: <a href=
8734         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8735         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8736         * get-a-sorted-list-of-indices-of-an-array </a>
8737         * 
8738         * @param main
8739         *            the values to use for determining the order
8740         * @param indices
8741         *            the second array
8742         */
8743        public static void parallelQuicksortAscending(final long[] main, final short[] indices) {
8744                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
8745        }
8746        
8747    /**
8748         * Sort parallel arrays. Arrays are sorted in-place. The first array
8749         * determines the order, and is sorted into ascending order.
8750         * <p>
8751         * Implementation inspired by this stackoverflow page: <a href=
8752         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8753         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8754         * get-a-sorted-list-of-indices-of-an-array </a>
8755         * 
8756         * @param main
8757         *            the values to use for determining the order
8758         * @param indices
8759         *            the second array
8760         * @param left
8761         *            the starting index
8762         * @param right
8763         *            the ending index
8764         */
8765        public static void
8766                        parallelQuicksortAscending(final long[] main, final short[] indices, final int left, final int right)
8767        {
8768                if (right <= left)
8769                        return;
8770
8771                final int i = partitionAsc(main, indices, left, right);
8772
8773                parallelQuicksortAscending(main, indices, left, i - 1);
8774                parallelQuicksortAscending(main, indices, i + 1, right);
8775        }
8776
8777        // partition a[left] to a[right], assumes left < right
8778        private static int partitionAsc(final long[] a, final short[] index, final int left, final int right) {
8779                int i = left - 1;
8780                int j = right;
8781                while (true) {
8782                        while (a[++i] < a[right])
8783                                // find item on left to swap
8784                                ; // a[right] acts as sentinel
8785                        while (a[right] < a[--j])
8786                                // find item on right to swap
8787                                if (j == left)
8788                                        break; // don't go out-of-bounds
8789                        if (i >= j)
8790                                break; // check if pointers cross
8791                        exch(a, index, i, j); // swap two elements into place
8792                }
8793                exch(a, index, i, right); // swap with partition element
8794                return i;
8795        }
8796
8797    
8798    /**
8799         * Sort parallel arrays. Arrays are sorted in-place. The first array
8800         * determines the order, and is sorted into ascending order.
8801         * <p>
8802         * Implementation inspired by this stackoverflow page: <a href=
8803         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8804         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8805         * get-a-sorted-list-of-indices-of-an-array </a>
8806         * 
8807         * @param main
8808         *            the values to use for determining the order
8809         * @param indices
8810         *            the second array
8811         */
8812        public static void parallelQuicksortAscending(final byte[] main, final double[] indices) {
8813                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
8814        }
8815        
8816    /**
8817         * Sort parallel arrays. Arrays are sorted in-place. The first array
8818         * determines the order, and is sorted into ascending order.
8819         * <p>
8820         * Implementation inspired by this stackoverflow page: <a href=
8821         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8822         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8823         * get-a-sorted-list-of-indices-of-an-array </a>
8824         * 
8825         * @param main
8826         *            the values to use for determining the order
8827         * @param indices
8828         *            the second array
8829         * @param left
8830         *            the starting index
8831         * @param right
8832         *            the ending index
8833         */
8834        public static void
8835                        parallelQuicksortAscending(final byte[] main, final double[] indices, final int left, final int right)
8836        {
8837                if (right <= left)
8838                        return;
8839
8840                final int i = partitionAsc(main, indices, left, right);
8841
8842                parallelQuicksortAscending(main, indices, left, i - 1);
8843                parallelQuicksortAscending(main, indices, i + 1, right);
8844        }
8845
8846        // partition a[left] to a[right], assumes left < right
8847        private static int partitionAsc(final byte[] a, final double[] index, final int left, final int right) {
8848                int i = left - 1;
8849                int j = right;
8850                while (true) {
8851                        while (a[++i] < a[right])
8852                                // find item on left to swap
8853                                ; // a[right] acts as sentinel
8854                        while (a[right] < a[--j])
8855                                // find item on right to swap
8856                                if (j == left)
8857                                        break; // don't go out-of-bounds
8858                        if (i >= j)
8859                                break; // check if pointers cross
8860                        exch(a, index, i, j); // swap two elements into place
8861                }
8862                exch(a, index, i, right); // swap with partition element
8863                return i;
8864        }
8865
8866    
8867    /**
8868         * Sort parallel arrays. Arrays are sorted in-place. The first array
8869         * determines the order, and is sorted into ascending order.
8870         * <p>
8871         * Implementation inspired by this stackoverflow page: <a href=
8872         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8873         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8874         * get-a-sorted-list-of-indices-of-an-array </a>
8875         * 
8876         * @param main
8877         *            the values to use for determining the order
8878         * @param indices
8879         *            the second array
8880         */
8881        public static void parallelQuicksortAscending(final byte[] main, final float[] indices) {
8882                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
8883        }
8884        
8885    /**
8886         * Sort parallel arrays. Arrays are sorted in-place. The first array
8887         * determines the order, and is sorted into ascending order.
8888         * <p>
8889         * Implementation inspired by this stackoverflow page: <a href=
8890         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8891         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8892         * get-a-sorted-list-of-indices-of-an-array </a>
8893         * 
8894         * @param main
8895         *            the values to use for determining the order
8896         * @param indices
8897         *            the second array
8898         * @param left
8899         *            the starting index
8900         * @param right
8901         *            the ending index
8902         */
8903        public static void
8904                        parallelQuicksortAscending(final byte[] main, final float[] indices, final int left, final int right)
8905        {
8906                if (right <= left)
8907                        return;
8908
8909                final int i = partitionAsc(main, indices, left, right);
8910
8911                parallelQuicksortAscending(main, indices, left, i - 1);
8912                parallelQuicksortAscending(main, indices, i + 1, right);
8913        }
8914
8915        // partition a[left] to a[right], assumes left < right
8916        private static int partitionAsc(final byte[] a, final float[] index, final int left, final int right) {
8917                int i = left - 1;
8918                int j = right;
8919                while (true) {
8920                        while (a[++i] < a[right])
8921                                // find item on left to swap
8922                                ; // a[right] acts as sentinel
8923                        while (a[right] < a[--j])
8924                                // find item on right to swap
8925                                if (j == left)
8926                                        break; // don't go out-of-bounds
8927                        if (i >= j)
8928                                break; // check if pointers cross
8929                        exch(a, index, i, j); // swap two elements into place
8930                }
8931                exch(a, index, i, right); // swap with partition element
8932                return i;
8933        }
8934
8935    
8936    /**
8937         * Sort parallel arrays. Arrays are sorted in-place. The first array
8938         * determines the order, and is sorted into ascending order.
8939         * <p>
8940         * Implementation inspired by this stackoverflow page: <a href=
8941         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8942         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8943         * get-a-sorted-list-of-indices-of-an-array </a>
8944         * 
8945         * @param main
8946         *            the values to use for determining the order
8947         * @param indices
8948         *            the second array
8949         */
8950        public static void parallelQuicksortAscending(final byte[] main, final int[] indices) {
8951                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
8952        }
8953        
8954    /**
8955         * Sort parallel arrays. Arrays are sorted in-place. The first array
8956         * determines the order, and is sorted into ascending order.
8957         * <p>
8958         * Implementation inspired by this stackoverflow page: <a href=
8959         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
8960         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
8961         * get-a-sorted-list-of-indices-of-an-array </a>
8962         * 
8963         * @param main
8964         *            the values to use for determining the order
8965         * @param indices
8966         *            the second array
8967         * @param left
8968         *            the starting index
8969         * @param right
8970         *            the ending index
8971         */
8972        public static void
8973                        parallelQuicksortAscending(final byte[] main, final int[] indices, final int left, final int right)
8974        {
8975                if (right <= left)
8976                        return;
8977
8978                final int i = partitionAsc(main, indices, left, right);
8979
8980                parallelQuicksortAscending(main, indices, left, i - 1);
8981                parallelQuicksortAscending(main, indices, i + 1, right);
8982        }
8983
8984        // partition a[left] to a[right], assumes left < right
8985        private static int partitionAsc(final byte[] a, final int[] index, final int left, final int right) {
8986                int i = left - 1;
8987                int j = right;
8988                while (true) {
8989                        while (a[++i] < a[right])
8990                                // find item on left to swap
8991                                ; // a[right] acts as sentinel
8992                        while (a[right] < a[--j])
8993                                // find item on right to swap
8994                                if (j == left)
8995                                        break; // don't go out-of-bounds
8996                        if (i >= j)
8997                                break; // check if pointers cross
8998                        exch(a, index, i, j); // swap two elements into place
8999                }
9000                exch(a, index, i, right); // swap with partition element
9001                return i;
9002        }
9003
9004    
9005    /**
9006         * Sort parallel arrays. Arrays are sorted in-place. The first array
9007         * determines the order, and is sorted into ascending order.
9008         * <p>
9009         * Implementation inspired by this stackoverflow page: <a href=
9010         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
9011         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
9012         * get-a-sorted-list-of-indices-of-an-array </a>
9013         * 
9014         * @param main
9015         *            the values to use for determining the order
9016         * @param indices
9017         *            the second array
9018         */
9019        public static void parallelQuicksortAscending(final byte[] main, final long[] indices) {
9020                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
9021        }
9022        
9023    /**
9024         * Sort parallel arrays. Arrays are sorted in-place. The first array
9025         * determines the order, and is sorted into ascending order.
9026         * <p>
9027         * Implementation inspired by this stackoverflow page: <a href=
9028         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
9029         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
9030         * get-a-sorted-list-of-indices-of-an-array </a>
9031         * 
9032         * @param main
9033         *            the values to use for determining the order
9034         * @param indices
9035         *            the second array
9036         * @param left
9037         *            the starting index
9038         * @param right
9039         *            the ending index
9040         */
9041        public static void
9042                        parallelQuicksortAscending(final byte[] main, final long[] indices, final int left, final int right)
9043        {
9044                if (right <= left)
9045                        return;
9046
9047                final int i = partitionAsc(main, indices, left, right);
9048
9049                parallelQuicksortAscending(main, indices, left, i - 1);
9050                parallelQuicksortAscending(main, indices, i + 1, right);
9051        }
9052
9053        // partition a[left] to a[right], assumes left < right
9054        private static int partitionAsc(final byte[] a, final long[] index, final int left, final int right) {
9055                int i = left - 1;
9056                int j = right;
9057                while (true) {
9058                        while (a[++i] < a[right])
9059                                // find item on left to swap
9060                                ; // a[right] acts as sentinel
9061                        while (a[right] < a[--j])
9062                                // find item on right to swap
9063                                if (j == left)
9064                                        break; // don't go out-of-bounds
9065                        if (i >= j)
9066                                break; // check if pointers cross
9067                        exch(a, index, i, j); // swap two elements into place
9068                }
9069                exch(a, index, i, right); // swap with partition element
9070                return i;
9071        }
9072
9073    
9074    /**
9075         * Sort parallel arrays. Arrays are sorted in-place. The first array
9076         * determines the order, and is sorted into ascending order.
9077         * <p>
9078         * Implementation inspired by this stackoverflow page: <a href=
9079         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
9080         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
9081         * get-a-sorted-list-of-indices-of-an-array </a>
9082         * 
9083         * @param main
9084         *            the values to use for determining the order
9085         * @param indices
9086         *            the second array
9087         */
9088        public static void parallelQuicksortAscending(final byte[] main, final byte[] indices) {
9089                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
9090        }
9091        
9092    /**
9093         * Sort parallel arrays. Arrays are sorted in-place. The first array
9094         * determines the order, and is sorted into ascending order.
9095         * <p>
9096         * Implementation inspired by this stackoverflow page: <a href=
9097         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
9098         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
9099         * get-a-sorted-list-of-indices-of-an-array </a>
9100         * 
9101         * @param main
9102         *            the values to use for determining the order
9103         * @param indices
9104         *            the second array
9105         * @param left
9106         *            the starting index
9107         * @param right
9108         *            the ending index
9109         */
9110        public static void
9111                        parallelQuicksortAscending(final byte[] main, final byte[] indices, final int left, final int right)
9112        {
9113                if (right <= left)
9114                        return;
9115
9116                final int i = partitionAsc(main, indices, left, right);
9117
9118                parallelQuicksortAscending(main, indices, left, i - 1);
9119                parallelQuicksortAscending(main, indices, i + 1, right);
9120        }
9121
9122        // partition a[left] to a[right], assumes left < right
9123        private static int partitionAsc(final byte[] a, final byte[] index, final int left, final int right) {
9124                int i = left - 1;
9125                int j = right;
9126                while (true) {
9127                        while (a[++i] < a[right])
9128                                // find item on left to swap
9129                                ; // a[right] acts as sentinel
9130                        while (a[right] < a[--j])
9131                                // find item on right to swap
9132                                if (j == left)
9133                                        break; // don't go out-of-bounds
9134                        if (i >= j)
9135                                break; // check if pointers cross
9136                        exch(a, index, i, j); // swap two elements into place
9137                }
9138                exch(a, index, i, right); // swap with partition element
9139                return i;
9140        }
9141
9142    
9143    /**
9144         * Sort parallel arrays. Arrays are sorted in-place. The first array
9145         * determines the order, and is sorted into ascending order.
9146         * <p>
9147         * Implementation inspired by this stackoverflow page: <a href=
9148         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
9149         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
9150         * get-a-sorted-list-of-indices-of-an-array </a>
9151         * 
9152         * @param main
9153         *            the values to use for determining the order
9154         * @param indices
9155         *            the second array
9156         */
9157        public static void parallelQuicksortAscending(final byte[] main, final short[] indices) {
9158                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
9159        }
9160        
9161    /**
9162         * Sort parallel arrays. Arrays are sorted in-place. The first array
9163         * determines the order, and is sorted into ascending order.
9164         * <p>
9165         * Implementation inspired by this stackoverflow page: <a href=
9166         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
9167         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
9168         * get-a-sorted-list-of-indices-of-an-array </a>
9169         * 
9170         * @param main
9171         *            the values to use for determining the order
9172         * @param indices
9173         *            the second array
9174         * @param left
9175         *            the starting index
9176         * @param right
9177         *            the ending index
9178         */
9179        public static void
9180                        parallelQuicksortAscending(final byte[] main, final short[] indices, final int left, final int right)
9181        {
9182                if (right <= left)
9183                        return;
9184
9185                final int i = partitionAsc(main, indices, left, right);
9186
9187                parallelQuicksortAscending(main, indices, left, i - 1);
9188                parallelQuicksortAscending(main, indices, i + 1, right);
9189        }
9190
9191        // partition a[left] to a[right], assumes left < right
9192        private static int partitionAsc(final byte[] a, final short[] index, final int left, final int right) {
9193                int i = left - 1;
9194                int j = right;
9195                while (true) {
9196                        while (a[++i] < a[right])
9197                                // find item on left to swap
9198                                ; // a[right] acts as sentinel
9199                        while (a[right] < a[--j])
9200                                // find item on right to swap
9201                                if (j == left)
9202                                        break; // don't go out-of-bounds
9203                        if (i >= j)
9204                                break; // check if pointers cross
9205                        exch(a, index, i, j); // swap two elements into place
9206                }
9207                exch(a, index, i, right); // swap with partition element
9208                return i;
9209        }
9210
9211    
9212    /**
9213         * Sort parallel arrays. Arrays are sorted in-place. The first array
9214         * determines the order, and is sorted into ascending order.
9215         * <p>
9216         * Implementation inspired by this stackoverflow page: <a href=
9217         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
9218         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
9219         * get-a-sorted-list-of-indices-of-an-array </a>
9220         * 
9221         * @param main
9222         *            the values to use for determining the order
9223         * @param indices
9224         *            the second array
9225         */
9226        public static void parallelQuicksortAscending(final short[] main, final double[] indices) {
9227                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
9228        }
9229        
9230    /**
9231         * Sort parallel arrays. Arrays are sorted in-place. The first array
9232         * determines the order, and is sorted into ascending order.
9233         * <p>
9234         * Implementation inspired by this stackoverflow page: <a href=
9235         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
9236         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
9237         * get-a-sorted-list-of-indices-of-an-array </a>
9238         * 
9239         * @param main
9240         *            the values to use for determining the order
9241         * @param indices
9242         *            the second array
9243         * @param left
9244         *            the starting index
9245         * @param right
9246         *            the ending index
9247         */
9248        public static void
9249                        parallelQuicksortAscending(final short[] main, final double[] indices, final int left, final int right)
9250        {
9251                if (right <= left)
9252                        return;
9253
9254                final int i = partitionAsc(main, indices, left, right);
9255
9256                parallelQuicksortAscending(main, indices, left, i - 1);
9257                parallelQuicksortAscending(main, indices, i + 1, right);
9258        }
9259
9260        // partition a[left] to a[right], assumes left < right
9261        private static int partitionAsc(final short[] a, final double[] index, final int left, final int right) {
9262                int i = left - 1;
9263                int j = right;
9264                while (true) {
9265                        while (a[++i] < a[right])
9266                                // find item on left to swap
9267                                ; // a[right] acts as sentinel
9268                        while (a[right] < a[--j])
9269                                // find item on right to swap
9270                                if (j == left)
9271                                        break; // don't go out-of-bounds
9272                        if (i >= j)
9273                                break; // check if pointers cross
9274                        exch(a, index, i, j); // swap two elements into place
9275                }
9276                exch(a, index, i, right); // swap with partition element
9277                return i;
9278        }
9279
9280    
9281    /**
9282         * Sort parallel arrays. Arrays are sorted in-place. The first array
9283         * determines the order, and is sorted into ascending order.
9284         * <p>
9285         * Implementation inspired by this stackoverflow page: <a href=
9286         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
9287         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
9288         * get-a-sorted-list-of-indices-of-an-array </a>
9289         * 
9290         * @param main
9291         *            the values to use for determining the order
9292         * @param indices
9293         *            the second array
9294         */
9295        public static void parallelQuicksortAscending(final short[] main, final float[] indices) {
9296                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
9297        }
9298        
9299    /**
9300         * Sort parallel arrays. Arrays are sorted in-place. The first array
9301         * determines the order, and is sorted into ascending order.
9302         * <p>
9303         * Implementation inspired by this stackoverflow page: <a href=
9304         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
9305         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
9306         * get-a-sorted-list-of-indices-of-an-array </a>
9307         * 
9308         * @param main
9309         *            the values to use for determining the order
9310         * @param indices
9311         *            the second array
9312         * @param left
9313         *            the starting index
9314         * @param right
9315         *            the ending index
9316         */
9317        public static void
9318                        parallelQuicksortAscending(final short[] main, final float[] indices, final int left, final int right)
9319        {
9320                if (right <= left)
9321                        return;
9322
9323                final int i = partitionAsc(main, indices, left, right);
9324
9325                parallelQuicksortAscending(main, indices, left, i - 1);
9326                parallelQuicksortAscending(main, indices, i + 1, right);
9327        }
9328
9329        // partition a[left] to a[right], assumes left < right
9330        private static int partitionAsc(final short[] a, final float[] index, final int left, final int right) {
9331                int i = left - 1;
9332                int j = right;
9333                while (true) {
9334                        while (a[++i] < a[right])
9335                                // find item on left to swap
9336                                ; // a[right] acts as sentinel
9337                        while (a[right] < a[--j])
9338                                // find item on right to swap
9339                                if (j == left)
9340                                        break; // don't go out-of-bounds
9341                        if (i >= j)
9342                                break; // check if pointers cross
9343                        exch(a, index, i, j); // swap two elements into place
9344                }
9345                exch(a, index, i, right); // swap with partition element
9346                return i;
9347        }
9348
9349    
9350    /**
9351         * Sort parallel arrays. Arrays are sorted in-place. The first array
9352         * determines the order, and is sorted into ascending order.
9353         * <p>
9354         * Implementation inspired by this stackoverflow page: <a href=
9355         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
9356         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
9357         * get-a-sorted-list-of-indices-of-an-array </a>
9358         * 
9359         * @param main
9360         *            the values to use for determining the order
9361         * @param indices
9362         *            the second array
9363         */
9364        public static void parallelQuicksortAscending(final short[] main, final int[] indices) {
9365                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
9366        }
9367        
9368    /**
9369         * Sort parallel arrays. Arrays are sorted in-place. The first array
9370         * determines the order, and is sorted into ascending order.
9371         * <p>
9372         * Implementation inspired by this stackoverflow page: <a href=
9373         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
9374         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
9375         * get-a-sorted-list-of-indices-of-an-array </a>
9376         * 
9377         * @param main
9378         *            the values to use for determining the order
9379         * @param indices
9380         *            the second array
9381         * @param left
9382         *            the starting index
9383         * @param right
9384         *            the ending index
9385         */
9386        public static void
9387                        parallelQuicksortAscending(final short[] main, final int[] indices, final int left, final int right)
9388        {
9389                if (right <= left)
9390                        return;
9391
9392                final int i = partitionAsc(main, indices, left, right);
9393
9394                parallelQuicksortAscending(main, indices, left, i - 1);
9395                parallelQuicksortAscending(main, indices, i + 1, right);
9396        }
9397
9398        // partition a[left] to a[right], assumes left < right
9399        private static int partitionAsc(final short[] a, final int[] index, final int left, final int right) {
9400                int i = left - 1;
9401                int j = right;
9402                while (true) {
9403                        while (a[++i] < a[right])
9404                                // find item on left to swap
9405                                ; // a[right] acts as sentinel
9406                        while (a[right] < a[--j])
9407                                // find item on right to swap
9408                                if (j == left)
9409                                        break; // don't go out-of-bounds
9410                        if (i >= j)
9411                                break; // check if pointers cross
9412                        exch(a, index, i, j); // swap two elements into place
9413                }
9414                exch(a, index, i, right); // swap with partition element
9415                return i;
9416        }
9417
9418    
9419    /**
9420         * Sort parallel arrays. Arrays are sorted in-place. The first array
9421         * determines the order, and is sorted into ascending order.
9422         * <p>
9423         * Implementation inspired by this stackoverflow page: <a href=
9424         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
9425         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
9426         * get-a-sorted-list-of-indices-of-an-array </a>
9427         * 
9428         * @param main
9429         *            the values to use for determining the order
9430         * @param indices
9431         *            the second array
9432         */
9433        public static void parallelQuicksortAscending(final short[] main, final long[] indices) {
9434                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
9435        }
9436        
9437    /**
9438         * Sort parallel arrays. Arrays are sorted in-place. The first array
9439         * determines the order, and is sorted into ascending order.
9440         * <p>
9441         * Implementation inspired by this stackoverflow page: <a href=
9442         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
9443         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
9444         * get-a-sorted-list-of-indices-of-an-array </a>
9445         * 
9446         * @param main
9447         *            the values to use for determining the order
9448         * @param indices
9449         *            the second array
9450         * @param left
9451         *            the starting index
9452         * @param right
9453         *            the ending index
9454         */
9455        public static void
9456                        parallelQuicksortAscending(final short[] main, final long[] indices, final int left, final int right)
9457        {
9458                if (right <= left)
9459                        return;
9460
9461                final int i = partitionAsc(main, indices, left, right);
9462
9463                parallelQuicksortAscending(main, indices, left, i - 1);
9464                parallelQuicksortAscending(main, indices, i + 1, right);
9465        }
9466
9467        // partition a[left] to a[right], assumes left < right
9468        private static int partitionAsc(final short[] a, final long[] index, final int left, final int right) {
9469                int i = left - 1;
9470                int j = right;
9471                while (true) {
9472                        while (a[++i] < a[right])
9473                                // find item on left to swap
9474                                ; // a[right] acts as sentinel
9475                        while (a[right] < a[--j])
9476                                // find item on right to swap
9477                                if (j == left)
9478                                        break; // don't go out-of-bounds
9479                        if (i >= j)
9480                                break; // check if pointers cross
9481                        exch(a, index, i, j); // swap two elements into place
9482                }
9483                exch(a, index, i, right); // swap with partition element
9484                return i;
9485        }
9486
9487    
9488    /**
9489         * Sort parallel arrays. Arrays are sorted in-place. The first array
9490         * determines the order, and is sorted into ascending order.
9491         * <p>
9492         * Implementation inspired by this stackoverflow page: <a href=
9493         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
9494         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
9495         * get-a-sorted-list-of-indices-of-an-array </a>
9496         * 
9497         * @param main
9498         *            the values to use for determining the order
9499         * @param indices
9500         *            the second array
9501         */
9502        public static void parallelQuicksortAscending(final short[] main, final byte[] indices) {
9503                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
9504        }
9505        
9506    /**
9507         * Sort parallel arrays. Arrays are sorted in-place. The first array
9508         * determines the order, and is sorted into ascending order.
9509         * <p>
9510         * Implementation inspired by this stackoverflow page: <a href=
9511         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
9512         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
9513         * get-a-sorted-list-of-indices-of-an-array </a>
9514         * 
9515         * @param main
9516         *            the values to use for determining the order
9517         * @param indices
9518         *            the second array
9519         * @param left
9520         *            the starting index
9521         * @param right
9522         *            the ending index
9523         */
9524        public static void
9525                        parallelQuicksortAscending(final short[] main, final byte[] indices, final int left, final int right)
9526        {
9527                if (right <= left)
9528                        return;
9529
9530                final int i = partitionAsc(main, indices, left, right);
9531
9532                parallelQuicksortAscending(main, indices, left, i - 1);
9533                parallelQuicksortAscending(main, indices, i + 1, right);
9534        }
9535
9536        // partition a[left] to a[right], assumes left < right
9537        private static int partitionAsc(final short[] a, final byte[] index, final int left, final int right) {
9538                int i = left - 1;
9539                int j = right;
9540                while (true) {
9541                        while (a[++i] < a[right])
9542                                // find item on left to swap
9543                                ; // a[right] acts as sentinel
9544                        while (a[right] < a[--j])
9545                                // find item on right to swap
9546                                if (j == left)
9547                                        break; // don't go out-of-bounds
9548                        if (i >= j)
9549                                break; // check if pointers cross
9550                        exch(a, index, i, j); // swap two elements into place
9551                }
9552                exch(a, index, i, right); // swap with partition element
9553                return i;
9554        }
9555
9556    
9557    /**
9558         * Sort parallel arrays. Arrays are sorted in-place. The first array
9559         * determines the order, and is sorted into ascending order.
9560         * <p>
9561         * Implementation inspired by this stackoverflow page: <a href=
9562         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
9563         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
9564         * get-a-sorted-list-of-indices-of-an-array </a>
9565         * 
9566         * @param main
9567         *            the values to use for determining the order
9568         * @param indices
9569         *            the second array
9570         */
9571        public static void parallelQuicksortAscending(final short[] main, final short[] indices) {
9572                ArrayUtils.parallelQuicksortAscending(main, indices, 0, indices.length - 1);
9573        }
9574        
9575    /**
9576         * Sort parallel arrays. Arrays are sorted in-place. The first array
9577         * determines the order, and is sorted into ascending order.
9578         * <p>
9579         * Implementation inspired by this stackoverflow page: <a href=
9580         * "http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-get-a-sorted-list-of-indices-of-an-array"
9581         * > http://stackoverflow.com/questions/951848/java-array-sort-quick-way-to-
9582         * get-a-sorted-list-of-indices-of-an-array </a>
9583         * 
9584         * @param main
9585         *            the values to use for determining the order
9586         * @param indices
9587         *            the second array
9588         * @param left
9589         *            the starting index
9590         * @param right
9591         *            the ending index
9592         */
9593        public static void
9594                        parallelQuicksortAscending(final short[] main, final short[] indices, final int left, final int right)
9595        {
9596                if (right <= left)
9597                        return;
9598
9599                final int i = partitionAsc(main, indices, left, right);
9600
9601                parallelQuicksortAscending(main, indices, left, i - 1);
9602                parallelQuicksortAscending(main, indices, i + 1, right);
9603        }
9604
9605        // partition a[left] to a[right], assumes left < right
9606        private static int partitionAsc(final short[] a, final short[] index, final int left, final int right) {
9607                int i = left - 1;
9608                int j = right;
9609                while (true) {
9610                        while (a[++i] < a[right])
9611                                // find item on left to swap
9612                                ; // a[right] acts as sentinel
9613                        while (a[right] < a[--j])
9614                                // find item on right to swap
9615                                if (j == left)
9616                                        break; // don't go out-of-bounds
9617                        if (i >= j)
9618                                break; // check if pointers cross
9619                        exch(a, index, i, j); // swap two elements into place
9620                }
9621                exch(a, index, i, right); // swap with partition element
9622                return i;
9623        }
9624
9625    
9626    // exchange a[i] and a[j]
9627        private static void exch(final double[] a, final double[] index, final int i, final int j) {
9628                final double swap = a[i];
9629                a[i] = a[j];
9630                a[j] = swap;
9631
9632                final double b = index[i];
9633                index[i] = index[j];
9634                index[j] = b;
9635        }
9636
9637    
9638    // exchange a[i] and a[j]
9639        private static void exch(final double[] a, final float[] index, final int i, final int j) {
9640                final double swap = a[i];
9641                a[i] = a[j];
9642                a[j] = swap;
9643
9644                final float b = index[i];
9645                index[i] = index[j];
9646                index[j] = b;
9647        }
9648
9649    
9650    // exchange a[i] and a[j]
9651        private static void exch(final double[] a, final int[] index, final int i, final int j) {
9652                final double swap = a[i];
9653                a[i] = a[j];
9654                a[j] = swap;
9655
9656                final int b = index[i];
9657                index[i] = index[j];
9658                index[j] = b;
9659        }
9660
9661    
9662    // exchange a[i] and a[j]
9663        private static void exch(final double[] a, final long[] index, final int i, final int j) {
9664                final double swap = a[i];
9665                a[i] = a[j];
9666                a[j] = swap;
9667
9668                final long b = index[i];
9669                index[i] = index[j];
9670                index[j] = b;
9671        }
9672
9673    
9674    // exchange a[i] and a[j]
9675        private static void exch(final double[] a, final byte[] index, final int i, final int j) {
9676                final double swap = a[i];
9677                a[i] = a[j];
9678                a[j] = swap;
9679
9680                final byte b = index[i];
9681                index[i] = index[j];
9682                index[j] = b;
9683        }
9684
9685    
9686    // exchange a[i] and a[j]
9687        private static void exch(final double[] a, final short[] index, final int i, final int j) {
9688                final double swap = a[i];
9689                a[i] = a[j];
9690                a[j] = swap;
9691
9692                final short b = index[i];
9693                index[i] = index[j];
9694                index[j] = b;
9695        }
9696
9697    
9698    // exchange a[i] and a[j]
9699        private static void exch(final float[] a, final double[] index, final int i, final int j) {
9700                final float swap = a[i];
9701                a[i] = a[j];
9702                a[j] = swap;
9703
9704                final double b = index[i];
9705                index[i] = index[j];
9706                index[j] = b;
9707        }
9708
9709    
9710    // exchange a[i] and a[j]
9711        private static void exch(final float[] a, final float[] index, final int i, final int j) {
9712                final float swap = a[i];
9713                a[i] = a[j];
9714                a[j] = swap;
9715
9716                final float b = index[i];
9717                index[i] = index[j];
9718                index[j] = b;
9719        }
9720
9721    
9722    // exchange a[i] and a[j]
9723        private static void exch(final float[] a, final int[] index, final int i, final int j) {
9724                final float swap = a[i];
9725                a[i] = a[j];
9726                a[j] = swap;
9727
9728                final int b = index[i];
9729                index[i] = index[j];
9730                index[j] = b;
9731        }
9732
9733    
9734    // exchange a[i] and a[j]
9735        private static void exch(final float[] a, final long[] index, final int i, final int j) {
9736                final float swap = a[i];
9737                a[i] = a[j];
9738                a[j] = swap;
9739
9740                final long b = index[i];
9741                index[i] = index[j];
9742                index[j] = b;
9743        }
9744
9745    
9746    // exchange a[i] and a[j]
9747        private static void exch(final float[] a, final byte[] index, final int i, final int j) {
9748                final float swap = a[i];
9749                a[i] = a[j];
9750                a[j] = swap;
9751
9752                final byte b = index[i];
9753                index[i] = index[j];
9754                index[j] = b;
9755        }
9756
9757    
9758    // exchange a[i] and a[j]
9759        private static void exch(final float[] a, final short[] index, final int i, final int j) {
9760                final float swap = a[i];
9761                a[i] = a[j];
9762                a[j] = swap;
9763
9764                final short b = index[i];
9765                index[i] = index[j];
9766                index[j] = b;
9767        }
9768
9769    
9770    // exchange a[i] and a[j]
9771        private static void exch(final int[] a, final double[] index, final int i, final int j) {
9772                final int swap = a[i];
9773                a[i] = a[j];
9774                a[j] = swap;
9775
9776                final double b = index[i];
9777                index[i] = index[j];
9778                index[j] = b;
9779        }
9780
9781    
9782    // exchange a[i] and a[j]
9783        private static void exch(final int[] a, final float[] index, final int i, final int j) {
9784                final int swap = a[i];
9785                a[i] = a[j];
9786                a[j] = swap;
9787
9788                final float b = index[i];
9789                index[i] = index[j];
9790                index[j] = b;
9791        }
9792
9793    
9794    // exchange a[i] and a[j]
9795        private static void exch(final int[] a, final int[] index, final int i, final int j) {
9796                final int swap = a[i];
9797                a[i] = a[j];
9798                a[j] = swap;
9799
9800                final int b = index[i];
9801                index[i] = index[j];
9802                index[j] = b;
9803        }
9804
9805    
9806    // exchange a[i] and a[j]
9807        private static void exch(final int[] a, final long[] index, final int i, final int j) {
9808                final int swap = a[i];
9809                a[i] = a[j];
9810                a[j] = swap;
9811
9812                final long b = index[i];
9813                index[i] = index[j];
9814                index[j] = b;
9815        }
9816
9817    
9818    // exchange a[i] and a[j]
9819        private static void exch(final int[] a, final byte[] index, final int i, final int j) {
9820                final int swap = a[i];
9821                a[i] = a[j];
9822                a[j] = swap;
9823
9824                final byte b = index[i];
9825                index[i] = index[j];
9826                index[j] = b;
9827        }
9828
9829    
9830    // exchange a[i] and a[j]
9831        private static void exch(final int[] a, final short[] index, final int i, final int j) {
9832                final int swap = a[i];
9833                a[i] = a[j];
9834                a[j] = swap;
9835
9836                final short b = index[i];
9837                index[i] = index[j];
9838                index[j] = b;
9839        }
9840
9841    
9842    // exchange a[i] and a[j]
9843        private static void exch(final long[] a, final double[] index, final int i, final int j) {
9844                final long swap = a[i];
9845                a[i] = a[j];
9846                a[j] = swap;
9847
9848                final double b = index[i];
9849                index[i] = index[j];
9850                index[j] = b;
9851        }
9852
9853    
9854    // exchange a[i] and a[j]
9855        private static void exch(final long[] a, final float[] index, final int i, final int j) {
9856                final long swap = a[i];
9857                a[i] = a[j];
9858                a[j] = swap;
9859
9860                final float b = index[i];
9861                index[i] = index[j];
9862                index[j] = b;
9863        }
9864
9865    
9866    // exchange a[i] and a[j]
9867        private static void exch(final long[] a, final int[] index, final int i, final int j) {
9868                final long swap = a[i];
9869                a[i] = a[j];
9870                a[j] = swap;
9871
9872                final int b = index[i];
9873                index[i] = index[j];
9874                index[j] = b;
9875        }
9876
9877    
9878    // exchange a[i] and a[j]
9879        private static void exch(final long[] a, final long[] index, final int i, final int j) {
9880                final long swap = a[i];
9881                a[i] = a[j];
9882                a[j] = swap;
9883
9884                final long b = index[i];
9885                index[i] = index[j];
9886                index[j] = b;
9887        }
9888
9889    
9890    // exchange a[i] and a[j]
9891        private static void exch(final long[] a, final byte[] index, final int i, final int j) {
9892                final long swap = a[i];
9893                a[i] = a[j];
9894                a[j] = swap;
9895
9896                final byte b = index[i];
9897                index[i] = index[j];
9898                index[j] = b;
9899        }
9900
9901    
9902    // exchange a[i] and a[j]
9903        private static void exch(final long[] a, final short[] index, final int i, final int j) {
9904                final long swap = a[i];
9905                a[i] = a[j];
9906                a[j] = swap;
9907
9908                final short b = index[i];
9909                index[i] = index[j];
9910                index[j] = b;
9911        }
9912
9913    
9914    // exchange a[i] and a[j]
9915        private static void exch(final byte[] a, final double[] index, final int i, final int j) {
9916                final byte swap = a[i];
9917                a[i] = a[j];
9918                a[j] = swap;
9919
9920                final double b = index[i];
9921                index[i] = index[j];
9922                index[j] = b;
9923        }
9924
9925    
9926    // exchange a[i] and a[j]
9927        private static void exch(final byte[] a, final float[] index, final int i, final int j) {
9928                final byte swap = a[i];
9929                a[i] = a[j];
9930                a[j] = swap;
9931
9932                final float b = index[i];
9933                index[i] = index[j];
9934                index[j] = b;
9935        }
9936
9937    
9938    // exchange a[i] and a[j]
9939        private static void exch(final byte[] a, final int[] index, final int i, final int j) {
9940                final byte swap = a[i];
9941                a[i] = a[j];
9942                a[j] = swap;
9943
9944                final int b = index[i];
9945                index[i] = index[j];
9946                index[j] = b;
9947        }
9948
9949    
9950    // exchange a[i] and a[j]
9951        private static void exch(final byte[] a, final long[] index, final int i, final int j) {
9952                final byte swap = a[i];
9953                a[i] = a[j];
9954                a[j] = swap;
9955
9956                final long b = index[i];
9957                index[i] = index[j];
9958                index[j] = b;
9959        }
9960
9961    
9962    // exchange a[i] and a[j]
9963        private static void exch(final byte[] a, final byte[] index, final int i, final int j) {
9964                final byte swap = a[i];
9965                a[i] = a[j];
9966                a[j] = swap;
9967
9968                final byte b = index[i];
9969                index[i] = index[j];
9970                index[j] = b;
9971        }
9972
9973    
9974    // exchange a[i] and a[j]
9975        private static void exch(final byte[] a, final short[] index, final int i, final int j) {
9976                final byte swap = a[i];
9977                a[i] = a[j];
9978                a[j] = swap;
9979
9980                final short b = index[i];
9981                index[i] = index[j];
9982                index[j] = b;
9983        }
9984
9985    
9986    // exchange a[i] and a[j]
9987        private static void exch(final short[] a, final double[] index, final int i, final int j) {
9988                final short swap = a[i];
9989                a[i] = a[j];
9990                a[j] = swap;
9991
9992                final double b = index[i];
9993                index[i] = index[j];
9994                index[j] = b;
9995        }
9996
9997    
9998    // exchange a[i] and a[j]
9999        private static void exch(final short[] a, final float[] index, final int i, final int j) {
10000                final short swap = a[i];
10001                a[i] = a[j];
10002                a[j] = swap;
10003
10004                final float b = index[i];
10005                index[i] = index[j];
10006                index[j] = b;
10007        }
10008
10009    
10010    // exchange a[i] and a[j]
10011        private static void exch(final short[] a, final int[] index, final int i, final int j) {
10012                final short swap = a[i];
10013                a[i] = a[j];
10014                a[j] = swap;
10015
10016                final int b = index[i];
10017                index[i] = index[j];
10018                index[j] = b;
10019        }
10020
10021    
10022    // exchange a[i] and a[j]
10023        private static void exch(final short[] a, final long[] index, final int i, final int j) {
10024                final short swap = a[i];
10025                a[i] = a[j];
10026                a[j] = swap;
10027
10028                final long b = index[i];
10029                index[i] = index[j];
10030                index[j] = b;
10031        }
10032
10033    
10034    // exchange a[i] and a[j]
10035        private static void exch(final short[] a, final byte[] index, final int i, final int j) {
10036                final short swap = a[i];
10037                a[i] = a[j];
10038                a[j] = swap;
10039
10040                final byte b = index[i];
10041                index[i] = index[j];
10042                index[j] = b;
10043        }
10044
10045    
10046    // exchange a[i] and a[j]
10047        private static void exch(final short[] a, final short[] index, final int i, final int j) {
10048                final short swap = a[i];
10049                a[i] = a[j];
10050                a[j] = swap;
10051
10052                final short b = index[i];
10053                index[i] = index[j];
10054                index[j] = b;
10055        }
10056
10057    
10058        /**
10059         * Determine the indices of the given array if it were to be sorted into
10060         * ascending order.
10061         * 
10062         * @param arr
10063         *            the array
10064         * @return the sorted indices
10065         */
10066        public static int[] indexSort(final double[] arr) {
10067                final int[] index = new int[arr.length];
10068
10069                for (int i = 0; i < index.length; i++)
10070                        index[i] = i;
10071
10072                quicksort(arr, index, 0, index.length - 1);
10073
10074                return index;
10075        }
10076
10077        // quicksort a[left] to a[right]
10078        private static void quicksort(final double[] a, final int[] index, final int left, final int right) {
10079                if (right <= left)
10080                        return;
10081                final int i = partition(a, index, left, right);
10082                quicksort(a, index, left, i - 1);
10083                quicksort(a, index, i + 1, right);
10084        }
10085
10086        // partition a[left] to a[right], assumes left < right
10087        private static int partition(final double[] a, final int[] index,
10088                        final int left, final int right)
10089        {
10090                int i = left - 1;
10091                int j = right;
10092                while (true) {
10093                        while (a[index[++i]] < a[index[right]])
10094                                // find item on left to swap
10095                                ; // a[right] acts as sentinel
10096                        while (a[index[right]] < a[index[--j]])
10097                                // find item on right to swap
10098                                if (j == left)
10099                                        break; // don't go out-of-bounds
10100                        if (i >= j)
10101                                break; // check if pointers cross
10102                        exch(index, i, j); // swap two elements into place
10103                }
10104                exch(index, i, right); // swap with partition element
10105                return i;
10106        }
10107
10108    
10109        /**
10110         * Determine the indices of the given array if it were to be sorted into
10111         * ascending order.
10112         * 
10113         * @param arr
10114         *            the array
10115         * @return the sorted indices
10116         */
10117        public static int[] indexSort(final float[] arr) {
10118                final int[] index = new int[arr.length];
10119
10120                for (int i = 0; i < index.length; i++)
10121                        index[i] = i;
10122
10123                quicksort(arr, index, 0, index.length - 1);
10124
10125                return index;
10126        }
10127
10128        // quicksort a[left] to a[right]
10129        private static void quicksort(final float[] a, final int[] index, final int left, final int right) {
10130                if (right <= left)
10131                        return;
10132                final int i = partition(a, index, left, right);
10133                quicksort(a, index, left, i - 1);
10134                quicksort(a, index, i + 1, right);
10135        }
10136
10137        // partition a[left] to a[right], assumes left < right
10138        private static int partition(final float[] a, final int[] index,
10139                        final int left, final int right)
10140        {
10141                int i = left - 1;
10142                int j = right;
10143                while (true) {
10144                        while (a[index[++i]] < a[index[right]])
10145                                // find item on left to swap
10146                                ; // a[right] acts as sentinel
10147                        while (a[index[right]] < a[index[--j]])
10148                                // find item on right to swap
10149                                if (j == left)
10150                                        break; // don't go out-of-bounds
10151                        if (i >= j)
10152                                break; // check if pointers cross
10153                        exch(index, i, j); // swap two elements into place
10154                }
10155                exch(index, i, right); // swap with partition element
10156                return i;
10157        }
10158
10159    
10160        /**
10161         * Determine the indices of the given array if it were to be sorted into
10162         * ascending order.
10163         * 
10164         * @param arr
10165         *            the array
10166         * @return the sorted indices
10167         */
10168        public static int[] indexSort(final int[] arr) {
10169                final int[] index = new int[arr.length];
10170
10171                for (int i = 0; i < index.length; i++)
10172                        index[i] = i;
10173
10174                quicksort(arr, index, 0, index.length - 1);
10175
10176                return index;
10177        }
10178
10179        // quicksort a[left] to a[right]
10180        private static void quicksort(final int[] a, final int[] index, final int left, final int right) {
10181                if (right <= left)
10182                        return;
10183                final int i = partition(a, index, left, right);
10184                quicksort(a, index, left, i - 1);
10185                quicksort(a, index, i + 1, right);
10186        }
10187
10188        // partition a[left] to a[right], assumes left < right
10189        private static int partition(final int[] a, final int[] index,
10190                        final int left, final int right)
10191        {
10192                int i = left - 1;
10193                int j = right;
10194                while (true) {
10195                        while (a[index[++i]] < a[index[right]])
10196                                // find item on left to swap
10197                                ; // a[right] acts as sentinel
10198                        while (a[index[right]] < a[index[--j]])
10199                                // find item on right to swap
10200                                if (j == left)
10201                                        break; // don't go out-of-bounds
10202                        if (i >= j)
10203                                break; // check if pointers cross
10204                        exch(index, i, j); // swap two elements into place
10205                }
10206                exch(index, i, right); // swap with partition element
10207                return i;
10208        }
10209
10210    
10211        /**
10212         * Determine the indices of the given array if it were to be sorted into
10213         * ascending order.
10214         * 
10215         * @param arr
10216         *            the array
10217         * @return the sorted indices
10218         */
10219        public static int[] indexSort(final long[] arr) {
10220                final int[] index = new int[arr.length];
10221
10222                for (int i = 0; i < index.length; i++)
10223                        index[i] = i;
10224
10225                quicksort(arr, index, 0, index.length - 1);
10226
10227                return index;
10228        }
10229
10230        // quicksort a[left] to a[right]
10231        private static void quicksort(final long[] a, final int[] index, final int left, final int right) {
10232                if (right <= left)
10233                        return;
10234                final int i = partition(a, index, left, right);
10235                quicksort(a, index, left, i - 1);
10236                quicksort(a, index, i + 1, right);
10237        }
10238
10239        // partition a[left] to a[right], assumes left < right
10240        private static int partition(final long[] a, final int[] index,
10241                        final int left, final int right)
10242        {
10243                int i = left - 1;
10244                int j = right;
10245                while (true) {
10246                        while (a[index[++i]] < a[index[right]])
10247                                // find item on left to swap
10248                                ; // a[right] acts as sentinel
10249                        while (a[index[right]] < a[index[--j]])
10250                                // find item on right to swap
10251                                if (j == left)
10252                                        break; // don't go out-of-bounds
10253                        if (i >= j)
10254                                break; // check if pointers cross
10255                        exch(index, i, j); // swap two elements into place
10256                }
10257                exch(index, i, right); // swap with partition element
10258                return i;
10259        }
10260
10261    
10262        /**
10263         * Determine the indices of the given array if it were to be sorted into
10264         * ascending order.
10265         * 
10266         * @param arr
10267         *            the array
10268         * @return the sorted indices
10269         */
10270        public static int[] indexSort(final byte[] arr) {
10271                final int[] index = new int[arr.length];
10272
10273                for (int i = 0; i < index.length; i++)
10274                        index[i] = i;
10275
10276                quicksort(arr, index, 0, index.length - 1);
10277
10278                return index;
10279        }
10280
10281        // quicksort a[left] to a[right]
10282        private static void quicksort(final byte[] a, final int[] index, final int left, final int right) {
10283                if (right <= left)
10284                        return;
10285                final int i = partition(a, index, left, right);
10286                quicksort(a, index, left, i - 1);
10287                quicksort(a, index, i + 1, right);
10288        }
10289
10290        // partition a[left] to a[right], assumes left < right
10291        private static int partition(final byte[] a, final int[] index,
10292                        final int left, final int right)
10293        {
10294                int i = left - 1;
10295                int j = right;
10296                while (true) {
10297                        while (a[index[++i]] < a[index[right]])
10298                                // find item on left to swap
10299                                ; // a[right] acts as sentinel
10300                        while (a[index[right]] < a[index[--j]])
10301                                // find item on right to swap
10302                                if (j == left)
10303                                        break; // don't go out-of-bounds
10304                        if (i >= j)
10305                                break; // check if pointers cross
10306                        exch(index, i, j); // swap two elements into place
10307                }
10308                exch(index, i, right); // swap with partition element
10309                return i;
10310        }
10311
10312    
10313        /**
10314         * Determine the indices of the given array if it were to be sorted into
10315         * ascending order.
10316         * 
10317         * @param arr
10318         *            the array
10319         * @return the sorted indices
10320         */
10321        public static int[] indexSort(final short[] arr) {
10322                final int[] index = new int[arr.length];
10323
10324                for (int i = 0; i < index.length; i++)
10325                        index[i] = i;
10326
10327                quicksort(arr, index, 0, index.length - 1);
10328
10329                return index;
10330        }
10331
10332        // quicksort a[left] to a[right]
10333        private static void quicksort(final short[] a, final int[] index, final int left, final int right) {
10334                if (right <= left)
10335                        return;
10336                final int i = partition(a, index, left, right);
10337                quicksort(a, index, left, i - 1);
10338                quicksort(a, index, i + 1, right);
10339        }
10340
10341        // partition a[left] to a[right], assumes left < right
10342        private static int partition(final short[] a, final int[] index,
10343                        final int left, final int right)
10344        {
10345                int i = left - 1;
10346                int j = right;
10347                while (true) {
10348                        while (a[index[++i]] < a[index[right]])
10349                                // find item on left to swap
10350                                ; // a[right] acts as sentinel
10351                        while (a[index[right]] < a[index[--j]])
10352                                // find item on right to swap
10353                                if (j == left)
10354                                        break; // don't go out-of-bounds
10355                        if (i >= j)
10356                                break; // check if pointers cross
10357                        exch(index, i, j); // swap two elements into place
10358                }
10359                exch(index, i, right); // swap with partition element
10360                return i;
10361        }
10362
10363    
10364        // exchange a[i] and a[j]
10365        static void exch(final int[] index, final int i, final int j) {
10366                final int b = index[i];
10367                index[i] = index[j];
10368                index[j] = b;
10369        }
10370
10371    
10372        /**
10373         * Normalise and scale the values so that the maximum value in the array is
10374         * 1.
10375         * 
10376         * @param array
10377         *            The array to normalise
10378         * @return The array
10379         */
10380        public static double[] normaliseMax(final double[] array) {
10381                return normaliseMax(array, 1d);
10382        }
10383
10384        /**
10385         * Normalise and scale the values so that the maximum value in the array is
10386         * max
10387         * 
10388         * @param array
10389         *            The array to normalise
10390         * @param max
10391         *            The maximum value
10392         * @return The array
10393         */
10394        public static double[] normaliseMax(final double[] array, final double max) {
10395                final double m = maxValue(array);
10396                for (int i = 0; i < array.length; i++)
10397                        array[i] = (array[i] / m) * max;
10398                return array;
10399        }
10400
10401    
10402        /**
10403         * Convert the array to a {@link String} by joining the elements with the
10404         * given glue.
10405         * 
10406         * @param s
10407         *            the array
10408         * @param glue
10409         *            the glue
10410         * @return the string
10411         */
10412        public static String toString(final String[] s, final String glue) {
10413                final int k = s.length;
10414
10415                if (k == 0)
10416                        return null;
10417
10418                final StringBuilder out = new StringBuilder();
10419                out.append(s[0]);
10420
10421                for (int x = 1; x < k; ++x)
10422                        out.append(glue).append(s[x]);
10423
10424                return out.toString();
10425        }
10426
10427    
10428        /**
10429         * Fill the array with the value
10430         * 
10431         * @param a1
10432         *            The array
10433         * @param i
10434         *            The value
10435         * @return The array
10436         */
10437        public static double[][] fill(final double[][] a1, final double i)
10438        {
10439                for (int j = 0; j < a1.length; j++)
10440                        fill(a1[j], i);
10441                return a1;
10442        }
10443
10444        /**
10445         * Fill the array with the value from the start index for the length given
10446         * 
10447         * @param a1
10448         *            The array to fill
10449         * @param i
10450         *            The value to fill with
10451         * @param s
10452         *            The start index
10453         * @param l
10454         *            The length of the fill
10455         * @return The array
10456         */
10457        public static double[] fill(final double[] a1, final double i, final int s, final int l)
10458        {
10459                for (int j = s; j < s + l; j++)
10460                        a1[j] = i;
10461                return a1;
10462        }
10463
10464        /**
10465         * Fill the array with the value
10466         * 
10467         * @param a1
10468         *            The array
10469         * @param i
10470         *            The value
10471         * @return The array
10472         */
10473        public static double[] fill(final double[] a1, final double i)
10474        {
10475                for (int j = 0; j < a1.length; j++)
10476                        a1[j] = i;
10477                return a1;
10478        }
10479
10480    
10481        /**
10482         * Fill the array with the value
10483         * 
10484         * @param a1
10485         *            The array
10486         * @param i
10487         *            The value
10488         * @return The array
10489         */
10490        public static float[][] fill(final float[][] a1, final float i)
10491        {
10492                for (int j = 0; j < a1.length; j++)
10493                        fill(a1[j], i);
10494                return a1;
10495        }
10496
10497        /**
10498         * Fill the array with the value from the start index for the length given
10499         * 
10500         * @param a1
10501         *            The array to fill
10502         * @param i
10503         *            The value to fill with
10504         * @param s
10505         *            The start index
10506         * @param l
10507         *            The length of the fill
10508         * @return The array
10509         */
10510        public static float[] fill(final float[] a1, final float i, final int s, final int l)
10511        {
10512                for (int j = s; j < s + l; j++)
10513                        a1[j] = i;
10514                return a1;
10515        }
10516
10517        /**
10518         * Fill the array with the value
10519         * 
10520         * @param a1
10521         *            The array
10522         * @param i
10523         *            The value
10524         * @return The array
10525         */
10526        public static float[] fill(final float[] a1, final float i)
10527        {
10528                for (int j = 0; j < a1.length; j++)
10529                        a1[j] = i;
10530                return a1;
10531        }
10532
10533    
10534        /**
10535         * Fill the array with the value
10536         * 
10537         * @param a1
10538         *            The array
10539         * @param i
10540         *            The value
10541         * @return The array
10542         */
10543        public static int[][] fill(final int[][] a1, final int i)
10544        {
10545                for (int j = 0; j < a1.length; j++)
10546                        fill(a1[j], i);
10547                return a1;
10548        }
10549
10550        /**
10551         * Fill the array with the value from the start index for the length given
10552         * 
10553         * @param a1
10554         *            The array to fill
10555         * @param i
10556         *            The value to fill with
10557         * @param s
10558         *            The start index
10559         * @param l
10560         *            The length of the fill
10561         * @return The array
10562         */
10563        public static int[] fill(final int[] a1, final int i, final int s, final int l)
10564        {
10565                for (int j = s; j < s + l; j++)
10566                        a1[j] = i;
10567                return a1;
10568        }
10569
10570        /**
10571         * Fill the array with the value
10572         * 
10573         * @param a1
10574         *            The array
10575         * @param i
10576         *            The value
10577         * @return The array
10578         */
10579        public static int[] fill(final int[] a1, final int i)
10580        {
10581                for (int j = 0; j < a1.length; j++)
10582                        a1[j] = i;
10583                return a1;
10584        }
10585
10586    
10587        /**
10588         * Fill the array with the value
10589         * 
10590         * @param a1
10591         *            The array
10592         * @param i
10593         *            The value
10594         * @return The array
10595         */
10596        public static long[][] fill(final long[][] a1, final long i)
10597        {
10598                for (int j = 0; j < a1.length; j++)
10599                        fill(a1[j], i);
10600                return a1;
10601        }
10602
10603        /**
10604         * Fill the array with the value from the start index for the length given
10605         * 
10606         * @param a1
10607         *            The array to fill
10608         * @param i
10609         *            The value to fill with
10610         * @param s
10611         *            The start index
10612         * @param l
10613         *            The length of the fill
10614         * @return The array
10615         */
10616        public static long[] fill(final long[] a1, final long i, final int s, final int l)
10617        {
10618                for (int j = s; j < s + l; j++)
10619                        a1[j] = i;
10620                return a1;
10621        }
10622
10623        /**
10624         * Fill the array with the value
10625         * 
10626         * @param a1
10627         *            The array
10628         * @param i
10629         *            The value
10630         * @return The array
10631         */
10632        public static long[] fill(final long[] a1, final long i)
10633        {
10634                for (int j = 0; j < a1.length; j++)
10635                        a1[j] = i;
10636                return a1;
10637        }
10638
10639    
10640        /**
10641         * Fill the array with the value
10642         * 
10643         * @param a1
10644         *            The array
10645         * @param i
10646         *            The value
10647         * @return The array
10648         */
10649        public static byte[][] fill(final byte[][] a1, final byte i)
10650        {
10651                for (int j = 0; j < a1.length; j++)
10652                        fill(a1[j], i);
10653                return a1;
10654        }
10655
10656        /**
10657         * Fill the array with the value from the start index for the length given
10658         * 
10659         * @param a1
10660         *            The array to fill
10661         * @param i
10662         *            The value to fill with
10663         * @param s
10664         *            The start index
10665         * @param l
10666         *            The length of the fill
10667         * @return The array
10668         */
10669        public static byte[] fill(final byte[] a1, final byte i, final int s, final int l)
10670        {
10671                for (int j = s; j < s + l; j++)
10672                        a1[j] = i;
10673                return a1;
10674        }
10675
10676        /**
10677         * Fill the array with the value
10678         * 
10679         * @param a1
10680         *            The array
10681         * @param i
10682         *            The value
10683         * @return The array
10684         */
10685        public static byte[] fill(final byte[] a1, final byte i)
10686        {
10687                for (int j = 0; j < a1.length; j++)
10688                        a1[j] = i;
10689                return a1;
10690        }
10691
10692    
10693        /**
10694         * Fill the array with the value
10695         * 
10696         * @param a1
10697         *            The array
10698         * @param i
10699         *            The value
10700         * @return The array
10701         */
10702        public static short[][] fill(final short[][] a1, final short i)
10703        {
10704                for (int j = 0; j < a1.length; j++)
10705                        fill(a1[j], i);
10706                return a1;
10707        }
10708
10709        /**
10710         * Fill the array with the value from the start index for the length given
10711         * 
10712         * @param a1
10713         *            The array to fill
10714         * @param i
10715         *            The value to fill with
10716         * @param s
10717         *            The start index
10718         * @param l
10719         *            The length of the fill
10720         * @return The array
10721         */
10722        public static short[] fill(final short[] a1, final short i, final int s, final int l)
10723        {
10724                for (int j = s; j < s + l; j++)
10725                        a1[j] = i;
10726                return a1;
10727        }
10728
10729        /**
10730         * Fill the array with the value
10731         * 
10732         * @param a1
10733         *            The array
10734         * @param i
10735         *            The value
10736         * @return The array
10737         */
10738        public static short[] fill(final short[] a1, final short i)
10739        {
10740                for (int j = 0; j < a1.length; j++)
10741                        a1[j] = i;
10742                return a1;
10743        }
10744
10745    
10746        /**
10747         * Fills the array with ordinal values
10748         * 
10749         * @param array
10750         *            The array to fill
10751         * @return the array
10752         */
10753        public static int[] fill(final int[] array)
10754        {
10755                for (int i = 0; i < array.length; i++)
10756                        array[i] = i;
10757                return array;
10758        }
10759
10760    
10761        /**
10762         * Truncates the given array to the given size.
10763         * 
10764         * @param array
10765         *            The array to truncate
10766         * @param index
10767         *            The size to truncate it to
10768         * @return The truncated array
10769         */
10770        public static double[] truncate(final double[] array, final int index)
10771        {
10772                final double[] d = new double[index];
10773                System.arraycopy(array, 0, d, 0, index);
10774                return d;
10775        }
10776
10777        /**
10778         * Truncates every element in the given array to the given size.
10779         * 
10780         * @param array
10781         *            The array to truncate
10782         * @param index
10783         *            The size to truncate it to
10784         * @return The truncated array
10785         */
10786        public static double[][] truncate(final double[][] array, final int index)
10787        {
10788                final double[][] d = new double[Math.min(array.length, index)][index];
10789                for (int i = 0; i < d.length; i++)
10790                        d[i] = truncate(array[i], index);
10791                return d;
10792        }
10793
10794    
10795        /**
10796         * Truncates the given array to the given size.
10797         * 
10798         * @param array
10799         *            The array to truncate
10800         * @param index
10801         *            The size to truncate it to
10802         * @return The truncated array
10803         */
10804        public static float[] truncate(final float[] array, final int index)
10805        {
10806                final float[] d = new float[index];
10807                System.arraycopy(array, 0, d, 0, index);
10808                return d;
10809        }
10810
10811        /**
10812         * Truncates every element in the given array to the given size.
10813         * 
10814         * @param array
10815         *            The array to truncate
10816         * @param index
10817         *            The size to truncate it to
10818         * @return The truncated array
10819         */
10820        public static float[][] truncate(final float[][] array, final int index)
10821        {
10822                final float[][] d = new float[Math.min(array.length, index)][index];
10823                for (int i = 0; i < d.length; i++)
10824                        d[i] = truncate(array[i], index);
10825                return d;
10826        }
10827
10828    
10829        /**
10830         * Truncates the given array to the given size.
10831         * 
10832         * @param array
10833         *            The array to truncate
10834         * @param index
10835         *            The size to truncate it to
10836         * @return The truncated array
10837         */
10838        public static int[] truncate(final int[] array, final int index)
10839        {
10840                final int[] d = new int[index];
10841                System.arraycopy(array, 0, d, 0, index);
10842                return d;
10843        }
10844
10845        /**
10846         * Truncates every element in the given array to the given size.
10847         * 
10848         * @param array
10849         *            The array to truncate
10850         * @param index
10851         *            The size to truncate it to
10852         * @return The truncated array
10853         */
10854        public static int[][] truncate(final int[][] array, final int index)
10855        {
10856                final int[][] d = new int[Math.min(array.length, index)][index];
10857                for (int i = 0; i < d.length; i++)
10858                        d[i] = truncate(array[i], index);
10859                return d;
10860        }
10861
10862    
10863        /**
10864         * Truncates the given array to the given size.
10865         * 
10866         * @param array
10867         *            The array to truncate
10868         * @param index
10869         *            The size to truncate it to
10870         * @return The truncated array
10871         */
10872        public static long[] truncate(final long[] array, final int index)
10873        {
10874                final long[] d = new long[index];
10875                System.arraycopy(array, 0, d, 0, index);
10876                return d;
10877        }
10878
10879        /**
10880         * Truncates every element in the given array to the given size.
10881         * 
10882         * @param array
10883         *            The array to truncate
10884         * @param index
10885         *            The size to truncate it to
10886         * @return The truncated array
10887         */
10888        public static long[][] truncate(final long[][] array, final int index)
10889        {
10890                final long[][] d = new long[Math.min(array.length, index)][index];
10891                for (int i = 0; i < d.length; i++)
10892                        d[i] = truncate(array[i], index);
10893                return d;
10894        }
10895
10896    
10897        /**
10898         * Truncates the given array to the given size.
10899         * 
10900         * @param array
10901         *            The array to truncate
10902         * @param index
10903         *            The size to truncate it to
10904         * @return The truncated array
10905         */
10906        public static byte[] truncate(final byte[] array, final int index)
10907        {
10908                final byte[] d = new byte[index];
10909                System.arraycopy(array, 0, d, 0, index);
10910                return d;
10911        }
10912
10913        /**
10914         * Truncates every element in the given array to the given size.
10915         * 
10916         * @param array
10917         *            The array to truncate
10918         * @param index
10919         *            The size to truncate it to
10920         * @return The truncated array
10921         */
10922        public static byte[][] truncate(final byte[][] array, final int index)
10923        {
10924                final byte[][] d = new byte[Math.min(array.length, index)][index];
10925                for (int i = 0; i < d.length; i++)
10926                        d[i] = truncate(array[i], index);
10927                return d;
10928        }
10929
10930    
10931        /**
10932         * Truncates the given array to the given size.
10933         * 
10934         * @param array
10935         *            The array to truncate
10936         * @param index
10937         *            The size to truncate it to
10938         * @return The truncated array
10939         */
10940        public static short[] truncate(final short[] array, final int index)
10941        {
10942                final short[] d = new short[index];
10943                System.arraycopy(array, 0, d, 0, index);
10944                return d;
10945        }
10946
10947        /**
10948         * Truncates every element in the given array to the given size.
10949         * 
10950         * @param array
10951         *            The array to truncate
10952         * @param index
10953         *            The size to truncate it to
10954         * @return The truncated array
10955         */
10956        public static short[][] truncate(final short[][] array, final int index)
10957        {
10958                final short[][] d = new short[Math.min(array.length, index)][index];
10959                for (int i = 0; i < d.length; i++)
10960                        d[i] = truncate(array[i], index);
10961                return d;
10962        }
10963
10964    
10965        /**
10966         * Quick Select algorithm for getting the nth item from the array as if it
10967         * were sorted. Expected complexity is O(N); worst case is O(N^2). The input
10968         * array will be reordered; clone it first if this is a problem.
10969         * Implementation based on public domain code from Nicolas Devillard.
10970         * 
10971         * @see "http://ndevilla.free.fr/median/median/src/quickselect.c"
10972         * 
10973         * @param arr
10974         *            the array to select from
10975         * @param n
10976         *            the item to select
10977         * @return the selected item
10978         */
10979        public static double quickSelect(double arr[], int n) {
10980                return quickSelect(arr, n, 0, arr.length - 1);
10981        }
10982
10983        /**
10984         * Quick Select algorithm for getting the nth item from a sub-array as if it
10985         * were sorted. Expected complexity is O(N); worst case is O(N^2). The input
10986         * array will be reordered; clone it first if this is a problem.
10987         * Implementation based on public domain code from Nicolas Devillard.
10988         * 
10989         * @see "http://ndevilla.free.fr/median/median/src/quickselect.c"
10990         * 
10991         * @param arr
10992         *            the array to select from
10993         * @param n
10994         *            the item to select
10995         * @param low
10996         *            the starting position in the array (inclusive)
10997         * @param high
10998         *            the ending position in the array (exclusive)
10999         * @return the selected item
11000         */
11001        public static double quickSelect(double arr[], int n, int low, int high) {
11002                high--; // make high inclusive
11003
11004                int middle, ll, hh;
11005                double tmp = 0;
11006                final int median = (low + high) / 2;
11007
11008                while (true) {
11009                        if (high <= low) /* One element only */
11010                                return arr[median];
11011
11012                        if (high == low + 1) { /* Two elements only */
11013                                if (arr[low] > arr[high]) {
11014                                        tmp = arr[low];
11015                                        arr[low] = arr[high];
11016                                        arr[high] = tmp;
11017                                }
11018                                return arr[median];
11019                        }
11020
11021                        /* Find median of low, middle and high items; swap into position low */
11022                        middle = (low + high) / 2;
11023                        if (arr[middle] > arr[high]) {
11024                                tmp = arr[middle];
11025                                arr[middle] = arr[high];
11026                                arr[high] = tmp;
11027                                ;
11028                        }
11029                        if (arr[low] > arr[high]) {
11030                                tmp = arr[low];
11031                                arr[low] = arr[high];
11032                                arr[high] = tmp;
11033                        }
11034                        if (arr[middle] > arr[low]) {
11035                                tmp = arr[low];
11036                                arr[low] = arr[middle];
11037                                arr[middle] = tmp;
11038                        }
11039
11040                        /* Swap low item (now in position middle) into position (low+1) */
11041                        tmp = arr[middle];
11042                        arr[middle] = arr[low + 1];
11043                        arr[low + 1] = tmp;
11044
11045                        /* Nibble from each end towards middle, swapping items when stuck */
11046                        ll = low + 1;
11047                        hh = high;
11048                        for (;;) {
11049                                do
11050                                        ll++;
11051                                while (arr[low] > arr[ll]);
11052                                do
11053                                        hh--;
11054                                while (arr[hh] > arr[low]);
11055
11056                                if (hh < ll)
11057                                        break;
11058
11059                                tmp = arr[ll];
11060                                arr[ll] = arr[hh];
11061                                arr[hh] = tmp;
11062                        }
11063
11064                        /* Swap middle item (in position low) back into correct position */
11065                        tmp = arr[low];
11066                        arr[low] = arr[hh];
11067                        arr[hh] = tmp;
11068
11069                        /* Re-set active partition */
11070                        if (hh <= median)
11071                                low = ll;
11072                        if (hh >= median)
11073                                high = hh - 1;
11074                }
11075        }       
11076
11077        
11078        /**
11079         * Quick Select algorithm for getting the nth item from the array as if it
11080         * were sorted. Expected complexity is O(N); worst case is O(N^2). The input
11081         * array will be reordered; clone it first if this is a problem.
11082         * Implementation based on public domain code from Nicolas Devillard.
11083         * 
11084         * @see "http://ndevilla.free.fr/median/median/src/quickselect.c"
11085         * 
11086         * @param arr
11087         *            the array to select from
11088         * @param n
11089         *            the item to select
11090         * @return the selected item
11091         */
11092        public static float quickSelect(float arr[], int n) {
11093                return quickSelect(arr, n, 0, arr.length - 1);
11094        }
11095
11096        /**
11097         * Quick Select algorithm for getting the nth item from a sub-array as if it
11098         * were sorted. Expected complexity is O(N); worst case is O(N^2). The input
11099         * array will be reordered; clone it first if this is a problem.
11100         * Implementation based on public domain code from Nicolas Devillard.
11101         * 
11102         * @see "http://ndevilla.free.fr/median/median/src/quickselect.c"
11103         * 
11104         * @param arr
11105         *            the array to select from
11106         * @param n
11107         *            the item to select
11108         * @param low
11109         *            the starting position in the array (inclusive)
11110         * @param high
11111         *            the ending position in the array (exclusive)
11112         * @return the selected item
11113         */
11114        public static float quickSelect(float arr[], int n, int low, int high) {
11115                high--; // make high inclusive
11116
11117                int middle, ll, hh;
11118                float tmp = 0;
11119                final int median = (low + high) / 2;
11120
11121                while (true) {
11122                        if (high <= low) /* One element only */
11123                                return arr[median];
11124
11125                        if (high == low + 1) { /* Two elements only */
11126                                if (arr[low] > arr[high]) {
11127                                        tmp = arr[low];
11128                                        arr[low] = arr[high];
11129                                        arr[high] = tmp;
11130                                }
11131                                return arr[median];
11132                        }
11133
11134                        /* Find median of low, middle and high items; swap into position low */
11135                        middle = (low + high) / 2;
11136                        if (arr[middle] > arr[high]) {
11137                                tmp = arr[middle];
11138                                arr[middle] = arr[high];
11139                                arr[high] = tmp;
11140                                ;
11141                        }
11142                        if (arr[low] > arr[high]) {
11143                                tmp = arr[low];
11144                                arr[low] = arr[high];
11145                                arr[high] = tmp;
11146                        }
11147                        if (arr[middle] > arr[low]) {
11148                                tmp = arr[low];
11149                                arr[low] = arr[middle];
11150                                arr[middle] = tmp;
11151                        }
11152
11153                        /* Swap low item (now in position middle) into position (low+1) */
11154                        tmp = arr[middle];
11155                        arr[middle] = arr[low + 1];
11156                        arr[low + 1] = tmp;
11157
11158                        /* Nibble from each end towards middle, swapping items when stuck */
11159                        ll = low + 1;
11160                        hh = high;
11161                        for (;;) {
11162                                do
11163                                        ll++;
11164                                while (arr[low] > arr[ll]);
11165                                do
11166                                        hh--;
11167                                while (arr[hh] > arr[low]);
11168
11169                                if (hh < ll)
11170                                        break;
11171
11172                                tmp = arr[ll];
11173                                arr[ll] = arr[hh];
11174                                arr[hh] = tmp;
11175                        }
11176
11177                        /* Swap middle item (in position low) back into correct position */
11178                        tmp = arr[low];
11179                        arr[low] = arr[hh];
11180                        arr[hh] = tmp;
11181
11182                        /* Re-set active partition */
11183                        if (hh <= median)
11184                                low = ll;
11185                        if (hh >= median)
11186                                high = hh - 1;
11187                }
11188        }       
11189
11190        
11191        /**
11192         * Quick Select algorithm for getting the nth item from the array as if it
11193         * were sorted. Expected complexity is O(N); worst case is O(N^2). The input
11194         * array will be reordered; clone it first if this is a problem.
11195         * Implementation based on public domain code from Nicolas Devillard.
11196         * 
11197         * @see "http://ndevilla.free.fr/median/median/src/quickselect.c"
11198         * 
11199         * @param arr
11200         *            the array to select from
11201         * @param n
11202         *            the item to select
11203         * @return the selected item
11204         */
11205        public static int quickSelect(int arr[], int n) {
11206                return quickSelect(arr, n, 0, arr.length - 1);
11207        }
11208
11209        /**
11210         * Quick Select algorithm for getting the nth item from a sub-array as if it
11211         * were sorted. Expected complexity is O(N); worst case is O(N^2). The input
11212         * array will be reordered; clone it first if this is a problem.
11213         * Implementation based on public domain code from Nicolas Devillard.
11214         * 
11215         * @see "http://ndevilla.free.fr/median/median/src/quickselect.c"
11216         * 
11217         * @param arr
11218         *            the array to select from
11219         * @param n
11220         *            the item to select
11221         * @param low
11222         *            the starting position in the array (inclusive)
11223         * @param high
11224         *            the ending position in the array (exclusive)
11225         * @return the selected item
11226         */
11227        public static int quickSelect(int arr[], int n, int low, int high) {
11228                high--; // make high inclusive
11229
11230                int middle, ll, hh;
11231                int tmp = 0;
11232                final int median = (low + high) / 2;
11233
11234                while (true) {
11235                        if (high <= low) /* One element only */
11236                                return arr[median];
11237
11238                        if (high == low + 1) { /* Two elements only */
11239                                if (arr[low] > arr[high]) {
11240                                        tmp = arr[low];
11241                                        arr[low] = arr[high];
11242                                        arr[high] = tmp;
11243                                }
11244                                return arr[median];
11245                        }
11246
11247                        /* Find median of low, middle and high items; swap into position low */
11248                        middle = (low + high) / 2;
11249                        if (arr[middle] > arr[high]) {
11250                                tmp = arr[middle];
11251                                arr[middle] = arr[high];
11252                                arr[high] = tmp;
11253                                ;
11254                        }
11255                        if (arr[low] > arr[high]) {
11256                                tmp = arr[low];
11257                                arr[low] = arr[high];
11258                                arr[high] = tmp;
11259                        }
11260                        if (arr[middle] > arr[low]) {
11261                                tmp = arr[low];
11262                                arr[low] = arr[middle];
11263                                arr[middle] = tmp;
11264                        }
11265
11266                        /* Swap low item (now in position middle) into position (low+1) */
11267                        tmp = arr[middle];
11268                        arr[middle] = arr[low + 1];
11269                        arr[low + 1] = tmp;
11270
11271                        /* Nibble from each end towards middle, swapping items when stuck */
11272                        ll = low + 1;
11273                        hh = high;
11274                        for (;;) {
11275                                do
11276                                        ll++;
11277                                while (arr[low] > arr[ll]);
11278                                do
11279                                        hh--;
11280                                while (arr[hh] > arr[low]);
11281
11282                                if (hh < ll)
11283                                        break;
11284
11285                                tmp = arr[ll];
11286                                arr[ll] = arr[hh];
11287                                arr[hh] = tmp;
11288                        }
11289
11290                        /* Swap middle item (in position low) back into correct position */
11291                        tmp = arr[low];
11292                        arr[low] = arr[hh];
11293                        arr[hh] = tmp;
11294
11295                        /* Re-set active partition */
11296                        if (hh <= median)
11297                                low = ll;
11298                        if (hh >= median)
11299                                high = hh - 1;
11300                }
11301        }       
11302
11303        
11304        /**
11305         * Quick Select algorithm for getting the nth item from the array as if it
11306         * were sorted. Expected complexity is O(N); worst case is O(N^2). The input
11307         * array will be reordered; clone it first if this is a problem.
11308         * Implementation based on public domain code from Nicolas Devillard.
11309         * 
11310         * @see "http://ndevilla.free.fr/median/median/src/quickselect.c"
11311         * 
11312         * @param arr
11313         *            the array to select from
11314         * @param n
11315         *            the item to select
11316         * @return the selected item
11317         */
11318        public static long quickSelect(long arr[], int n) {
11319                return quickSelect(arr, n, 0, arr.length - 1);
11320        }
11321
11322        /**
11323         * Quick Select algorithm for getting the nth item from a sub-array as if it
11324         * were sorted. Expected complexity is O(N); worst case is O(N^2). The input
11325         * array will be reordered; clone it first if this is a problem.
11326         * Implementation based on public domain code from Nicolas Devillard.
11327         * 
11328         * @see "http://ndevilla.free.fr/median/median/src/quickselect.c"
11329         * 
11330         * @param arr
11331         *            the array to select from
11332         * @param n
11333         *            the item to select
11334         * @param low
11335         *            the starting position in the array (inclusive)
11336         * @param high
11337         *            the ending position in the array (exclusive)
11338         * @return the selected item
11339         */
11340        public static long quickSelect(long arr[], int n, int low, int high) {
11341                high--; // make high inclusive
11342
11343                int middle, ll, hh;
11344                long tmp = 0;
11345                final int median = (low + high) / 2;
11346
11347                while (true) {
11348                        if (high <= low) /* One element only */
11349                                return arr[median];
11350
11351                        if (high == low + 1) { /* Two elements only */
11352                                if (arr[low] > arr[high]) {
11353                                        tmp = arr[low];
11354                                        arr[low] = arr[high];
11355                                        arr[high] = tmp;
11356                                }
11357                                return arr[median];
11358                        }
11359
11360                        /* Find median of low, middle and high items; swap into position low */
11361                        middle = (low + high) / 2;
11362                        if (arr[middle] > arr[high]) {
11363                                tmp = arr[middle];
11364                                arr[middle] = arr[high];
11365                                arr[high] = tmp;
11366                                ;
11367                        }
11368                        if (arr[low] > arr[high]) {
11369                                tmp = arr[low];
11370                                arr[low] = arr[high];
11371                                arr[high] = tmp;
11372                        }
11373                        if (arr[middle] > arr[low]) {
11374                                tmp = arr[low];
11375                                arr[low] = arr[middle];
11376                                arr[middle] = tmp;
11377                        }
11378
11379                        /* Swap low item (now in position middle) into position (low+1) */
11380                        tmp = arr[middle];
11381                        arr[middle] = arr[low + 1];
11382                        arr[low + 1] = tmp;
11383
11384                        /* Nibble from each end towards middle, swapping items when stuck */
11385                        ll = low + 1;
11386                        hh = high;
11387                        for (;;) {
11388                                do
11389                                        ll++;
11390                                while (arr[low] > arr[ll]);
11391                                do
11392                                        hh--;
11393                                while (arr[hh] > arr[low]);
11394
11395                                if (hh < ll)
11396                                        break;
11397
11398                                tmp = arr[ll];
11399                                arr[ll] = arr[hh];
11400                                arr[hh] = tmp;
11401                        }
11402
11403                        /* Swap middle item (in position low) back into correct position */
11404                        tmp = arr[low];
11405                        arr[low] = arr[hh];
11406                        arr[hh] = tmp;
11407
11408                        /* Re-set active partition */
11409                        if (hh <= median)
11410                                low = ll;
11411                        if (hh >= median)
11412                                high = hh - 1;
11413                }
11414        }       
11415
11416        
11417        /**
11418         * Quick Select algorithm for getting the nth item from the array as if it
11419         * were sorted. Expected complexity is O(N); worst case is O(N^2). The input
11420         * array will be reordered; clone it first if this is a problem.
11421         * Implementation based on public domain code from Nicolas Devillard.
11422         * 
11423         * @see "http://ndevilla.free.fr/median/median/src/quickselect.c"
11424         * 
11425         * @param arr
11426         *            the array to select from
11427         * @param n
11428         *            the item to select
11429         * @return the selected item
11430         */
11431        public static byte quickSelect(byte arr[], int n) {
11432                return quickSelect(arr, n, 0, arr.length - 1);
11433        }
11434
11435        /**
11436         * Quick Select algorithm for getting the nth item from a sub-array as if it
11437         * were sorted. Expected complexity is O(N); worst case is O(N^2). The input
11438         * array will be reordered; clone it first if this is a problem.
11439         * Implementation based on public domain code from Nicolas Devillard.
11440         * 
11441         * @see "http://ndevilla.free.fr/median/median/src/quickselect.c"
11442         * 
11443         * @param arr
11444         *            the array to select from
11445         * @param n
11446         *            the item to select
11447         * @param low
11448         *            the starting position in the array (inclusive)
11449         * @param high
11450         *            the ending position in the array (exclusive)
11451         * @return the selected item
11452         */
11453        public static byte quickSelect(byte arr[], int n, int low, int high) {
11454                high--; // make high inclusive
11455
11456                int middle, ll, hh;
11457                byte tmp = 0;
11458                final int median = (low + high) / 2;
11459
11460                while (true) {
11461                        if (high <= low) /* One element only */
11462                                return arr[median];
11463
11464                        if (high == low + 1) { /* Two elements only */
11465                                if (arr[low] > arr[high]) {
11466                                        tmp = arr[low];
11467                                        arr[low] = arr[high];
11468                                        arr[high] = tmp;
11469                                }
11470                                return arr[median];
11471                        }
11472
11473                        /* Find median of low, middle and high items; swap into position low */
11474                        middle = (low + high) / 2;
11475                        if (arr[middle] > arr[high]) {
11476                                tmp = arr[middle];
11477                                arr[middle] = arr[high];
11478                                arr[high] = tmp;
11479                                ;
11480                        }
11481                        if (arr[low] > arr[high]) {
11482                                tmp = arr[low];
11483                                arr[low] = arr[high];
11484                                arr[high] = tmp;
11485                        }
11486                        if (arr[middle] > arr[low]) {
11487                                tmp = arr[low];
11488                                arr[low] = arr[middle];
11489                                arr[middle] = tmp;
11490                        }
11491
11492                        /* Swap low item (now in position middle) into position (low+1) */
11493                        tmp = arr[middle];
11494                        arr[middle] = arr[low + 1];
11495                        arr[low + 1] = tmp;
11496
11497                        /* Nibble from each end towards middle, swapping items when stuck */
11498                        ll = low + 1;
11499                        hh = high;
11500                        for (;;) {
11501                                do
11502                                        ll++;
11503                                while (arr[low] > arr[ll]);
11504                                do
11505                                        hh--;
11506                                while (arr[hh] > arr[low]);
11507
11508                                if (hh < ll)
11509                                        break;
11510
11511                                tmp = arr[ll];
11512                                arr[ll] = arr[hh];
11513                                arr[hh] = tmp;
11514                        }
11515
11516                        /* Swap middle item (in position low) back into correct position */
11517                        tmp = arr[low];
11518                        arr[low] = arr[hh];
11519                        arr[hh] = tmp;
11520
11521                        /* Re-set active partition */
11522                        if (hh <= median)
11523                                low = ll;
11524                        if (hh >= median)
11525                                high = hh - 1;
11526                }
11527        }       
11528
11529        
11530        /**
11531         * Quick Select algorithm for getting the nth item from the array as if it
11532         * were sorted. Expected complexity is O(N); worst case is O(N^2). The input
11533         * array will be reordered; clone it first if this is a problem.
11534         * Implementation based on public domain code from Nicolas Devillard.
11535         * 
11536         * @see "http://ndevilla.free.fr/median/median/src/quickselect.c"
11537         * 
11538         * @param arr
11539         *            the array to select from
11540         * @param n
11541         *            the item to select
11542         * @return the selected item
11543         */
11544        public static short quickSelect(short arr[], int n) {
11545                return quickSelect(arr, n, 0, arr.length - 1);
11546        }
11547
11548        /**
11549         * Quick Select algorithm for getting the nth item from a sub-array as if it
11550         * were sorted. Expected complexity is O(N); worst case is O(N^2). The input
11551         * array will be reordered; clone it first if this is a problem.
11552         * Implementation based on public domain code from Nicolas Devillard.
11553         * 
11554         * @see "http://ndevilla.free.fr/median/median/src/quickselect.c"
11555         * 
11556         * @param arr
11557         *            the array to select from
11558         * @param n
11559         *            the item to select
11560         * @param low
11561         *            the starting position in the array (inclusive)
11562         * @param high
11563         *            the ending position in the array (exclusive)
11564         * @return the selected item
11565         */
11566        public static short quickSelect(short arr[], int n, int low, int high) {
11567                high--; // make high inclusive
11568
11569                int middle, ll, hh;
11570                short tmp = 0;
11571                final int median = (low + high) / 2;
11572
11573                while (true) {
11574                        if (high <= low) /* One element only */
11575                                return arr[median];
11576
11577                        if (high == low + 1) { /* Two elements only */
11578                                if (arr[low] > arr[high]) {
11579                                        tmp = arr[low];
11580                                        arr[low] = arr[high];
11581                                        arr[high] = tmp;
11582                                }
11583                                return arr[median];
11584                        }
11585
11586                        /* Find median of low, middle and high items; swap into position low */
11587                        middle = (low + high) / 2;
11588                        if (arr[middle] > arr[high]) {
11589                                tmp = arr[middle];
11590                                arr[middle] = arr[high];
11591                                arr[high] = tmp;
11592                                ;
11593                        }
11594                        if (arr[low] > arr[high]) {
11595                                tmp = arr[low];
11596                                arr[low] = arr[high];
11597                                arr[high] = tmp;
11598                        }
11599                        if (arr[middle] > arr[low]) {
11600                                tmp = arr[low];
11601                                arr[low] = arr[middle];
11602                                arr[middle] = tmp;
11603                        }
11604
11605                        /* Swap low item (now in position middle) into position (low+1) */
11606                        tmp = arr[middle];
11607                        arr[middle] = arr[low + 1];
11608                        arr[low + 1] = tmp;
11609
11610                        /* Nibble from each end towards middle, swapping items when stuck */
11611                        ll = low + 1;
11612                        hh = high;
11613                        for (;;) {
11614                                do
11615                                        ll++;
11616                                while (arr[low] > arr[ll]);
11617                                do
11618                                        hh--;
11619                                while (arr[hh] > arr[low]);
11620
11621                                if (hh < ll)
11622                                        break;
11623
11624                                tmp = arr[ll];
11625                                arr[ll] = arr[hh];
11626                                arr[hh] = tmp;
11627                        }
11628
11629                        /* Swap middle item (in position low) back into correct position */
11630                        tmp = arr[low];
11631                        arr[low] = arr[hh];
11632                        arr[hh] = tmp;
11633
11634                        /* Re-set active partition */
11635                        if (hh <= median)
11636                                low = ll;
11637                        if (hh >= median)
11638                                high = hh - 1;
11639                }
11640        }       
11641
11642        
11643        /**
11644         * Convert from Double[] to double[]. This will create a new array and copy the contents.
11645         *
11646         * @param array input array
11647         * @return the converted array
11648         */
11649        public double[] convert(Double[] array) {
11650                double[] out = new double[array.length];
11651                
11652                for (int i=0; i<array.length; i++) {
11653                        out[i] = array[i];
11654                }
11655                
11656                return out;
11657        }
11658        
11659        /**
11660         * Convert from Double[] to Double[]. This will create a new array and copy the contents.
11661         *
11662         * @param array input array
11663         * @return the converted array
11664         */
11665        public Double[] convert(double[] array) {
11666                Double[] out = new Double[array.length];
11667                
11668                for (int i=0; i<array.length; i++) {
11669                        out[i] = array[i];
11670                }
11671                
11672                return out;
11673        }
11674
11675        
11676        /**
11677         * Convert from Float[] to float[]. This will create a new array and copy the contents.
11678         *
11679         * @param array input array
11680         * @return the converted array
11681         */
11682        public float[] convert(Float[] array) {
11683                float[] out = new float[array.length];
11684                
11685                for (int i=0; i<array.length; i++) {
11686                        out[i] = array[i];
11687                }
11688                
11689                return out;
11690        }
11691        
11692        /**
11693         * Convert from Float[] to Float[]. This will create a new array and copy the contents.
11694         *
11695         * @param array input array
11696         * @return the converted array
11697         */
11698        public Float[] convert(float[] array) {
11699                Float[] out = new Float[array.length];
11700                
11701                for (int i=0; i<array.length; i++) {
11702                        out[i] = array[i];
11703                }
11704                
11705                return out;
11706        }
11707
11708        
11709        /**
11710         * Convert from Integer[] to int[]. This will create a new array and copy the contents.
11711         *
11712         * @param array input array
11713         * @return the converted array
11714         */
11715        public int[] convert(Integer[] array) {
11716                int[] out = new int[array.length];
11717                
11718                for (int i=0; i<array.length; i++) {
11719                        out[i] = array[i];
11720                }
11721                
11722                return out;
11723        }
11724        
11725        /**
11726         * Convert from Int[] to Integer[]. This will create a new array and copy the contents.
11727         *
11728         * @param array input array
11729         * @return the converted array
11730         */
11731        public Integer[] convert(int[] array) {
11732                Integer[] out = new Integer[array.length];
11733                
11734                for (int i=0; i<array.length; i++) {
11735                        out[i] = array[i];
11736                }
11737                
11738                return out;
11739        }
11740
11741        
11742        /**
11743         * Convert from Long[] to long[]. This will create a new array and copy the contents.
11744         *
11745         * @param array input array
11746         * @return the converted array
11747         */
11748        public long[] convert(Long[] array) {
11749                long[] out = new long[array.length];
11750                
11751                for (int i=0; i<array.length; i++) {
11752                        out[i] = array[i];
11753                }
11754                
11755                return out;
11756        }
11757        
11758        /**
11759         * Convert from Long[] to Long[]. This will create a new array and copy the contents.
11760         *
11761         * @param array input array
11762         * @return the converted array
11763         */
11764        public Long[] convert(long[] array) {
11765                Long[] out = new Long[array.length];
11766                
11767                for (int i=0; i<array.length; i++) {
11768                        out[i] = array[i];
11769                }
11770                
11771                return out;
11772        }
11773
11774        
11775        /**
11776         * Convert from Byte[] to byte[]. This will create a new array and copy the contents.
11777         *
11778         * @param array input array
11779         * @return the converted array
11780         */
11781        public byte[] convert(Byte[] array) {
11782                byte[] out = new byte[array.length];
11783                
11784                for (int i=0; i<array.length; i++) {
11785                        out[i] = array[i];
11786                }
11787                
11788                return out;
11789        }
11790        
11791        /**
11792         * Convert from Byte[] to Byte[]. This will create a new array and copy the contents.
11793         *
11794         * @param array input array
11795         * @return the converted array
11796         */
11797        public Byte[] convert(byte[] array) {
11798                Byte[] out = new Byte[array.length];
11799                
11800                for (int i=0; i<array.length; i++) {
11801                        out[i] = array[i];
11802                }
11803                
11804                return out;
11805        }
11806
11807        
11808        /**
11809         * Convert from Short[] to short[]. This will create a new array and copy the contents.
11810         *
11811         * @param array input array
11812         * @return the converted array
11813         */
11814        public short[] convert(Short[] array) {
11815                short[] out = new short[array.length];
11816                
11817                for (int i=0; i<array.length; i++) {
11818                        out[i] = array[i];
11819                }
11820                
11821                return out;
11822        }
11823        
11824        /**
11825         * Convert from Short[] to Short[]. This will create a new array and copy the contents.
11826         *
11827         * @param array input array
11828         * @return the converted array
11829         */
11830        public Short[] convert(short[] array) {
11831                Short[] out = new Short[array.length];
11832                
11833                for (int i=0; i<array.length; i++) {
11834                        out[i] = array[i];
11835                }
11836                
11837                return out;
11838        }
11839
11840        
11841        /**
11842         * Compute the p-norm of the array
11843         * 
11844         * @param array the array 
11845         * @param p the p value
11846         * @return the p-norm
11847         */
11848        public static double pnorm(final double[] array, final int p) {
11849                double sum = 0;
11850
11851                for (int i=0; i<array.length; i++)
11852                        sum += Math.pow(Math.abs(array[i]), p);
11853
11854                return Math.pow(sum, 1.0/p);
11855        }
11856
11857        
11858        /**
11859         * Compute the p-norm of the array
11860         * 
11861         * @param array the array 
11862         * @param p the p value
11863         * @return the p-norm
11864         */
11865        public static double pnorm(final float[] array, final int p) {
11866                double sum = 0;
11867
11868                for (int i=0; i<array.length; i++)
11869                        sum += Math.pow(Math.abs(array[i]), p);
11870
11871                return Math.pow(sum, 1.0/p);
11872        }
11873
11874        
11875        /**
11876         * Compute the p-norm of the array
11877         * 
11878         * @param array the array 
11879         * @param p the p value
11880         * @return the p-norm
11881         */
11882        public static double pnorm(final int[] array, final int p) {
11883                double sum = 0;
11884
11885                for (int i=0; i<array.length; i++)
11886                        sum += Math.pow(Math.abs(array[i]), p);
11887
11888                return Math.pow(sum, 1.0/p);
11889        }
11890
11891        
11892        /**
11893         * Compute the p-norm of the array
11894         * 
11895         * @param array the array 
11896         * @param p the p value
11897         * @return the p-norm
11898         */
11899        public static double pnorm(final long[] array, final int p) {
11900                double sum = 0;
11901
11902                for (int i=0; i<array.length; i++)
11903                        sum += Math.pow(Math.abs(array[i]), p);
11904
11905                return Math.pow(sum, 1.0/p);
11906        }
11907
11908        
11909        /**
11910         * Compute the p-norm of the array
11911         * 
11912         * @param array the array 
11913         * @param p the p value
11914         * @return the p-norm
11915         */
11916        public static double pnorm(final byte[] array, final int p) {
11917                double sum = 0;
11918
11919                for (int i=0; i<array.length; i++)
11920                        sum += Math.pow(Math.abs(array[i]), p);
11921
11922                return Math.pow(sum, 1.0/p);
11923        }
11924
11925        
11926        /**
11927         * Compute the p-norm of the array
11928         * 
11929         * @param array the array 
11930         * @param p the p value
11931         * @return the p-norm
11932         */
11933        public static double pnorm(final short[] array, final int p) {
11934                double sum = 0;
11935
11936                for (int i=0; i<array.length; i++)
11937                        sum += Math.pow(Math.abs(array[i]), p);
11938
11939                return Math.pow(sum, 1.0/p);
11940        }
11941
11942        
11943}