/*
* Copyright (C) 2008-2015 by Holger Arndt
*
* This file is part of the Universal Java Matrix Package (UJMP).
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership and licensing.
*
* UJMP is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* UJMP is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with UJMP; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
package org.ujmp.core.util;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Random;
import java.util.UUID;
import org.ujmp.core.Matrix;
import org.ujmp.core.collections.list.FastArrayList;
public abstract class MathUtil {
private static List dateFormats = null;
public static final double EPSILON = 1e-12;
public static final double ROOT2PI = Math.sqrt(2.0 * Math.PI);
public static final double LOG10 = Math.log(10.0);
public static final double LOG2 = Math.log(2.0);
private static final double COFGAMMALN[] = { 76.18009172947146, -86.50532032941677,
24.01409824083091, -1.231739572450155, 0.1208650973866179e-2, -0.5395239384953e-5 };
private static long seed = System.nanoTime();
private static final ThreadLocal randoms = new ThreadLocal();
private static final Random random = new RandomSimple();
public static Random getRandom() {
if (UJMPSettings.getInstance().isUseMultiThreadedRandom()) {
Random random = randoms.get();
if (random == null) {
random = new RandomSimple();
randoms.set(random);
}
return random;
} else {
return random;
}
}
static {
try {
getRandom().setSeed(seed);
dateFormats = new FastArrayList();
dateFormats.add(DateFormat.getDateInstance(DateFormat.SHORT, Locale.US));
dateFormats.add(DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.US));
dateFormats.add(DateFormat.getDateInstance(DateFormat.LONG, Locale.US));
dateFormats.add(DateFormat.getDateInstance(DateFormat.SHORT, Locale.GERMAN));
dateFormats.add(DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.GERMAN));
dateFormats.add(DateFormat.getDateInstance(DateFormat.LONG, Locale.GERMAN));
dateFormats.add(DateFormat.getTimeInstance(DateFormat.SHORT, Locale.US));
dateFormats.add(DateFormat.getTimeInstance(DateFormat.MEDIUM, Locale.US));
dateFormats.add(DateFormat.getTimeInstance(DateFormat.LONG, Locale.US));
dateFormats.add(DateFormat.getTimeInstance(DateFormat.SHORT, Locale.GERMAN));
dateFormats.add(DateFormat.getTimeInstance(DateFormat.MEDIUM, Locale.GERMAN));
dateFormats.add(DateFormat.getTimeInstance(DateFormat.LONG, Locale.GERMAN));
} catch (Throwable t) {
}
}
public static String md5(String text) throws NoSuchAlgorithmException {
return md5(text.getBytes());
}
public static final int search(final long[] values, int fromIndex, int toIndex, final long key) {
toIndex--;
while (fromIndex <= toIndex) {
int mid = (fromIndex + toIndex) >>> 1;
long midVal = values[mid];
if (midVal < key) {
fromIndex = mid + 1;
} else if (midVal > key) {
toIndex = mid - 1;
} else {
return mid;
}
}
return -(fromIndex + 1);
}
public static String md5(byte[] data) {
MessageDigest mdAlgorithm;
StringBuilder hexString = new StringBuilder();
try {
mdAlgorithm = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
mdAlgorithm.update(data);
byte[] digest = mdAlgorithm.digest();
for (int i = 0; i < digest.length; i++) {
String text = Integer.toHexString(0xFF & digest[i]);
if (text.length() < 2) {
text = "0" + text;
}
hexString.append(text);
}
hexString.trimToSize();
return hexString.toString();
}
public static String md5(File file) throws NoSuchAlgorithmException, IOException {
MessageDigest mdAlgorithm;
StringBuilder hexString = new StringBuilder();
mdAlgorithm = MessageDigest.getInstance("MD5");
FileInputStream fi = new FileInputStream(file);
BufferedInputStream bi = new BufferedInputStream(fi);
byte[] data = new byte[8192];
for (int length = bi.read(data); length != -1; length = bi.read(data)) {
mdAlgorithm.update(data, 0, length);
}
bi.close();
fi.close();
byte[] digest = mdAlgorithm.digest();
for (int i = 0; i < digest.length; i++) {
String text = Integer.toHexString(0xFF & digest[i]);
if (text.length() < 2) {
text = "0" + text;
}
hexString.append(text);
}
hexString.trimToSize();
return hexString.toString();
}
public static String md5(Serializable o) throws NoSuchAlgorithmException, IOException {
return md5(SerializationUtil.serialize(o));
}
// public static final Random getRandom() {
// return random;
// }
public static final boolean xor(boolean b1, boolean b2) {
if (b1 == false && b2 == false) {
return false;
} else if (b1 == false && b2 == true) {
return true;
} else if (b1 == true && b2 == false) {
return true;
} else {
return false;
}
}
public static double[] logToProbs(double[] logs) {
double[] probs = new double[logs.length];
double max = MathUtil.max(logs);
logs = MathUtil.minus(logs, max);
double sum = 0.0;
for (int i = 0; i < probs.length; i++) {
probs[i] = Math.exp(logs[i]);
sum += probs[i];
}
if (sum == 0) {
Arrays.fill(probs, 0.0);
return probs;
}
// renormalize if necessary
while (sum < 1e-6) {
sum = 0;
for (int i = 0; i < probs.length; i++) {
probs[i] *= 10;
sum += probs[i];
}
}
for (int i = 0; i < probs.length; i++) {
probs[i] = probs[i] / sum;
}
return probs;
}
public static double[] plus(double[] values, double value) {
double[] result = Arrays.copyOf(values, values.length);
for (int i = 0; i < values.length; i++) {
result[i] += value;
}
return result;
}
public static double[] minus(double[] values, double value) {
double[] result = Arrays.copyOf(values, values.length);
for (int i = 0; i < values.length; i++) {
result[i] -= value;
}
return result;
}
public static final long getSeed() {
return seed;
}
public static final double round(double value, int decimals) {
return Math.round(value * Math.pow(10, decimals)) / Math.pow(10, decimals);
}
public static void setSeed(long seed) {
MathUtil.seed = seed;
getRandom().setSeed(seed);
}
public static final double log2(final double d) {
return Math.log(d) / LOG2;
}
public static final double log10(final double d) {
return Math.log(d) / LOG10;
}
public static int hash(int h) {
// This function ensures that hashCodes that differ only by
// constant multiples at each bit position have a bounded
// number of collisions (approximately 8 at default load factor).
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}
public static final double gauss(final double mean, final double sigma, final double x) {
return Math.exp(-0.5 * Math.pow((x - mean) / sigma, 2.0)) / (sigma * ROOT2PI);
}
public static final double artanh(double x) {
return 0.5 * Math.log((1 + x) / (1 - x));
}
public static final double nextGaussian(double mean, double sigma) {
return sigma <= 0.0 ? 0.0 : sigma * getRandom().nextGaussian() + mean;
}
public static final double nextGaussian() {
return getRandom().nextGaussian();
}
public static final double nextDouble(double min, double max) {
return min + getRandom().nextDouble() * (max - min);
}
/**
* Returns a random value in the desired interval
*
* @param min
* minimum value (inclusive)
* @param max
* maximum value (exclusive)
* @return a random value
*/
public static final int nextInteger(int min, int max) {
return min == max ? min : min + getRandom().nextInt(max - min);
}
public static final int nextInteger(int max) {
return getRandom().nextInt(max);
}
public static boolean isEventHappening(double probability) {
return nextDouble() < probability;
}
public static boolean nextBoolean() {
return getRandom().nextBoolean();
}
public static double nextDouble() {
return getRandom().nextDouble();
}
public static final double ignoreNaN(final double v) {
return Double.isNaN(v) || (v == Double.POSITIVE_INFINITY)
|| (v == Double.NEGATIVE_INFINITY) ? 0.0 : v;
}
public static final boolean isNaNOrInfinite(final double v) {
return Double.isNaN(v) || (v == Double.POSITIVE_INFINITY)
|| (v == Double.NEGATIVE_INFINITY);
}
public static final boolean isNaNOrInfinite(final Object o) {
return Double.valueOf(Double.NaN).equals(o)
|| Double.valueOf(Double.POSITIVE_INFINITY).equals(o)
|| Double.valueOf(Double.NEGATIVE_INFINITY).equals(o);
}
public static final Matrix getMatrix(Object o) {
if (o == null) {
return null;
}
if (o instanceof Matrix) {
Matrix m = (Matrix) o;
if (m.isScalar() && m.getAsObject(0, 0) instanceof Matrix) {
return getMatrix(m.getAsObject(0, 0));
} else {
return m;
}
} else {
return Matrix.Factory.linkToValue(o);
}
}
public static final Date getDate(Object o) {
if (o == null) {
return null;
}
if (o instanceof Date) {
return (Date) o;
}
if (o instanceof Long) {
return new Date((Long) o);
}
if (o instanceof String) {
for (DateFormat df : dateFormats) {
try {
return df.parse((String) o);
} catch (Exception e) {
}
}
}
return new Date(getLong(o));
}
public static final double getDouble(final Object o) {
if (o == null) {
return 0.0;
} else if (o instanceof Double) {
return (Double) o;
} else if (o instanceof Date) {
return ((Date) o).getTime();
} else if (o instanceof Matrix) {
return ((Matrix) o).doubleValue();
} else {
if ("true".equalsIgnoreCase(o.toString())) {
return 1.0;
}
if ("false".equalsIgnoreCase(o.toString())) {
return 0.0;
}
try {
return Double.parseDouble(o.toString());
} catch (Exception e) {
}
}
return Double.NaN;
}
/** sqrt(a^2 + b^2) without under/overflow. **/
public static final double hypot(final double a, final double b) {
double r;
if (Math.abs(a) > Math.abs(b)) {
r = b / a;
r = Math.abs(a) * Math.sqrt(1.0 + r * r);
} else if (b != 0) {
r = a / b;
r = Math.abs(b) * Math.sqrt(1.0 + r * r);
} else {
r = 0.0;
}
return r;
}
public static final long[] collectionToLongArray(final Collection extends Number> numbers) {
final long[] ret = new long[numbers.size()];
int i = 0;
for (Number n : numbers) {
ret[i++] = n.longValue();
}
return ret;
}
public static final double[] collectionToDoubleArray(final Collection extends Number> numbers) {
final double[] ret = new double[numbers.size()];
int i = 0;
for (Number n : numbers) {
ret[i++] = n.doubleValue();
}
return ret;
}
public static final int[] collectionToIntArray(final Collection extends Number> numbers) {
final int[] ret = new int[numbers.size()];
int i = 0;
for (Number n : numbers) {
ret[i++] = n.intValue();
}
return ret;
}
public static List toLongList(long[] numbers) {
List ret = new FastArrayList(numbers.length);
for (int i = 0; i < numbers.length; i++) {
ret.add(numbers[i]);
}
return ret;
}
public static List toLongList(int[] numbers) {
List ret = new FastArrayList(numbers.length);
for (int i = 0; i < numbers.length; i++) {
ret.add((long) numbers[i]);
}
return ret;
}
public static List toDoubleList(double[] numbers) {
List ret = new FastArrayList(numbers.length);
for (int i = 0; i < numbers.length; i++) {
ret.add(numbers[i]);
}
return ret;
}
public static List toDoubleList(int[] numbers) {
List ret = new FastArrayList(numbers.length);
for (int i = 0; i < numbers.length; i++) {
ret.add((double) numbers[i]);
}
return ret;
}
public static List toDoubleList(long[] numbers) {
List ret = new FastArrayList(numbers.length);
for (int i = 0; i < numbers.length; i++) {
ret.add((double) numbers[i]);
}
return ret;
}
public static double[] toDoubleArray(int... intArray) {
int nmb = intArray.length;
double[] ret = new double[nmb];
for (int i = 0; i < nmb; i++)
ret[i] = intArray[i];
return ret;
}
public static double[][] toDoubleArray(int[]... intArray) {
int rows = intArray.length;
if (rows <= 0)
return new double[0][0];
int cols = intArray[0].length;
double[][] ret = new double[rows][cols];
for (int i = rows - 1; i >= 0; i--) {
for (int j = cols - 1; j >= 0; j--) {
ret[i][j] = intArray[i][j];
}
}
return ret;
}
public static List sequenceListLong(long startInclusive, long endExclusive) {
return sequenceListLong(startInclusive, endExclusive, 1);
}
public static List sequenceListLong(long startInclusive, long endExclusive, long stepsize) {
List list = new FastArrayList();
if (startInclusive < endExclusive) {
stepsize = Math.abs(stepsize);
for (long l = startInclusive; l < endExclusive; l += stepsize) {
list.add(l);
}
} else {
stepsize = -Math.abs(stepsize);
for (long l = startInclusive; l > endExclusive; l += stepsize) {
list.add(l);
}
}
return list;
}
public static List sequenceListDouble(double startInclusive, double endExclusive) {
return sequenceListDouble(startInclusive, endExclusive, 1);
}
public static List sequenceListDouble(double startInclusive, double endExclusive,
double stepsize) {
List list = new FastArrayList();
if (startInclusive < endExclusive) {
stepsize = Math.abs(stepsize);
for (double l = startInclusive; l < endExclusive; l += stepsize) {
list.add(l);
}
} else {
stepsize = -Math.abs(stepsize);
for (double l = startInclusive; l > endExclusive; l += stepsize) {
list.add(l);
}
}
return list;
}
public static List sequenceListInt(int startInclusive, int endExclusive) {
List list = new FastArrayList();
if (startInclusive < endExclusive) {
for (int l = startInclusive; l < endExclusive; l++) {
list.add(l);
}
} else {
for (int l = startInclusive - 1; l > endExclusive; l--) {
list.add(l);
}
}
return list;
}
public static long[] sequenceLong(long startInclusive, long endExclusive) {
return collectionToLongArray(sequenceListLong(startInclusive, endExclusive));
}
public static long[] sequenceLong(long startInclusive, long endExclusive, long stepsize) {
return collectionToLongArray(sequenceListLong(startInclusive, endExclusive, stepsize));
}
public static double[] sequenceDouble(double startInclusive, double endExclusive) {
return collectionToDoubleArray(sequenceListDouble(startInclusive, endExclusive));
}
public static double[] sequenceDouble(double startInclusive, double endExclusive,
double stepsize) {
return collectionToDoubleArray(sequenceListDouble(startInclusive, endExclusive, stepsize));
}
public static int[] sequenceInt(int startInclusive, int endExclusive) {
return collectionToIntArray(sequenceListInt(startInclusive, endExclusive));
}
public static List randPermLong(long startInclusive, long endExclusive) {
List list = sequenceListLong(startInclusive, endExclusive);
Collections.shuffle(list);
return list;
}
public static List randPermInt(int startInclusive, int endExclusive) {
List list = sequenceListInt(startInclusive, endExclusive);
Collections.shuffle(list);
return list;
}
public static boolean equals(Object o1, Object o2) {
if (o1 == o2) {
return true;
} else if (o1 == null && o2 != null) {
return false;
} else if (o1 != null && o2 == null) {
return false;
} else if ((o1 instanceof Matrix) && (o2 instanceof Matrix)) {
return ((Matrix) o1).equals((Matrix) o2);
} else if ((o1 instanceof Number) && (o2 instanceof Number)) {
return getDouble(o1) == getDouble(o2);
} else if ((o1 instanceof String) && (o2 instanceof String)) {
return ((String) o1).equals((String) o2);
} else if ((o1 instanceof Boolean) && (o2 instanceof Boolean)) {
return ((Boolean) o1).equals(o2);
} else if ((o1 instanceof BigDecimal) && (o2 instanceof BigDecimal)) {
return ((BigDecimal) o1).compareTo((BigDecimal) o2) == 0;
} else if ((o1 instanceof BigInteger) && (o2 instanceof BigInteger)) {
return ((BigInteger) o1).compareTo((BigInteger) o2) == 0;
} else if ((o1 instanceof String) && (o2 instanceof Number)) {
return getDouble(o1) == getDouble(o2);
} else if ((o1 instanceof Number) && (o2 instanceof String)) {
return getDouble(o1) == getDouble(o2);
} else {
return o1.equals(o2);
}
}
public static double sensitivity(double tp, double fn) {
double r = tp / (tp + fn);
return MathUtil.isNaNOrInfinite(r) ? 0.0 : r;
}
public static double specificity(double tn, double fp) {
double r = tn / (tn + fp);
return MathUtil.isNaNOrInfinite(r) ? 0.0 : r;
}
public static double positivePredictiveValue(double tp, double fp) {
double r = tp / (tp + fp);
return MathUtil.isNaNOrInfinite(r) ? 0.0 : r;
}
public static double negativePredictiveValue(double tn, double fn) {
double r = tn / (tn + fn);
return MathUtil.isNaNOrInfinite(r) ? 0.0 : r;
}
public static double falsePositiveRate(double fp, double tn) {
double r = fp / (fp + tn);
return MathUtil.isNaNOrInfinite(r) ? 0.0 : r;
}
public static double falseNegativeRate(double fn, double tp) {
double r = fn / (fn + tp);
return MathUtil.isNaNOrInfinite(r) ? 0.0 : r;
}
public static double recall(double tp, double fn) {
double r = tp / (tp + fn);
return MathUtil.isNaNOrInfinite(r) ? 0.0 : r;
}
public static double precision(double tp, double fp) {
double r = tp / (tp + fp);
return MathUtil.isNaNOrInfinite(r) ? 0.0 : r;
}
public static double fallout(double tn, double fp) {
double r = tn / (fp + tn);
return MathUtil.isNaNOrInfinite(r) ? 0.0 : r;
}
public static double trueNegativeRate(double tn, double fp) {
double r = tn / (fp + tn);
return MathUtil.isNaNOrInfinite(r) ? 0.0 : r;
}
public static double f1Measure(double precision, double recall) {
double r = (2.0 * precision * recall) / (precision + recall);
return MathUtil.isNaNOrInfinite(r) ? 0.0 : r;
}
public static double fBetaMeasure(double beta, double precision, double recall) {
double r = ((1 + beta * beta) * precision * recall) / (beta * beta * precision + recall);
return MathUtil.isNaNOrInfinite(r) ? 0.0 : r;
}
public static Object getPreferredObject(Object o) {
if (o == null) {
return null;
}
if (o instanceof Number) {
return o;
}
if (o instanceof String) {
Double d = getDouble(o);
if (isNaNOrInfinite(d)) {
return o;
}
return d;
}
return o;
}
public static boolean getBoolean(Object o) {
if (o == null) {
return false;
}
if (o instanceof Boolean) {
return (Boolean) o;
}
if (o instanceof Number) {
return ((Number) o).doubleValue() != 0;
}
if (o instanceof Matrix) {
return ((Matrix) o).booleanValue();
}
if (o instanceof String) {
String s = ((String) o).toLowerCase();
if (s.equals("true")) {
return true;
} else if (s.equals("false")) {
return false;
} else {
try {
return Double.parseDouble(s) != 0.0;
} catch (Exception e) {
}
}
}
return false;
}
public static byte getByte(Object o) {
if (o == null) {
return 0;
}
if (o instanceof Byte) {
return (Byte) o;
}
if (o instanceof Number) {
return ((Number) o).byteValue();
}
if (o instanceof Matrix) {
return ((Matrix) o).byteValue();
}
if (o instanceof String) {
try {
return Byte.parseByte(((String) o));
} catch (Exception e) {
}
}
return 0;
}
public static BigInteger getBigInteger(Object o) {
if (o == null) {
return BigInteger.ZERO;
}
if (o instanceof BigInteger) {
return (BigInteger) o;
}
if (o instanceof Number) {
if (MathUtil.isNaNOrInfinite(o)) {
throw new IllegalArgumentException("NaN, Inf and -Inf not allowed for BigInteger");
} else {
return BigInteger.valueOf(((Number) o).longValue());
}
}
if (o instanceof Matrix) {
return ((Matrix) o).bigIntegerValue();
}
if (o instanceof String) {
return new BigInteger((String) o);
}
return BigInteger.ZERO;
}
public static BigDecimal getBigDecimal(Object o) {
if (o == null) {
return BigDecimal.ZERO;
}
if (o instanceof BigDecimal) {
return (BigDecimal) o;
}
if (o instanceof Number) {
double val = ((Number) o).doubleValue();
if (MathUtil.isNaNOrInfinite(val)) {
return null;
} else if (val == 0) {
return BigDecimal.ZERO;
} else if (val == 1) {
return BigDecimal.ONE;
} else if (val == 10) {
return BigDecimal.TEN;
} else {
return BigDecimal.valueOf(val);
}
}
if (o instanceof Matrix) {
return ((Matrix) o).bigDecimalValue();
}
if (o instanceof String) {
try {
return new BigDecimal((String) o);
} catch (Exception e) {
return BigDecimal.ZERO;
}
}
return BigDecimal.ZERO;
}
public static char getChar(Object o) {
if (o == null) {
return 0;
}
if (o instanceof Character) {
return (Character) o;
}
if (o instanceof Number) {
return (char) ((Number) o).byteValue();
}
if (o instanceof Matrix) {
return ((Matrix) o).charValue();
}
if (o instanceof String) {
try {
return (char) Byte.parseByte(((String) o));
} catch (Exception e) {
}
}
return 0;
}
public static float getFloat(Object o) {
if (o == null) {
return 0;
}
if (o instanceof Float) {
return (Float) o;
}
if (o instanceof Number) {
return ((Number) o).floatValue();
}
if (o instanceof Matrix) {
return ((Matrix) o).floatValue();
}
if (o instanceof String) {
try {
return Float.parseFloat(((String) o));
} catch (Exception e) {
}
}
return 0;
}
public static Object getObject(Object o) {
if (o == null) {
return null;
}
if (o instanceof Matrix) {
Matrix m = (Matrix) o;
if (m.getValueCount() == 1) {
return m.getAsObject(0, 0);
}
}
return o;
}
public static int getInt(Object o) {
if (o == null) {
return 0;
}
if (o instanceof Integer) {
return (Integer) o;
}
if (o instanceof Number) {
return ((Number) o).intValue();
}
if (o instanceof Matrix) {
return ((Matrix) o).intValue();
}
if (o instanceof String) {
try {
return Integer.parseInt(((String) o));
} catch (Exception e) {
}
}
return 0;
}
public static long getLong(Object o) {
if (o == null) {
return 0;
}
if (o instanceof Long) {
return (Long) o;
}
if (o instanceof Number) {
return ((Number) o).longValue();
}
if (o instanceof Matrix) {
return ((Matrix) o).longValue();
}
if (o instanceof String) {
try {
return Long.parseLong(((String) o));
} catch (Exception e) {
}
}
return 0;
}
public static short getShort(Object o) {
if (o == null) {
return 0;
}
if (o instanceof Short) {
return (Short) o;
}
if (o instanceof Number) {
return ((Number) o).shortValue();
}
if (o instanceof Matrix) {
return ((Matrix) o).shortValue();
}
if (o instanceof String) {
try {
return Short.parseShort(((String) o));
} catch (Exception e) {
}
}
return 0;
}
public static int[] toIntArray(long... coordinates) {
int[] result = new int[coordinates.length];
for (int i = coordinates.length; --i != -1;) {
result[i] = (int) coordinates[i];
}
return result;
}
public static long[] toLongArray(int... coordinates) {
long[] result = new long[coordinates.length];
for (int i = coordinates.length; --i != -1;) {
result[i] = coordinates[i];
}
return result;
}
public static boolean isNull(Object value) {
if (value == null) {
return true;
}
if (value instanceof Number) {
if (((Number) value).doubleValue() == 0.0) {
return true;
}
}
return false;
}
public static double norminv(double p, double mu, double sigma) {
if (sigma <= 0) {
return Double.NaN;
}
if (MathUtil.isNaNOrInfinite(p)) {
return Double.NaN;
}
if (p == 1) {
return Double.POSITIVE_INFINITY;
}
if (p == 0) {
return Double.NEGATIVE_INFINITY;
}
if (p < 0 || p > 1) {
return Double.NaN;
}
double r, val;
double p_ = p;
double q = p_ - 0.5;
if (Math.abs(q) <= .425) {
r = .180625 - q * q;
val = q
* (((((((r * 2509.0809287301226727 + 33430.575583588128105) * r + 67265.770927008700853)
* r + 45921.953931549871457)
* r + 13731.693765509461125)
* r + 1971.5909503065514427)
* r + 133.14166789178437745)
* r + 3.387132872796366608)
/ (((((((r * 5226.495278852854561 + 28729.085735721942674) * r + 39307.89580009271061)
* r + 21213.794301586595867)
* r + 5394.1960214247511077)
* r + 687.1870074920579083)
* r + 42.313330701600911252)
* r + 1.);
} else {
if (q > 0) {
r = 1 - p;
} else {
r = p_;
}
r = Math.sqrt(-Math.log(r));
if (r <= 5.) {
r += -1.6;
val = (((((((r * 7.7454501427834140764e-4 + 0.0227238449892691845833) * r + 0.24178072517745061177)
* r + 1.27045825245236838258)
* r + 3.64784832476320460504)
* r + 5.7694972214606914055)
* r + 4.6303378461565452959)
* r + 1.42343711074968357734)
/ (((((((r * 1.05075007164441684324e-9 + 5.475938084995344946e-4) * r + 0.0151986665636164571966)
* r + 0.14810397642748007459)
* r + 0.68976733498510000455)
* r + 1.6763848301838038494)
* r + 2.05319162663775882187)
* r + 1.0);
} else {
r += -5.;
val = (((((((r * 2.01033439929228813265e-7 + 2.71155556874348757815e-5) * r + 0.0012426609473880784386)
* r + 0.026532189526576123093)
* r + 0.29656057182850489123)
* r + 1.7848265399172913358)
* r + 5.4637849111641143699)
* r + 6.6579046435011037772)
/ (((((((r * 2.04426310338993978564e-15 + 1.4215117583164458887e-7) * r + 1.8463183175100546818e-5)
* r + 7.868691311456132591e-4)
* r + 0.0148753612908506148525)
* r + 0.13692988092273580531)
* r + 0.59983220655588793769)
* r + 1.0);
}
if (q < 0.0) {
val = -val;
}
}
return mu + sigma * val;
}
public static double f1Measure(double tp, double fp, double fn) {
double precision = precision(tp, fp);
double recall = recall(tp, fn);
return f1Measure(precision, recall);
}
public static final long factorial(int n) {
long r = 1;
for (int i = 2; i <= n; i++) {
r *= i;
}
return r;
}
public static final BigInteger factorialBig(int n) {
BigInteger r = BigInteger.ONE;
for (int i = 2; i <= n; i++) {
r = r.multiply(BigInteger.valueOf(i));
}
return r;
}
public static final long binomialCoefficient(int n, int k) {
if (k > n || k < 0) {
return 0;
} else {
return factorial(n) / factorial(k) / factorial(n - k);
}
}
public static final BigInteger binomialCoefficientBig(int n, int k) {
if (k > n || k < 0) {
return BigInteger.ZERO;
} else {
return factorialBig(n).divide(factorialBig(k)).divide(factorialBig(n - k));
}
}
public static final boolean greater(BigInteger i1, BigInteger i2) {
return i1.subtract(i2).signum() > 0;
}
public static final boolean smaller(BigInteger i1, BigInteger i2) {
return i1.subtract(i2).signum() < 0;
}
public static int max(int[] values) {
int max = -Integer.MAX_VALUE;
for (int i = values.length - 1; i != -1; i--) {
max = values[i] > max ? values[i] : max;
}
return max;
}
public static double max(double[] values) {
double max = -Double.MAX_VALUE;
for (int i = values.length - 1; i != -1; i--) {
max = values[i] > max ? values[i] : max;
}
return max;
}
public static int min(int[] values) {
int min = Integer.MAX_VALUE;
for (int i = values.length - 1; i != -1; i--) {
min = values[i] < min ? values[i] : min;
}
return min;
}
public static final BigDecimal plus(BigDecimal v1, BigDecimal v2) {
if (v1 != null && v2 != null) {
return v1.add(v2, UJMPSettings.getInstance().getMathContext());
} else {
return null;
}
}
public static final BigDecimal minus(BigDecimal v1, BigDecimal v2) {
if (v1 != null && v2 != null) {
return v1.subtract(v2, UJMPSettings.getInstance().getMathContext());
} else {
return null;
}
}
public static final BigDecimal times(BigDecimal v1, BigDecimal v2) {
if (v1 != null && v2 != null) {
return v1.multiply(v2, UJMPSettings.getInstance().getMathContext());
} else {
return null;
}
}
public static final BigDecimal divide(BigDecimal v1, BigDecimal v2) {
if (BigDecimal.ZERO.equals(v2)) {
return null;
} else if (v1 != null && v2 != null) {
return v1.divide(v2, UJMPSettings.getInstance().getMathContext());
} else {
return null;
}
}
public static boolean isGreater(BigDecimal v1, BigDecimal v2) {
return v1.compareTo(v2) > 0;
}
public static boolean isSmaller(BigDecimal v1, BigDecimal v2) {
return v1.compareTo(v2) < 0;
}
// Compute square root of large numbers using Heron's method
// adapted from http://www.merriampark.com/bigsqrt.htm
public static final BigDecimal sqrt(BigDecimal n) {
if (n.compareTo(BigDecimal.ZERO) <= 0) {
throw new IllegalArgumentException();
}
final BigDecimal TWO = new BigDecimal("2");
BigDecimal error;
BigDecimal lastGuess = BigDecimal.ZERO;
BigDecimal guess = BigDecimal.ONE.movePointRight(n.toBigInteger().toString().length() / 2);
int maxIterations = 50;
int iterations = 0;
boolean more = true;
while (more) {
lastGuess = guess;
guess = n.divide(guess, UJMPSettings.getInstance().getMathContext());
guess = guess.add(lastGuess);
guess = guess.divide(TWO, UJMPSettings.getInstance().getMathContext());
error = n.subtract(guess.multiply(guess));
if (++iterations >= maxIterations) {
more = false;
} else if (lastGuess.equals(guess)) {
more = error.abs().compareTo(BigDecimal.ONE) >= 0;
}
}
return guess;
}
/**
* from numerical recipes in c (p. 214)
*/
public static final double gammaln(double x) {
double ser = 1.00000000090015;
double y = x;
double tmp = x + 5.5;
tmp -= (x + 0.5) * Math.log(tmp);
for (int j = 0; j < 5; j++) {
ser += COFGAMMALN[j] / ++y;
}
return -tmp + Math.log(ser * 2.5066282751072975 / x);
}
public static final long pos2IndexRowMajor(long[] size, long[] pos) {
long sum = 0;
long prod = 1;
final int length = pos.length;
for (int k = length - 1; k >= 0; k--) {
sum += prod * pos[k];
prod *= size[k];
}
return sum;
}
public static final long pos2IndexColumnMajor(long[] size, long[] pos) {
long sum = 0;
long prod = 1;
final int length = pos.length;
for (int k = 0; k < length; k++) {
sum += prod * pos[k];
prod *= size[k];
}
return sum;
}
public static final long[] index2PosRowMajor(long[] size, long index) {
final long[] pos = new long[size.length];
long res = index;
for (int k = size.length; --k != -1;) {
pos[k] = res % size[k];
res /= size[k];
}
return pos;
}
public static final long[] index2PosColumnMajor(long[] size, long index) {
final int length = size.length;
final long[] pos = new long[length];
long res = index;
for (int k = 0; k < length; k++) {
pos[k] = res % size[k];
res /= size[k];
}
return pos;
}
public static final long totalCorrect(Matrix confusionMatrix) {
VerifyUtil.verifySquare(confusionMatrix);
return (long) confusionMatrix.trace();
}
public static final double accuracy(Matrix confusionMatrix) {
VerifyUtil.verifySquare(confusionMatrix);
return totalCorrect(confusionMatrix) / confusionMatrix.getValueSum();
}
public static double precisionMacro(Matrix confusionMatrix) {
VerifyUtil.verifySquare(confusionMatrix);
double sum = 0;
for (int catIndex = 0; catIndex < confusionMatrix.getRowCount(); catIndex++) {
sum += precision(confusionMatrix, catIndex);
}
return sum / confusionMatrix.getRowCount();
}
public static double recallMacro(Matrix confusionMatrix) {
VerifyUtil.verifySquare(confusionMatrix);
double sum = 0;
for (int catIndex = 0; catIndex < confusionMatrix.getRowCount(); catIndex++) {
sum += recall(confusionMatrix, catIndex);
}
return sum / confusionMatrix.getRowCount();
}
public static double f1MeasureMacro(Matrix confusionMatrix) {
VerifyUtil.verifySquare(confusionMatrix);
double sum = 0;
for (int catIndex = 0; catIndex < confusionMatrix.getRowCount(); catIndex++) {
sum += f1Measure(confusionMatrix, catIndex);
}
return sum / confusionMatrix.getRowCount();
}
public static double precision(Matrix confusionMatrix, long catIndex) {
VerifyUtil.verifySquare(confusionMatrix);
double tp = confusionMatrix.getAsDouble(catIndex, catIndex);
double fp = 0;
for (int c = 0; c < confusionMatrix.getRowCount(); c++) {
if (c == catIndex) {
continue;
}
fp += confusionMatrix.getAsDouble(catIndex, c);
}
return precision(tp, fp);
}
public static double recall(Matrix confusionMatrix, long catIndex) {
VerifyUtil.verifySquare(confusionMatrix);
double tp = confusionMatrix.getAsDouble(catIndex, catIndex);
double fn = 0;
for (int r = 0; r < confusionMatrix.getRowCount(); r++) {
if (r == catIndex) {
continue;
}
fn += confusionMatrix.getAsDouble(r, catIndex);
}
return recall(tp, fn);
}
public static double f1Measure(Matrix confusionMatrix, long catIndex) {
VerifyUtil.verifySquare(confusionMatrix);
return f1Measure(precision(confusionMatrix, catIndex), recall(confusionMatrix, catIndex));
}
public static double precisionMicro(Matrix confusionMatrix) {
double tp = 0;
double fp = 0;
for (int catIndex = 0; catIndex < confusionMatrix.getRowCount(); catIndex++) {
tp += confusionMatrix.getAsDouble(catIndex, catIndex);
for (int c = 0; c < confusionMatrix.getRowCount(); c++) {
if (c == catIndex) {
continue;
}
fp += confusionMatrix.getAsDouble(catIndex, c);
}
}
return precision(tp, fp);
}
public static double recallMicro(Matrix confusionMatrix) {
double tp = 0;
double fn = 0;
for (int catIndex = 0; catIndex < confusionMatrix.getRowCount(); catIndex++) {
tp += confusionMatrix.getAsDouble(catIndex, catIndex);
for (int r = 0; r < confusionMatrix.getRowCount(); r++) {
if (r == catIndex) {
continue;
}
fn += confusionMatrix.getAsDouble(r, catIndex);
}
}
return recall(tp, fn);
}
public static double f1MeasureMicro(Matrix confusionMatrix) {
double tp = 0;
double fn = 0;
double fp = 0;
for (int catIndex = 0; catIndex < confusionMatrix.getRowCount(); catIndex++) {
tp += confusionMatrix.getAsDouble(catIndex, catIndex);
for (int r = 0; r < confusionMatrix.getRowCount(); r++) {
if (r == catIndex) {
continue;
}
fn += confusionMatrix.getAsDouble(r, catIndex);
}
for (int c = 0; c < confusionMatrix.getRowCount(); c++) {
if (c == catIndex) {
continue;
}
fp += confusionMatrix.getAsDouble(catIndex, c);
}
}
return f1Measure(tp, fp, fn);
}
public static final int longToIntClip(final long value) {
final int intValue = (int) value;
if (value == intValue) {
return intValue;
} else if (value >= Integer.MAX_VALUE) {
return Integer.MAX_VALUE;
} else {
return Integer.MIN_VALUE;
}
}
public static final int longToInt(final long value) {
final int intValue = (int) value;
if (value == intValue) {
return intValue;
} else {
throw new IllegalArgumentException(
"long value too large, it cannot be converted to int");
}
}
public static boolean isDigit(char c) {
switch (c) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
return true;
default:
return false;
}
}
public static boolean isSign(char c) {
switch (c) {
case '-':
case '+':
return true;
default:
return false;
}
}
public static int hexToInt(String hex) {
return Integer.parseInt(hex, 16);
}
public static String intToHex(int i) {
return Integer.toHexString(i);
}
public static boolean isDiscrete(double number) {
return (int) number == number;
}
public static String guid() {
return UUID.randomUUID().toString();
}
}
Ads help maintain this website.