📄 utils.java
字号:
* 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; int c;
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
*/
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;
}
/**
* 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
* @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;
if (Double.isNaN(array[i])) {
array[i] = Double.MAX_VALUE;
}
}
quickSort(array, index, 0, array.length - 1);
return index;
}
/**
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -