package uk.ac.rhul.cs.utils; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; /** * Various utility functions related to arrays * * @author tamas */ public class ArrayUtils { /** * Returns the median of the elements in the given array. * * @param array the array for which we need the median * @return the median or null if the array is empty */ public static Double getMedian(double[] array) { if (array.length == 0) return null; double[] copy = array.clone(); int midpoint = copy.length / 2; Arrays.sort(copy); if (copy.length % 2 == 0) return (copy[midpoint-1] + copy[midpoint]) / 2; return copy[midpoint]; } /** * Gets the ranks of elements in the given array * * @param array the array for which we need the ranks * @param tolerance tolerance value within which two values are considered equal */ public static double[] getRanks(double[] array, double tolerance) { int i, j, n = array.length; ArrayList<Pair<Double, Integer>> valuesAndIndices = new ArrayList<Pair<Double, Integer>>(n); double[] ranks = new double[n]; if (n == 0) return ranks; for (i = 0; i < n; i++) { valuesAndIndices.add(Pair.create(array[i], i)); } Collections.sort(valuesAndIndices, new Comparator<Pair<Double, Integer>>() { public int compare(Pair<Double, Integer> foo, Pair<Double, Integer> bar) { return foo.getLeft().compareTo(bar.getLeft()); } }); int sumRanks = 0; int dupCount = 1; Pair<Double, Integer> prev = valuesAndIndices.get(0); for (i = 1; i < n; i++) { Pair<Double, Integer> curr = valuesAndIndices.get(i); if (Math.abs(curr.getLeft() - prev.getLeft()) < tolerance) { dupCount++; sumRanks += i; } else { double rank = (double)sumRanks / dupCount + 1; for (j = i - dupCount; j < i; j++) ranks[valuesAndIndices.get(j).getRight()] = rank; dupCount = 1; sumRanks = i; } prev = curr; } double rank = (double)sumRanks / dupCount + 1; for (j = n - dupCount; j < n; j++) ranks[valuesAndIndices.get(j).getRight()] = rank; return ranks; } /** * Returns the minimum element of an array */ public static double min(double[] array) { if (array.length == 0) throw new IllegalArgumentException("array must not be empty"); double result = array[0]; int i, n = array.length; for (i = 0; i < n; i++) if (array[i] < result) result = array[i]; return result; } /** * Returns the maximum element of an array */ public static double max(double[] array) { if (array.length == 0) throw new IllegalArgumentException("array must not be empty"); double result = array[0]; int i, n = array.length; for (i = 0; i < n; i++) if (array[i] > result) result = array[i]; return result; } }