📄 utils.java
字号:
* @param options an array of options suitable for passing to setOptions. May * be null. Any options accepted by the object will be removed from the * array. * @return the newly created object, ready for use. * @exception Exception if the class name is invalid, or if the * class is not assignable to the desired class type, or the options * supplied are not acceptable to the object */ public static Object forName(Class classType, String className, String [] options) throws Exception { Class c = null; try { c = Class.forName(className); } catch (Exception ex) { throw new Exception("Can't find class called: " + className); } if (!classType.isAssignableFrom(c)) { throw new Exception(classType.getName() + " is not assignable from " + className); } Object o = c.newInstance(); if ((o instanceof OptionHandler) && (options != null)) { ((OptionHandler)o).setOptions(options); Utils.checkForRemainingOptions(options); } return o; } /** * Computes entropy for an array of integers. * * @param counts array of counts * @return - a log2 a - b log2 b - c log2 c + (a+b+c) log2 (a+b+c) * when given array [a b c] */ public static /*@pure@*/ double info(int counts[]) { int total = 0; double x = 0; for (int j = 0; j < counts.length; j++) { x -= xlogx(counts[j]); total += counts[j]; } return x + xlogx(total); } /** * Tests if a is smaller or equal to b. * * @param a a double * @param b a double */ public static /*@pure@*/ boolean smOrEq(double a,double b) { return (a-b < SMALL); } /** * Tests if a is greater or equal to b. * * @param a a double * @param b a double */ public static /*@pure@*/ boolean grOrEq(double a,double b) { return (b-a < SMALL); } /** * Tests if a is smaller than b. * * @param a a double * @param b a double */ public static /*@pure@*/ boolean sm(double a,double b) { return (b-a > SMALL); } /** * Tests if a is greater than b. * * @param a a double * @param b a double */ public static /*@pure@*/ boolean gr(double a,double b) { return (a-b > SMALL); } /** * Returns the kth-smallest value in the array. * * @param array the array of integers * @param k the value of k * @return the kth-smallest value */ public static double kthSmallestValue(int[] array, int k) { int [] index = new int[array.length]; for (int i = 0; i < index.length; i++) { index[i] = i; } return array[index[select(array, index, 0, array.length - 1, k)]]; } /** * Returns the kth-smallest value in the array * * @param array the array of double * @param k the value of k * @return the kth-smallest value */ public static double kthSmallestValue(double[] array, int k) { int [] index = new int[array.length]; for (int i = 0; i < index.length; i++) { index[i] = i; } return array[index[select(array, index, 0, array.length - 1, k)]]; } /** * Returns the logarithm of a for base 2. * * @param a a double * @return the logarithm for base 2 */ public static /*@pure@*/ double log2(double a) { return Math.log(a) / log2; } /** * Returns index of maximum element in a given * array of doubles. First maximum is returned. * * @param doubles the array of doubles * @return the index of the maximum element */ public static /*@pure@*/ int maxIndex(double [] doubles) { double maximum = 0; int maxIndex = 0; for (int i = 0; i < doubles.length; i++) { if ((i == 0) || (doubles[i] > maximum)) { maxIndex = i; maximum = doubles[i]; } } return maxIndex; } /** * Returns index of maximum element in a given * array of integers. First maximum is returned. * * @param ints the array of integers * @return the index of the maximum element */ public static /*@pure@*/ int maxIndex(int [] ints) { int maximum = 0; int maxIndex = 0; for (int i = 0; i < ints.length; i++) { if ((i == 0) || (ints[i] > maximum)) { maxIndex = i; maximum = ints[i]; } } return maxIndex; } /** * Computes the mean for an array of doubles. * * @param vector the array * @return the mean */ public static /*@pure@*/ double mean(double[] vector) { double sum = 0; if (vector.length == 0) { return 0; } for (int i = 0; i < vector.length; i++) { sum += vector[i]; } return sum / (double) vector.length; } /** * Returns index of minimum element in a given * array of integers. First minimum is returned. * * @param ints the array of integers * @return the index of the minimum element */ public static /*@pure@*/ int minIndex(int [] ints) { int minimum = 0; int minIndex = 0; for (int i = 0; i < ints.length; i++) { if ((i == 0) || (ints[i] < minimum)) { minIndex = i; minimum = ints[i]; } } return minIndex; } /** * Returns index of minimum element in a given * array of doubles. First minimum is returned. * * @param doubles the array of doubles * @return the index of the minimum element */ public static /*@pure@*/ int minIndex(double [] doubles) { double minimum = 0; int minIndex = 0; for (int i = 0; i < doubles.length; i++) { if ((i == 0) || (doubles[i] < minimum)) { minIndex = i; minimum = doubles[i]; } } return minIndex; } /** * Normalizes the doubles in the array by their sum. * * @param doubles the array of double * @exception IllegalArgumentException if sum is Zero or NaN */ public static void normalize(double[] doubles) { double sum = 0; for (int i = 0; i < doubles.length; i++) { sum += doubles[i]; } normalize(doubles, sum); } /** * Normalizes the doubles in the array using the given value. * * @param doubles the array of double * @param sum the value by which the doubles are to be normalized * @exception IllegalArgumentException if sum is zero or NaN */ public static void normalize(double[] doubles, double sum) { if (Double.isNaN(sum)) { throw new IllegalArgumentException("Can't normalize array. Sum is NaN."); } if (sum == 0) { // Maybe this should just be a return. throw new IllegalArgumentException("Can't normalize array. Sum is zero."); } for (int i = 0; i < doubles.length; i++) { doubles[i] /= sum; } } /** * Converts an array containing the natural logarithms of * probabilities stored in a vector back into probabilities. * The probabilities are assumed to sum to one. * * @param a an array holding the natural logarithms of the probabilities * @return the converted array */ public static double[] logs2probs(double[] a) { double max = a[maxIndex(a)]; double sum = 0.0; double[] result = new double[a.length]; for(int i = 0; i < a.length; i++) { result[i] = Math.exp(a[i] - max); sum += result[i]; } normalize(result, sum); return result; } /** * Returns the log-odds for a given probabilitiy. * * @param prob the probabilitiy * * @return the log-odds after the probability has been mapped to * [Utils.SMALL, 1-Utils.SMALL] */ public static /*@pure@*/ double probToLogOdds(double prob) { if (gr(prob, 1) || (sm(prob, 0))) { throw new IllegalArgumentException("probToLogOdds: probability must " + "be in [0,1] "+prob); } double p = SMALL + (1.0 - 2 * SMALL) * prob; return Math.log(p / (1 - p)); } /** * Rounds a double to the next nearest integer value. The JDK version * of it doesn't work properly. * * @param value the double value * @return the resulting integer value */ public static /*@pure@*/ int round(double value) { int roundedValue = value > 0 ? (int)(value + 0.5) : -(int)(Math.abs(value) + 0.5); return roundedValue; } /** * Rounds a double to the next nearest integer value in a probabilistic * fashion (e.g. 0.8 has a 20% chance of being rounded down to 0 and a * 80% chance of being rounded up to 1). In the limit, the average of * the rounded numbers generated by this procedure should converge to * the original double. * * @param value the double value * @param rand the random number generator * @return the resulting integer value */ public static int probRound(double value, Random rand) { if (value >= 0) { double lower = Math.floor(value); double prob = value - lower; if (rand.nextDouble() < prob) { return (int)lower + 1; } else { return (int)lower; } } else { double lower = Math.floor(Math.abs(value)); double prob = Math.abs(value) - lower; if (rand.nextDouble() < prob) { return -((int)lower + 1); } else { return -(int)lower; } } } /** * Rounds a double to the given number of decimal places. * * @param value the double value * @param afterDecimalPoint the number of digits after the decimal point * @return the double rounded to the given precision */ public static /*@pure@*/ double roundDouble(double value,int afterDecimalPoint) { double mask = Math.pow(10.0, (double)afterDecimalPoint); return (double)(Math.round(value * mask)) / mask; } /** * Sorts a given array of integers in ascending order and returns an * array of integers with the positions of the elements of the original * array in the sorted array. The sort is stable. (Equal elements remain * in their original order.) * * @param array this array is not changed by the method! * @return an array of integers with the positions in the sorted * array. */ public static /*@pure@*/ int[] sort(int [] array) { int [] index = new int[array.length]; int [] newIndex = new int[array.length]; int [] helpIndex; int numEqual; for (int i = 0; i < index.length; i++) { index[i] = i; } quickSort(array, index, 0, array.length - 1); // Make sort stable int i = 0; while (i < index.length) { numEqual = 1; for (int j = i + 1; ((j < index.length) && (array[index[i]] == array[index[j]])); j++) { numEqual++; } if (numEqual > 1) { helpIndex = new int[numEqual]; for (int j = 0; j < numEqual; j++) { helpIndex[j] = i + j; } quickSort(index, helpIndex, 0, numEqual - 1); for (int j = 0; j < numEqual; j++) { newIndex[i + j] = index[helpIndex[j]]; } i += numEqual; } else { newIndex[i] = index[i]; i++; } } return newIndex; } /** * Sorts a given array of doubles in ascending order and returns an * array of integers with the positions of the elements of the * original array in the sorted array. NOTE THESE CHANGES: the sort * is no longer stable and it doesn't use safe floating-point * comparisons anymore. Occurrences of Double.NaN are treated as * Double.MAX_VALUE * * @param array this array is not changed by the method! * @return an array of integers with the positions in the sorted * array. */ public static /*@pure@*/ int[] sort(/*@non_null@*/ double [] array) { int [] index = new int[array.length]; array = (double [])array.clone(); for (int i = 0; i < index.length; i++) { index[i] = i;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -