@Override public void sortDescending() { FloatArrays.parallelQuickSort(data.elements(), descendingComparator); }
selectionSort(x, from, to); return; if (len > QUICKSORT_MEDIAN_OF_9) { // Big arrays, pseudomedian of 9 int s = len / 8; l = med3(x, l, l + s, l + 2 * s); m = med3(x, m - s, m, m + s); n = med3(x, n - 2 * s, n - s, n); m = med3(x, l, m, n); // Mid-size, med of 3 final float v = x[m]; while (b <= c && (comparison = (Float.compare((x[b]), (v)))) <= 0) { if (comparison == 0) swap(x, a++, b); b++; swap(x, c, d--); c--; swap(x, b++, c--); swap(x, from, b - s, s); s = Math.min(d - c, to - d - 1); swap(x, b, to - s, s); quickSort(x, from, from + s); if ((s = d - c) > 1) quickSort(x, to - s, to);
/** * Sorts two arrays according to the natural lexicographical ascending order * using a parallel quicksort. * * <p> * The sorting algorithm is a tuned quicksort adapted from Jon L. Bentley and M. * Douglas McIlroy, “Engineering a Sort Function”, <i>Software: * Practice and Experience</i>, 23(11), pages 1249−1265, 1993. * * <p> * This method implements a <em>lexicographical</em> sorting of the arguments. * Pairs of elements in the same position in the two provided arrays will be * considered a single key, and permuted accordingly. In the end, either * {@code x[i] < x[i + 1]} or <code>x[i] * == x[i + 1]</code> and {@code y[i] ≤ y[i + 1]}. * * <p> * This implementation uses a {@link ForkJoinPool} executor service with * {@link Runtime#availableProcessors()} parallel threads. * * @param x * the first array to be sorted. * @param y * the second array to be sorted. */ public static void parallelQuickSort(final float[] x, final float[] y) { ensureSameLength(x, y); parallelQuickSort(x, y, 0, x.length); } /**
/** * Sorts an array according to the natural ascending order using quicksort. * * <p> * The sorting algorithm is a tuned quicksort adapted from Jon L. Bentley and M. * Douglas McIlroy, “Engineering a Sort Function”, <i>Software: * Practice and Experience</i>, 23(11), pages 1249−1265, 1993. * * <p> * Note that this implementation does not allocate any object, contrarily to the * implementation used to sort primitive types in {@link java.util.Arrays}, * which switches to mergesort on large inputs. * * @param x * the array to be sorted. * */ public static void quickSort(final float[] x) { quickSort(x, 0, x.length); } protected static class ForkJoinQuickSort extends RecursiveAction {
quickSort(a, from, to); return; count[(fixFloat(a[i]) >>> shift & DIGIT_MASK ^ signMask)]++; c = (fixFloat(t) >>> shift & DIGIT_MASK ^ signMask); if (i < end) { // When all slots are OK, the last slot is necessarily OK. while ((d = --pos[c]) > i) { t = a[d]; a[d] = z; c = (fixFloat(t) >>> shift & DIGIT_MASK ^ signMask); quickSort(a, i, i + count[c]); else { offsetStack[stackPos] = i;
/** Stores an array fragment to a given print stream. * * @param array an array whose elements will be written to {@code stream}. * @param offset the index of the first element of {@code array} to be written. * @param length the number of elements of {@code array} to be written. * @param stream a print stream. */ public static void storeFloats(final float array[], final int offset, final int length, final PrintStream stream) { it.unimi.dsi.fastutil.floats.FloatArrays.ensureOffsetLength(array, offset, length); for(int i = 0; i < length; i++) stream.println(array[offset + i]); } /** Stores an array to a given print stream.
final int len = to - from; if (len < PARALLEL_QUICKSORT_NO_FORK) { quickSort(x, from, to); return; while (b <= c && (comparison = (Float.compare((x[b]), (v)))) <= 0) { if (comparison == 0) swap(x, a++, b); b++; swap(x, c, d--); c--; swap(x, b++, c--); swap(x, from, b - s, s); s = Math.min(d - c, to - d - 1); swap(x, b, to - s, s);
/** * Sorts two arrays according to the natural lexicographical ascending order * using quicksort. * * <p> * The sorting algorithm is a tuned quicksort adapted from Jon L. Bentley and M. * Douglas McIlroy, “Engineering a Sort Function”, <i>Software: * Practice and Experience</i>, 23(11), pages 1249−1265, 1993. * * <p> * This method implements a <em>lexicographical</em> sorting of the arguments. * Pairs of elements in the same position in the two provided arrays will be * considered a single key, and permuted accordingly. In the end, either * {@code x[i] < x[i + 1]} or <code>x[i] * == x[i + 1]</code> and {@code y[i] ≤ y[i + 1]}. * * @param x * the first array to be sorted. * @param y * the second array to be sorted. */ public static void quickSort(final float[] x, final float[] y) { ensureSameLength(x, y); quickSort(x, y, 0, x.length); } protected static class ForkJoinQuickSort2 extends RecursiveAction {
selectionSort(a, b, from, to); return; count[(fixFloat(k[i]) >>> shift & DIGIT_MASK ^ signMask)]++; float t = a[i]; float u = b[i]; c = (fixFloat(k[i]) >>> shift & DIGIT_MASK ^ signMask); if (i < end) { // When all slots are OK, the last slot is necessarily OK. while ((d = --pos[c]) > i) { c = (fixFloat(k[d]) >>> shift & DIGIT_MASK ^ signMask); float z = t; t = a[d]; selectionSort(a, b, i, i + count[c]); else { offsetStack[stackPos] = i;
final boolean stable) { if (to - from < RADIXSORT_NO_REC) { insertionSortIndirect(perm, a, from, to); return; count[(fixFloat(a[perm[i]]) >>> shift & DIGIT_MASK ^ signMask)]++; support[--pos[(fixFloat(a[perm[i]]) >>> shift & DIGIT_MASK ^ signMask)]] = perm[i]; System.arraycopy(support, 0, perm, first, length); for (int i = 0, p = first; i <= lastUsed; i++) { if (level < maxLevel && count[i] > 1) { if (count[i] < RADIXSORT_NO_REC) insertionSortIndirect(perm, a, p, p + count[i]); else { offsetStack[stackPos] = p; c = (fixFloat(a[t]) >>> shift & DIGIT_MASK ^ signMask); if (i < end) { // When all slots are OK, the last slot is necessarily OK. while ((d = --pos[c]) > i) { t = perm[d]; perm[d] = z; c = (fixFloat(a[t]) >>> shift & DIGIT_MASK ^ signMask); insertionSortIndirect(perm, a, i, i + count[c]); else { offsetStack[stackPos] = i;
/** * Sets the length of the given array. * * @param array * an array. * @param length * the new length for the array. * @return {@code array}, if it contains exactly {@code length} entries; * otherwise, if it contains <em>more</em> than {@code length} entries, * an array with {@code length} entries whose entries are the same as * the first {@code length} entries of {@code array}; otherwise, an * array with {@code length} entries whose first {@code array.length} * entries are the same as those of {@code array}. * */ public static float[] setLength(final float[] array, final int length) { if (length == array.length) return array; if (length < array.length) return trim(array, length); return ensureCapacity(array, length); } /**
/** * Sorts the specified pair of arrays lexicographically using radix sort. * <p> * The sorting algorithm is a tuned radix sort adapted from Peter M. McIlroy, * Keith Bostic and M. Douglas McIlroy, “Engineering radix sort”, * <i>Computing Systems</i>, 6(1), pages 5−27 (1993). * * <p> * This method implements a <em>lexicographical</em> sorting of the arguments. * Pairs of elements in the same position in the two provided arrays will be * considered a single key, and permuted accordingly. In the end, either * {@code a[i] < a[i + 1]} or {@code a[i] == a[i + 1]} and * {@code b[i] ≤ b[i + 1]}. * * @param a * the first array to be sorted. * @param b * the second array to be sorted. */ public static void radixSort(final float[] a, final float[] b) { ensureSameLength(a, b); radixSort(a, b, 0, a.length); } /**
/** * Sorts two arrays using a parallel radix sort. * * <p> * The sorting algorithm is a tuned radix sort adapted from Peter M. McIlroy, * Keith Bostic and M. Douglas McIlroy, “Engineering radix sort”, * <i>Computing Systems</i>, 6(1), pages 5−27 (1993). * * <p> * This method implements a <em>lexicographical</em> sorting of the arguments. * Pairs of elements in the same position in the two provided arrays will be * considered a single key, and permuted accordingly. In the end, either * {@code a[i] < a[i + 1]} or {@code a[i] == a[i + 1]} and * {@code b[i] ≤ b[i + 1]}. * * <p> * This implementation uses a pool of {@link Runtime#availableProcessors()} * threads. * * @param a * the first array to be sorted. * @param b * the second array to be sorted. */ public static void parallelRadixSort(final float[] a, final float[] b) { ensureSameLength(a, b); parallelRadixSort(a, b, 0, a.length); } private static void insertionSortIndirect(final int[] perm, final float[] a, final float[] b, final int from,
ensureSameLength(a, b); radixSortIndirect(perm, a, b, 0, a.length, stable);
final boolean stable) { if (to - from < PARALLEL_RADIXSORT_NO_FORK) { radixSortIndirect(perm, a, from, to, stable); return; count[(fixFloat(a[perm[i]]) >>> shift & DIGIT_MASK ^ signMask)]++; support[--pos[(fixFloat(a[perm[i]]) >>> shift & DIGIT_MASK ^ signMask)]] = perm[i]; System.arraycopy(support, first, perm, first, length); for (int i = 0, p = first; i <= lastUsed; i++) { if (level < maxLevel && count[i] > 1) { if (count[i] < PARALLEL_RADIXSORT_NO_FORK) radixSortIndirect(perm, a, p, p + count[i], stable); else { queueSize.incrementAndGet(); c = (fixFloat(a[t]) >>> shift & DIGIT_MASK ^ signMask); if (i < end) { // When all slots are OK, the last slot is necessarily OK. while ((d = --pos[c]) > i) { t = perm[d]; perm[d] = z; c = (fixFloat(a[t]) >>> shift & DIGIT_MASK ^ signMask); radixSortIndirect(perm, a, i, i + count[c], stable); else { queueSize.incrementAndGet();
/** * Ensures that an array can contain the given number of entries, preserving * just a part of the array. * * @param array * an array. * @param length * the new minimum length for this array. * @param preserve * the number of elements of the array that must be preserved in case * a new allocation is necessary. * @return {@code array}, if it can contain {@code length} entries or more; * otherwise, an array with {@code length} entries whose first * {@code preserve} entries are the same as those of {@code array}. */ public static float[] ensureCapacity(final float[] array, final int length, final int preserve) { return length > array.length ? forceCapacity(array, length, preserve) : array; } /**
/** * Ensures that this array list can contain the given number of entries without * resizing. * * @param capacity * the new minimum capacity for this array list. */ public void ensureCapacity(final int capacity) { if (capacity <= a.length || a == FloatArrays.DEFAULT_EMPTY_ARRAY) return; a = FloatArrays.ensureCapacity(a, capacity, size); assert size <= a.length; } /**
/** * Searches an array for the specified value using the binary search algorithm. * The range must be sorted prior to making this call. If it is not sorted, the * results are undefined. If the range contains multiple elements with the * specified value, there is no guarantee which one will be found. * * @param a * the array to be searched. * @param key * the value to be searched for. * @return index of the search key, if it is contained in the array; otherwise, * {@code (-(<i>insertion point</i>) - 1)}. The <i>insertion point</i> * is defined as the the point at which the value would be inserted into * the array: the index of the first element greater than the key, or * the length of the array, if all elements in the array are less than * the specified key. Note that this guarantees that the return value * will be ≥ 0 if and only if the key is found. * @see java.util.Arrays */ public static int binarySearch(final float[] a, final float key) { return binarySearch(a, 0, a.length, key); } /**
/** * Fills a portion of the given array with the given value. * * @param array * an array. * @param from * the starting index of the portion to fill (inclusive). * @param to * the end index of the portion to fill (exclusive). * @param value * the new value for all elements of the specified portion of the * array. * @deprecated Please use the corresponding {@link java.util.Arrays} method. */ @Deprecated public static void fill(final float[] array, final int from, int to, final float value) { ensureFromTo(array, from, to); if (from == 0) while (to-- != 0) array[to] = value; else for (int i = from; i < to; i++) array[i] = value; } /**
final int len = to - from; if (len < QUICKSORT_NO_REC) { selectionSort(x, y, from, to); return; if (len > QUICKSORT_MEDIAN_OF_9) { // Big arrays, pseudomedian of 9 int s = len / 8; l = med3(x, y, l, l + s, l + 2 * s); m = med3(x, y, m - s, m, m + s); n = med3(x, y, n - 2 * s, n - s, n); m = med3(x, y, l, m, n); // Mid-size, med of 3 final float v = x[m], w = y[m]; && (comparison = (t = (Float.compare((x[b]), (v)))) == 0 ? (Float.compare((y[b]), (w))) : t) <= 0) { if (comparison == 0) swap(x, y, a++, b); b++; && (comparison = (t = (Float.compare((x[c]), (v)))) == 0 ? (Float.compare((y[c]), (w))) : t) >= 0) { if (comparison == 0) swap(x, y, c, d--); c--; swap(x, y, b++, c--); swap(x, y, from, b - s, s); s = Math.min(d - c, to - d - 1); swap(x, y, b, to - s, s);