/** * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.util; import org.apache.commons.lang.Validate; /** * Performs sorting. This is not "parallel" in the sense of threads, but parallel in the sense that * two arrays are sorted in parallel. */ public class ParallelArrayBinarySort { /** * Sort the content of keys and values simultaneously so that * both match the correct ordering. Alters the arrays in place * @param keys The keys * @param values The values */ public static void parallelBinarySort(final double[] keys, final double[] values) { Validate.notNull(keys, "x data"); Validate.notNull(values, "y data"); Validate.isTrue(keys.length == values.length); final int n = keys.length; tripleArrayQuickSort(keys, values, null, 0, n - 1); } /** * Sort the content of keys and values simultaneously so that * both match the correct ordering. Alters the arrays in place. * Allow control over range of ordering for subarray ordering. * @param keys The keys * @param values The values * @param start Starting point (0-based) * @param end Final point (0-based, inclusive) */ public static void parallelBinarySort(final double[] keys, final double[] values, final int start, final int end) { Validate.notNull(keys, "x data"); Validate.notNull(values, "y data"); Validate.isTrue(keys.length == values.length); Validate.isTrue(start >= 0); Validate.isTrue(end < keys.length); tripleArrayQuickSort(keys, values, null, start, end); } /** * Sort the content of keys and two sets of values simultaneously so that * both match the correct ordering. Alters the arrays in place. * @param keys The keys * @param values1 The first set of values * @param values2 The second set of values */ public static void parallelBinarySort(final double[] keys, final double[] values1, final double[] values2) { Validate.notNull(keys, "x data"); Validate.notNull(values1, "y data 1"); Validate.notNull(values2, "y data 2"); Validate.isTrue(keys.length == values1.length); Validate.isTrue(keys.length == values2.length); final int n = keys.length; tripleArrayQuickSort(keys, values1, values2, 0, n - 1); } /** * Sort the content of keys and values simultaneously so that * both match the correct ordering. Alters the arrays in place * @param keys The keys * @param values The values */ public static void parallelBinarySort(final float[] keys, final double[] values) { Validate.notNull(keys, "x data"); Validate.notNull(values, "y data"); Validate.isTrue(keys.length == values.length); final int n = keys.length; dualArrayQuickSort(keys, values, 0, n - 1); } /** * Sort the content of keys and values simultaneously so that * both match the correct ordering. Alters the arrays in place * @param keys The keys * @param values The values */ public static void parallelBinarySort(final int[] keys, final double[] values) { Validate.notNull(keys, "x data"); Validate.notNull(values, "y data"); Validate.isTrue(keys.length == values.length); final int n = keys.length; dualArrayQuickSort(keys, values, 0, n - 1); } /** * Sort the content of keys and values simultaneously so that * both match the correct ordering. Alters the arrays in place * @param keys The keys * @param values The values */ public static void parallelBinarySort(final long[] keys, final double[] values) { Validate.notNull(keys, "x data"); Validate.notNull(values, "y data"); Validate.isTrue(keys.length == values.length); final int n = keys.length; dualArrayQuickSort(keys, values, 0, n - 1); } /** * Sort the content of keys and apply the same sort to the values. * Alters the arrays in place. * @param keys The keys * @param values The values */ public static void parallelBinarySort(final float[] keys, final int[] values) { Validate.notNull(keys, "x data"); Validate.notNull(values, "y data"); Validate.isTrue(keys.length == values.length); final int n = keys.length; dualArrayQuickSort(keys, values, 0, n - 1); } /** * Sort the content of keys and apply the same sort to the values. * Alters the arrays in place. * @param keys The keys * @param values The values */ public static void parallelBinarySort(final int[] keys, final int[] values) { Validate.notNull(keys, "x data"); Validate.notNull(values, "y data"); Validate.isTrue(keys.length == values.length); final int n = keys.length; dualArrayQuickSort(keys, values, 0, n - 1); } /** * Sort the content of keys and apply the same sort to the values. * Alters the arrays in place. * @param keys The keys * @param values The values */ public static void parallelBinarySort(final long[] keys, final int[] values) { Validate.notNull(keys, "x data"); Validate.notNull(values, "y data"); Validate.isTrue(keys.length == values.length); final int n = keys.length; dualArrayQuickSort(keys, values, 0, n - 1); } /** * Sort the content of keys and apply the same sort to the values. * Alters the arrays in place. * @param keys The keys * @param values The values */ public static void parallelBinarySort(final double[] keys, final int[] values) { Validate.notNull(keys, "x data"); Validate.notNull(values, "y data"); Validate.isTrue(keys.length == values.length); final int n = keys.length; dualArrayQuickSort(keys, values, 0, n - 1); } /** * Sort the content of keys and values simultaneously so that * both match the correct ordering. Alters the arrays in place * @param <T> The type of the keys * @param <U> The type of the values * @param keys The keys * @param values The values */ public static <T extends Comparable<T>, U> void parallelBinarySort(final T[] keys, final U[] values) { Validate.notNull(keys, "x data"); Validate.notNull(values, "y data"); Validate.isTrue(keys.length == values.length); final int n = keys.length; dualArrayQuickSort(keys, values, 0, n - 1); } /** * Sort the content of keys and values simultaneously so that * both match the correct ordering. Alters the arrays in place * @param <T> The type of the values * @param keys The keys * @param values The values */ public static <T> void parallelBinarySort(final double[] keys, final T[] values) { Validate.notNull(keys, "x data"); Validate.notNull(values, "y data"); Validate.isTrue(keys.length == values.length); final int n = keys.length; dualArrayQuickSort(keys, values, 0, n - 1); } /** quick sorts */ /** hard coded types */ private static void tripleArrayQuickSort(final double[] keys, final double[] values1, final double[] values2, final int left, final int right) { if (right > left) { final int pivot = (left + right) >> 1; final int pivotNewIndex = partition(keys, values1, values2, left, right, pivot); tripleArrayQuickSort(keys, values1, values2, left, pivotNewIndex - 1); tripleArrayQuickSort(keys, values1, values2, pivotNewIndex + 1, right); } } private static void dualArrayQuickSort(final float[] keys, final double[] values, final int left, final int right) { if (right > left) { final int pivot = (left + right) >> 1; final int pivotNewIndex = partition(keys, values, left, right, pivot); dualArrayQuickSort(keys, values, left, pivotNewIndex - 1); dualArrayQuickSort(keys, values, pivotNewIndex + 1, right); } } private static void dualArrayQuickSort(final int[] keys, final double[] values, final int left, final int right) { if (right > left) { final int pivot = (left + right) >> 1; final int pivotNewIndex = partition(keys, values, left, right, pivot); dualArrayQuickSort(keys, values, left, pivotNewIndex - 1); dualArrayQuickSort(keys, values, pivotNewIndex + 1, right); } } private static void dualArrayQuickSort(final long[] keys, final double[] values, final int left, final int right) { if (right > left) { final int pivot = (left + right) >> 1; final int pivotNewIndex = partition(keys, values, left, right, pivot); dualArrayQuickSort(keys, values, left, pivotNewIndex - 1); dualArrayQuickSort(keys, values, pivotNewIndex + 1, right); } } private static void dualArrayQuickSort(final double[] keys, final int[] values, final int left, final int right) { if (right > left) { final int pivot = (left + right) >> 1; final int pivotNewIndex = partition(keys, values, left, right, pivot); dualArrayQuickSort(keys, values, left, pivotNewIndex - 1); dualArrayQuickSort(keys, values, pivotNewIndex + 1, right); } } private static void dualArrayQuickSort(final float[] keys, final int[] values, final int left, final int right) { if (right > left) { final int pivot = (left + right) >> 1; final int pivotNewIndex = partition(keys, values, left, right, pivot); dualArrayQuickSort(keys, values, left, pivotNewIndex - 1); dualArrayQuickSort(keys, values, pivotNewIndex + 1, right); } } private static void dualArrayQuickSort(final int[] keys, final int[] values, final int left, final int right) { if (right > left) { final int pivot = (left + right) >> 1; final int pivotNewIndex = partition(keys, values, left, right, pivot); dualArrayQuickSort(keys, values, left, pivotNewIndex - 1); dualArrayQuickSort(keys, values, pivotNewIndex + 1, right); } } private static void dualArrayQuickSort(final long[] keys, final int[] values, final int left, final int right) { if (right > left) { final int pivot = (left + right) >> 1; final int pivotNewIndex = partition(keys, values, left, right, pivot); dualArrayQuickSort(keys, values, left, pivotNewIndex - 1); dualArrayQuickSort(keys, values, pivotNewIndex + 1, right); } } /** bendy types */ private static <T extends Comparable<T>, U> void dualArrayQuickSort(final T[] keys, final U[] values, final int left, final int right) { if (right > left) { final int pivot = (left + right) >> 1; final int pivotNewIndex = partition(keys, values, left, right, pivot); dualArrayQuickSort(keys, values, left, pivotNewIndex - 1); dualArrayQuickSort(keys, values, pivotNewIndex + 1, right); } } private static <T> void dualArrayQuickSort(final double[] keys, final T[] values, final int left, final int right) { if (right > left) { final int pivot = (left + right) >> 1; final int pivotNewIndex = partition(keys, values, left, right, pivot); dualArrayQuickSort(keys, values, left, pivotNewIndex - 1); dualArrayQuickSort(keys, values, pivotNewIndex + 1, right); } } /** partitions */ /** hard coded types */ private static int partition(final double[] keys, final double[] values1, final double[] values2, final int left, final int right, final int pivot) { final double pivotValue = keys[pivot]; swap(keys, values1, values2, pivot, right); int storeIndex = left; for (int i = left; i < right; i++) { if (keys[i] <= pivotValue) { swap(keys, values1, values2, i, storeIndex); storeIndex++; } } swap(keys, values1, values2, storeIndex, right); return storeIndex; } private static int partition(final float[] keys, final double[] values, final int left, final int right, final int pivot) { final double pivotValue = keys[pivot]; swap(keys, values, pivot, right); int storeIndex = left; for (int i = left; i < right; i++) { if (keys[i] <= pivotValue) { swap(keys, values, i, storeIndex); storeIndex++; } } swap(keys, values, storeIndex, right); return storeIndex; } private static int partition(final int[] keys, final double[] values, final int left, final int right, final int pivot) { final double pivotValue = keys[pivot]; swap(keys, values, pivot, right); int storeIndex = left; for (int i = left; i < right; i++) { if (keys[i] <= pivotValue) { swap(keys, values, i, storeIndex); storeIndex++; } } swap(keys, values, storeIndex, right); return storeIndex; } private static int partition(final long[] keys, final double[] values, final int left, final int right, final int pivot) { final double pivotValue = keys[pivot]; swap(keys, values, pivot, right); int storeIndex = left; for (int i = left; i < right; i++) { if (keys[i] <= pivotValue) { swap(keys, values, i, storeIndex); storeIndex++; } } swap(keys, values, storeIndex, right); return storeIndex; } private static int partition(final double[] keys, final int[] values, final int left, final int right, final int pivot) { final double pivotValue = keys[pivot]; swap(keys, values, pivot, right); int storeIndex = left; for (int i = left; i < right; i++) { if (keys[i] <= pivotValue) { swap(keys, values, i, storeIndex); storeIndex++; } } swap(keys, values, storeIndex, right); return storeIndex; } private static int partition(final float[] keys, final int[] values, final int left, final int right, final int pivot) { final double pivotValue = keys[pivot]; swap(keys, values, pivot, right); int storeIndex = left; for (int i = left; i < right; i++) { if (keys[i] <= pivotValue) { swap(keys, values, i, storeIndex); storeIndex++; } } swap(keys, values, storeIndex, right); return storeIndex; } private static int partition(final int[] keys, final int[] values, final int left, final int right, final int pivot) { final double pivotValue = keys[pivot]; swap(keys, values, pivot, right); int storeIndex = left; for (int i = left; i < right; i++) { if (keys[i] <= pivotValue) { swap(keys, values, i, storeIndex); storeIndex++; } } swap(keys, values, storeIndex, right); return storeIndex; } private static int partition(final long[] keys, final int[] values, final int left, final int right, final int pivot) { final double pivotValue = keys[pivot]; swap(keys, values, pivot, right); int storeIndex = left; for (int i = left; i < right; i++) { if (keys[i] <= pivotValue) { swap(keys, values, i, storeIndex); storeIndex++; } } swap(keys, values, storeIndex, right); return storeIndex; } /** bendy types */ private static <T extends Comparable<T>, U> int partition(final T[] keys, final U[] values, final int left, final int right, final int pivot) { final T pivotValue = keys[pivot]; swap(keys, values, pivot, right); int storeIndex = left; for (int i = left; i < right; i++) { if (keys[i].compareTo(pivotValue) < 1) { swap(keys, values, i, storeIndex); storeIndex++; } } swap(keys, values, storeIndex, right); return storeIndex; } private static <T> int partition(final double[] keys, final T[] values, final int left, final int right, final int pivot) { final double pivotValue = keys[pivot]; swap(keys, values, pivot, right); int storeIndex = left; for (int i = left; i < right; i++) { if (keys[i] <= pivotValue) { swap(keys, values, i, storeIndex); storeIndex++; } } swap(keys, values, storeIndex, right); return storeIndex; } /** swappers */ /** hardcoded */ private static void swap(final double[] keys, final double[] values1, final double[] values2, final int first, final int second) { double t = keys[first]; keys[first] = keys[second]; keys[second] = t; if (values1 != null) { t = values1[first]; values1[first] = values1[second]; values1[second] = t; } if (values2 != null) { t = values2[first]; values2[first] = values2[second]; values2[second] = t; } } private static void swap(final float[] keys, final double[] values, final int first, final int second) { float t = keys[first]; double k = values[first]; keys[first] = keys[second]; keys[second] = t; k = values[first]; values[first] = values[second]; values[second] = k; } private static void swap(final int[] keys, final double[] values, final int first, final int second) { int t = keys[first]; double k = values[first]; keys[first] = keys[second]; keys[second] = t; k = values[first]; values[first] = values[second]; values[second] = k; } private static void swap(final long[] keys, final double[] values, final int first, final int second) { long t = keys[first]; double k = values[first]; keys[first] = keys[second]; keys[second] = t; k = values[first]; values[first] = values[second]; values[second] = k; } private static void swap(final double[] keys, final int[] values, final int first, final int second) { double t = keys[first]; int k = values[first]; keys[first] = keys[second]; keys[second] = t; k = values[first]; values[first] = values[second]; values[second] = k; } private static void swap(final float[] keys, final int[] values, final int first, final int second) { float t = keys[first]; int k = values[first]; keys[first] = keys[second]; keys[second] = t; k = values[first]; values[first] = values[second]; values[second] = k; } private static void swap(final int[] keys, final int[] values, final int first, final int second) { int t = keys[first]; int k = values[first]; keys[first] = keys[second]; keys[second] = t; k = values[first]; values[first] = values[second]; values[second] = k; } private static void swap(final long[] keys, final int[] values, final int first, final int second) { long t = keys[first]; int k = values[first]; keys[first] = keys[second]; keys[second] = t; k = values[first]; values[first] = values[second]; values[second] = k; } /* bendy types */ private static <T extends Comparable<T>, U> void swap(final T[] keys, final U[] values, final int first, final int second) { final T t = keys[first]; keys[first] = keys[second]; keys[second] = t; final U u = values[first]; values[first] = values[second]; values[second] = u; } private static <T> void swap(final double[] keys, final T[] values, final int first, final int second) { final double x = keys[first]; keys[first] = keys[second]; keys[second] = x; final T t = values[first]; values[first] = values[second]; values[second] = t; } }