001 /* 002 * Copyright (C) 2008-2010 by Holger Arndt 003 * 004 * This file is part of the Universal Java Matrix Package (UJMP). 005 * See the NOTICE file distributed with this work for additional 006 * information regarding copyright ownership and licensing. 007 * 008 * UJMP is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU Lesser General Public License as 010 * published by the Free Software Foundation; either version 2 011 * of the License, or (at your option) any later version. 012 * 013 * UJMP is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU Lesser General Public License for more details. 017 * 018 * You should have received a copy of the GNU Lesser General Public 019 * License along with UJMP; if not, write to the 020 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 021 * Boston, MA 02110-1301 USA 022 */ 023 024 package org.ujmp.core.util; 025 026 import java.io.File; 027 import java.io.IOException; 028 import java.io.Serializable; 029 import java.math.BigDecimal; 030 import java.math.BigInteger; 031 import java.math.MathContext; 032 import java.security.MessageDigest; 033 import java.security.NoSuchAlgorithmException; 034 import java.text.DateFormat; 035 import java.util.ArrayList; 036 import java.util.Collection; 037 import java.util.Collections; 038 import java.util.Date; 039 import java.util.List; 040 import java.util.Locale; 041 import java.util.Random; 042 043 import org.ujmp.core.Matrix; 044 import org.ujmp.core.MatrixFactory; 045 import org.ujmp.core.util.io.IntelligentFileReader; 046 047 public abstract class MathUtil { 048 049 private static List<DateFormat> dateFormats = null; 050 051 private static final double ROOT2PI = Math.sqrt(2 * Math.PI); 052 053 private static final double LOG10 = Math.log(10.0); 054 055 private static final double LOG2 = Math.log(2.0); 056 057 private static final double COFGAMMALN[] = { 76.18009172947146, -86.50532032941677, 058 24.01409824083091, -1.231739572450155, 0.1208650973866179e-2, -0.5395239384953e-5 }; 059 060 private static long seed = System.nanoTime(); 061 062 private static Random random = new Random(); 063 064 static { 065 try { 066 random.setSeed(seed); 067 dateFormats = new ArrayList<DateFormat>(); 068 dateFormats.add(DateFormat.getDateInstance(DateFormat.SHORT, Locale.US)); 069 dateFormats.add(DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.US)); 070 dateFormats.add(DateFormat.getDateInstance(DateFormat.LONG, Locale.US)); 071 dateFormats.add(DateFormat.getDateInstance(DateFormat.SHORT, Locale.GERMAN)); 072 dateFormats.add(DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.GERMAN)); 073 dateFormats.add(DateFormat.getDateInstance(DateFormat.LONG, Locale.GERMAN)); 074 dateFormats.add(DateFormat.getTimeInstance(DateFormat.SHORT, Locale.US)); 075 dateFormats.add(DateFormat.getTimeInstance(DateFormat.MEDIUM, Locale.US)); 076 dateFormats.add(DateFormat.getTimeInstance(DateFormat.LONG, Locale.US)); 077 dateFormats.add(DateFormat.getTimeInstance(DateFormat.SHORT, Locale.GERMAN)); 078 dateFormats.add(DateFormat.getTimeInstance(DateFormat.MEDIUM, Locale.GERMAN)); 079 dateFormats.add(DateFormat.getTimeInstance(DateFormat.LONG, Locale.GERMAN)); 080 } catch (Throwable t) { 081 } 082 } 083 084 public static MathContext getDefaultMathContext() { 085 return UJMPSettings.getDefaultMathContext(); 086 } 087 088 public static String md5(String text) throws NoSuchAlgorithmException { 089 return md5(text.getBytes()); 090 } 091 092 public static String md5(byte[] data) throws NoSuchAlgorithmException { 093 MessageDigest mdAlgorithm; 094 StringBuilder hexString = new StringBuilder(); 095 096 mdAlgorithm = MessageDigest.getInstance("MD5"); 097 mdAlgorithm.update(data); 098 byte[] digest = mdAlgorithm.digest(); 099 100 for (int i = 0; i < digest.length; i++) { 101 String text = Integer.toHexString(0xFF & digest[i]); 102 103 if (text.length() < 2) { 104 text = "0" + text; 105 } 106 107 hexString.append(text); 108 } 109 hexString.trimToSize(); 110 return hexString.toString(); 111 } 112 113 public static String md5(File file) throws NoSuchAlgorithmException { 114 return md5(IntelligentFileReader.readBytes(file)); 115 } 116 117 public static String md5(Serializable o) throws NoSuchAlgorithmException, IOException { 118 return md5(SerializationUtil.serialize(o)); 119 } 120 121 public static final Random getRandom() { 122 return random; 123 } 124 125 public static final boolean xor(boolean b1, boolean b2) { 126 if (b1 == false && b2 == false) { 127 return false; 128 } else if (b1 == false && b2 == true) { 129 return true; 130 } else if (b1 == true && b2 == false) { 131 return true; 132 } else { 133 return false; 134 } 135 } 136 137 public static double[] logToProbs(double[] logs) { 138 double[] probs = new double[logs.length]; 139 double sum = 0.0; 140 for (int i = 0; i < probs.length; i++) { 141 probs[i] = Math.exp(logs[i]); 142 sum += probs[i]; 143 } 144 for (int i = 0; i < probs.length; i++) { 145 probs[i] = probs[i] / sum; 146 } 147 return probs; 148 } 149 150 public static final long getSeed() { 151 return seed; 152 } 153 154 public static final double round(double value, int decimals) { 155 return Math.round(value * Math.pow(10, decimals)) / Math.pow(10, decimals); 156 157 } 158 159 public static void setSeed(long seed) { 160 MathUtil.seed = seed; 161 random.setSeed(seed); 162 } 163 164 public static final double log2(final double d) { 165 return Math.log(d) / LOG2; 166 } 167 168 public static final double log10(final double d) { 169 return Math.log(d) / LOG10; 170 } 171 172 public static int hash(int h) { 173 // This function ensures that hashCodes that differ only by 174 // constant multiples at each bit position have a bounded 175 // number of collisions (approximately 8 at default load factor). 176 h ^= (h >>> 20) ^ (h >>> 12); 177 return h ^ (h >>> 7) ^ (h >>> 4); 178 } 179 180 public static final double gauss(double mean, double sigma, double x) { 181 return Math.exp(-0.5 * Math.pow((x - mean) / sigma, 2.0)) / (sigma * ROOT2PI); 182 } 183 184 public static final double artanh(double x) { 185 return 0.5 * Math.log((1 + x) / (1 - x)); 186 } 187 188 public static final double nextGaussian(double mean, double sigma) { 189 return sigma <= 0.0 ? 0.0 : sigma * random.nextGaussian() + mean; 190 } 191 192 public static final double nextUniform(double min, double max) { 193 if (min == max) { 194 max += Double.MIN_VALUE; 195 } 196 double r = random.nextDouble(); 197 while (r <= 0.0) { 198 r = random.nextDouble(); 199 } 200 201 return min + r * (max - min); 202 } 203 204 /** 205 * Returns a random value in the desired interval 206 * 207 * @param min 208 * minimum value (inclusive) 209 * @param max 210 * maximum value (inclusive) 211 * @return a random value 212 */ 213 public static final int nextInteger(int min, int max) { 214 if (min == max) { 215 return min; 216 } 217 double r = random.nextDouble(); 218 return (int) ((r * max) + ((1.0 - r) * min) + r); 219 } 220 221 public static boolean isEventHappening(double probability) { 222 return nextUniform(0.0, 1.0) < probability; 223 } 224 225 public static boolean nextBoolean() { 226 return nextGaussian(0.0, 1.0) > 0; 227 } 228 229 public static double nextDouble() { 230 return random.nextDouble(); 231 } 232 233 public static final double ignoreNaN(final double v) { 234 return Double.isNaN(v) || (v == Double.POSITIVE_INFINITY) 235 || (v == Double.NEGATIVE_INFINITY) ? 0.0 : v; 236 } 237 238 public static final boolean isNaNOrInfinite(final double v) { 239 return Double.isNaN(v) || (v == Double.POSITIVE_INFINITY) 240 || (v == Double.NEGATIVE_INFINITY); 241 } 242 243 public static final boolean isNaNOrInfinite(final Object o) { 244 return Double.valueOf(Double.NaN).equals(o) 245 || Double.valueOf(Double.POSITIVE_INFINITY).equals(o) 246 || Double.valueOf(Double.NEGATIVE_INFINITY).equals(o); 247 } 248 249 public static final Matrix getMatrix(Object o) { 250 if (o == null) { 251 return MatrixFactory.EMPTYMATRIX; 252 } 253 if (o instanceof Matrix) { 254 Matrix m = (Matrix) o; 255 if (m.isScalar() && m.getAsObject(0, 0) instanceof Matrix) { 256 return getMatrix(m.getAsObject(0, 0)); 257 } else { 258 return m; 259 } 260 } else { 261 return MatrixFactory.linkToValue(o); 262 } 263 } 264 265 public static final Date getDate(Object o) { 266 if (o == null) { 267 return null; 268 } 269 if (o instanceof Date) { 270 return (Date) o; 271 } 272 if (o instanceof Long) { 273 return new Date((Long) o); 274 } 275 if (o instanceof String) { 276 for (DateFormat df : dateFormats) { 277 try { 278 return df.parse((String) o); 279 } catch (Exception e) { 280 } 281 } 282 } 283 return new Date(getLong(o)); 284 } 285 286 public static final double getDouble(Object o) { 287 if (o == null) { 288 return 0.0; 289 } else if (o instanceof Double) { 290 return (Double) o; 291 } else if (o instanceof Date) { 292 return ((Date) o).getTime(); 293 } else if (o instanceof Matrix) { 294 return ((Matrix) o).doubleValue(); 295 } else { 296 if ("true".equalsIgnoreCase(o.toString())) { 297 return 1.0; 298 } 299 if ("false".equalsIgnoreCase(o.toString())) { 300 return 0.0; 301 } 302 try { 303 return Double.parseDouble(o.toString()); 304 } catch (Exception e) { 305 } 306 } 307 return Double.NaN; 308 } 309 310 /** sqrt(a^2 + b^2) without under/overflow. **/ 311 public static final double hypot(double a, double b) { 312 double r; 313 if (Math.abs(a) > Math.abs(b)) { 314 r = b / a; 315 r = Math.abs(a) * Math.sqrt(1.0 + r * r); 316 } else if (b != 0) { 317 r = a / b; 318 r = Math.abs(b) * Math.sqrt(1.0 + r * r); 319 } else { 320 r = 0.0; 321 } 322 return r; 323 } 324 325 public static long[] collectionToLong(Collection<? extends Number> numbers) { 326 long[] ret = new long[numbers.size()]; 327 int i = 0; 328 for (Number n : numbers) { 329 ret[i++] = n.longValue(); 330 } 331 return ret; 332 } 333 334 public static double[] collectionToDouble(Collection<? extends Number> numbers) { 335 double[] ret = new double[numbers.size()]; 336 int i = 0; 337 for (Number n : numbers) { 338 ret[i++] = n.doubleValue(); 339 } 340 return ret; 341 } 342 343 public static int[] collectionToInt(Collection<? extends Number> numbers) { 344 int[] ret = new int[numbers.size()]; 345 int i = 0; 346 for (Number n : numbers) { 347 ret[i++] = n.intValue(); 348 } 349 return ret; 350 } 351 352 public static List<Long> toLongList(long[] numbers) { 353 List<Long> ret = new ArrayList<Long>(numbers.length); 354 for (int i = 0; i < numbers.length; i++) { 355 ret.add(numbers[i]); 356 } 357 return ret; 358 } 359 360 public static List<Long> toLongList(int[] numbers) { 361 List<Long> ret = new ArrayList<Long>(numbers.length); 362 for (int i = 0; i < numbers.length; i++) { 363 ret.add((long) numbers[i]); 364 } 365 return ret; 366 } 367 368 public static List<Double> toDoubleList(double[] numbers) { 369 List<Double> ret = new ArrayList<Double>(numbers.length); 370 for (int i = 0; i < numbers.length; i++) { 371 ret.add(numbers[i]); 372 } 373 return ret; 374 } 375 376 public static List<Double> toDoubleList(int[] numbers) { 377 List<Double> ret = new ArrayList<Double>(numbers.length); 378 for (int i = 0; i < numbers.length; i++) { 379 ret.add((double) numbers[i]); 380 } 381 return ret; 382 } 383 384 public static List<Double> toDoubleList(long[] numbers) { 385 List<Double> ret = new ArrayList<Double>(numbers.length); 386 for (int i = 0; i < numbers.length; i++) { 387 ret.add((double) numbers[i]); 388 } 389 return ret; 390 } 391 392 public static double[] toDoubleArray(int... intArray) { 393 int nmb = intArray.length; 394 double[] ret = new double[nmb]; 395 for (int i = 0; i < nmb; i++) 396 ret[i] = intArray[i]; 397 return ret; 398 } 399 400 public static double[][] toDoubleArray(int[]... intArray) { 401 int rows = intArray.length; 402 if (rows <= 0) 403 return new double[0][0]; 404 int cols = intArray[0].length; 405 double[][] ret = new double[rows][cols]; 406 for (int i = rows - 1; i >= 0; i--) { 407 for (int j = cols - 1; j >= 0; j--) { 408 ret[i][j] = intArray[i][j]; 409 } 410 } 411 return ret; 412 } 413 414 public static List<Long> sequenceListLong(long start, long end) { 415 return sequenceListLong(start, end, 1); 416 } 417 418 public static List<Long> sequenceListLong(long start, long end, long stepsize) { 419 List<Long> list = new ArrayList<Long>(); 420 421 if (start < end) { 422 stepsize = Math.abs(stepsize); 423 for (long l = start; l <= end; l += stepsize) { 424 list.add(l); 425 } 426 } else { 427 stepsize = -Math.abs(stepsize); 428 for (long l = start; l >= end; l += stepsize) { 429 list.add(l); 430 } 431 } 432 return list; 433 } 434 435 public static List<Double> sequenceListDouble(double start, double end) { 436 return sequenceListDouble(start, end, 1); 437 } 438 439 public static List<Double> sequenceListDouble(double start, double end, double stepsize) { 440 List<Double> list = new ArrayList<Double>(); 441 442 if (start < end) { 443 stepsize = Math.abs(stepsize); 444 for (double l = start; l <= end; l += stepsize) { 445 list.add(l); 446 } 447 } else { 448 stepsize = -Math.abs(stepsize); 449 for (double l = start; l >= end; l += stepsize) { 450 list.add(l); 451 } 452 } 453 return list; 454 } 455 456 public static List<Integer> sequenceListInt(int start, int end) { 457 List<Integer> list = new ArrayList<Integer>(); 458 459 if (start < end) { 460 for (int l = start; l <= end; l++) { 461 list.add(l); 462 } 463 } else { 464 for (int l = start; l >= end; l--) { 465 list.add(l); 466 } 467 } 468 return list; 469 } 470 471 public static long[] sequenceLong(long start, long end) { 472 return collectionToLong(sequenceListLong(start, end)); 473 } 474 475 public static long[] sequenceLong(long start, long end, long stepsize) { 476 return collectionToLong(sequenceListLong(start, end, stepsize)); 477 } 478 479 public static double[] sequenceDouble(double start, double end) { 480 return collectionToDouble(sequenceListDouble(start, end)); 481 } 482 483 public static double[] sequenceDouble(double start, double end, double stepsize) { 484 return collectionToDouble(sequenceListDouble(start, end, stepsize)); 485 } 486 487 public static int[] sequenceInt(int start, int end) { 488 return collectionToInt(sequenceListInt(start, end)); 489 } 490 491 public static List<Long> randPerm(long start, long end) { 492 List<Long> list = sequenceListLong(start, end); 493 Collections.shuffle(list); 494 return list; 495 } 496 497 public static boolean equals(Object o1, Object o2) { 498 if ((o1 instanceof Number) || (o2 instanceof Number)) { 499 return getDouble(o1) == getDouble(o2); 500 } else if ((o1 instanceof String) || (o2 instanceof String)) { 501 return UJMPFormat.getSingleLineInstance().format(o1).equals( 502 UJMPFormat.getSingleLineInstance().format(o2)); 503 } else if ((o1 instanceof Boolean) || (o2 instanceof Boolean)) { 504 return ((Boolean) o1).equals(o2); 505 } else { 506 return false; 507 } 508 } 509 510 public static double sensitivity(double tp, double fn) { 511 double r = tp / (tp + fn); 512 return MathUtil.isNaNOrInfinite(r) ? 0.0 : r; 513 } 514 515 public static double specificity(double tn, double fp) { 516 double r = tn / (tn + fp); 517 return MathUtil.isNaNOrInfinite(r) ? 0.0 : r; 518 } 519 520 public static double positivePredictiveValue(double tp, double fp) { 521 double r = tp / (tp + fp); 522 return MathUtil.isNaNOrInfinite(r) ? 0.0 : r; 523 } 524 525 public static double negativePredictiveValue(double tn, double fn) { 526 double r = tn / (tn + fn); 527 return MathUtil.isNaNOrInfinite(r) ? 0.0 : r; 528 } 529 530 public static double falsePositiveRate(double fp, double tn) { 531 double r = fp / (fp + tn); 532 return MathUtil.isNaNOrInfinite(r) ? 0.0 : r; 533 } 534 535 public static double falseNegativeRate(double fn, double tp) { 536 double r = fn / (fn + tp); 537 return MathUtil.isNaNOrInfinite(r) ? 0.0 : r; 538 } 539 540 public static double recall(double tp, double fn) { 541 double r = tp / (tp + fn); 542 return MathUtil.isNaNOrInfinite(r) ? 0.0 : r; 543 } 544 545 public static double precision(double tp, double fp) { 546 double r = tp / (tp + fp); 547 return MathUtil.isNaNOrInfinite(r) ? 0.0 : r; 548 } 549 550 public static double fallout(double tn, double fp) { 551 double r = tn / (fp + tn); 552 return MathUtil.isNaNOrInfinite(r) ? 0.0 : r; 553 } 554 555 public static double trueNegativeRate(double tn, double fp) { 556 double r = tn / (fp + tn); 557 return MathUtil.isNaNOrInfinite(r) ? 0.0 : r; 558 } 559 560 public static double f1Measure(double precision, double recall) { 561 double r = (2.0 * precision * recall) / (precision + recall); 562 return MathUtil.isNaNOrInfinite(r) ? 0.0 : r; 563 } 564 565 public static double fBetaMeasure(double beta, double precision, double recall) { 566 double r = ((1 + beta * beta) * precision * recall) / (beta * beta * precision + recall); 567 return MathUtil.isNaNOrInfinite(r) ? 0.0 : r; 568 } 569 570 public static Object getPreferredObject(Object o) { 571 if (o == null) { 572 return null; 573 } 574 if (o instanceof Number) { 575 return o; 576 } 577 if (o instanceof String) { 578 Double d = getDouble(o); 579 if (isNaNOrInfinite(d)) { 580 return o; 581 } 582 return d; 583 } 584 return o; 585 } 586 587 public static boolean getBoolean(Object o) { 588 if (o == null) { 589 return false; 590 } 591 if (o instanceof Boolean) { 592 return (Boolean) o; 593 } 594 if (o instanceof Number) { 595 return ((Number) o).doubleValue() != 0; 596 } 597 if (o instanceof Matrix) { 598 return ((Matrix) o).booleanValue(); 599 } 600 if (o instanceof String) { 601 try { 602 return Boolean.parseBoolean(((String) o)); 603 } catch (Exception e) { 604 } 605 } 606 return false; 607 } 608 609 public static byte getByte(Object o) { 610 if (o == null) { 611 return 0; 612 } 613 if (o instanceof Byte) { 614 return (Byte) o; 615 } 616 if (o instanceof Number) { 617 return ((Number) o).byteValue(); 618 } 619 if (o instanceof Matrix) { 620 return ((Matrix) o).byteValue(); 621 } 622 if (o instanceof String) { 623 try { 624 return Byte.parseByte(((String) o)); 625 } catch (Exception e) { 626 } 627 } 628 return 0; 629 } 630 631 public static BigInteger getBigInteger(Object o) { 632 if (o == null) { 633 return BigInteger.ZERO; 634 } 635 if (o instanceof BigInteger) { 636 return (BigInteger) o; 637 } 638 if (o instanceof Number) { 639 if (MathUtil.isNaNOrInfinite(o)) { 640 throw new IllegalArgumentException("NaN, Inf and -Inf not allowed for BigInteger"); 641 } else { 642 return BigInteger.valueOf(((Number) o).longValue()); 643 } 644 } 645 if (o instanceof Matrix) { 646 return ((Matrix) o).bigIntegerValue(); 647 } 648 if (o instanceof String) { 649 return new BigInteger((String) o); 650 } 651 return BigInteger.ZERO; 652 } 653 654 public static BigDecimal getBigDecimal(Object o) { 655 if (o == null) { 656 return BigDecimal.ZERO; 657 } 658 if (o instanceof BigDecimal) { 659 return (BigDecimal) o; 660 } 661 if (o instanceof Number) { 662 double val = ((Number) o).doubleValue(); 663 if (MathUtil.isNaNOrInfinite(val)) { 664 return null; 665 } else if (val == 0) { 666 return BigDecimal.ZERO; 667 } else if (val == 1) { 668 return BigDecimal.ONE; 669 } else if (val == 10) { 670 return BigDecimal.TEN; 671 } else { 672 return BigDecimal.valueOf(val); 673 } 674 } 675 if (o instanceof Matrix) { 676 return ((Matrix) o).bigDecimalValue(); 677 } 678 if (o instanceof String) { 679 try { 680 return new BigDecimal((String) o); 681 } catch (Exception e) { 682 return BigDecimal.ZERO; 683 } 684 } 685 return BigDecimal.ZERO; 686 } 687 688 public static char getChar(Object o) { 689 if (o == null) { 690 return 0; 691 } 692 if (o instanceof Character) { 693 return (Character) o; 694 } 695 if (o instanceof Number) { 696 return (char) ((Number) o).byteValue(); 697 } 698 if (o instanceof Matrix) { 699 return ((Matrix) o).charValue(); 700 } 701 if (o instanceof String) { 702 try { 703 return (char) Byte.parseByte(((String) o)); 704 } catch (Exception e) { 705 } 706 } 707 return 0; 708 } 709 710 public static float getFloat(Object o) { 711 if (o == null) { 712 return 0; 713 } 714 if (o instanceof Float) { 715 return (Float) o; 716 } 717 if (o instanceof Number) { 718 return ((Number) o).floatValue(); 719 } 720 if (o instanceof Matrix) { 721 return ((Matrix) o).floatValue(); 722 } 723 if (o instanceof String) { 724 try { 725 return Float.parseFloat(((String) o)); 726 } catch (Exception e) { 727 } 728 } 729 return 0; 730 } 731 732 public static Object getObject(Object o) { 733 if (o == null) { 734 return null; 735 } 736 if (o instanceof Matrix) { 737 Matrix m = (Matrix) o; 738 if (m.getValueCount() == 1) { 739 return m.getAsObject(0, 0); 740 } 741 } 742 return o; 743 } 744 745 public static int getInt(Object o) { 746 if (o == null) { 747 return 0; 748 } 749 if (o instanceof Integer) { 750 return (Integer) o; 751 } 752 if (o instanceof Number) { 753 return ((Number) o).intValue(); 754 } 755 if (o instanceof Matrix) { 756 return ((Matrix) o).intValue(); 757 } 758 if (o instanceof String) { 759 try { 760 return Integer.parseInt(((String) o)); 761 } catch (Exception e) { 762 } 763 } 764 return 0; 765 } 766 767 public static long getLong(Object o) { 768 if (o == null) { 769 return 0; 770 } 771 if (o instanceof Long) { 772 return (Long) o; 773 } 774 if (o instanceof Number) { 775 return ((Number) o).longValue(); 776 } 777 if (o instanceof Matrix) { 778 return ((Matrix) o).longValue(); 779 } 780 if (o instanceof String) { 781 try { 782 return Long.parseLong(((String) o)); 783 } catch (Exception e) { 784 } 785 } 786 return 0; 787 } 788 789 public static short getShort(Object o) { 790 if (o == null) { 791 return 0; 792 } 793 if (o instanceof Short) { 794 return (Short) o; 795 } 796 if (o instanceof Number) { 797 return ((Number) o).shortValue(); 798 } 799 if (o instanceof Matrix) { 800 return ((Matrix) o).shortValue(); 801 } 802 if (o instanceof String) { 803 try { 804 return Short.parseShort(((String) o)); 805 } catch (Exception e) { 806 } 807 } 808 return 0; 809 } 810 811 public static int[] toIntArray(long... coordinates) { 812 int[] result = new int[coordinates.length]; 813 for (int i = coordinates.length; --i != -1;) { 814 result[i] = (int) coordinates[i]; 815 } 816 return result; 817 } 818 819 public static long[] toLongArray(int... coordinates) { 820 long[] result = new long[coordinates.length]; 821 for (int i = coordinates.length; --i != -1;) { 822 result[i] = coordinates[i]; 823 } 824 return result; 825 } 826 827 public static boolean isNull(Object value) { 828 if (value == null) { 829 return true; 830 } 831 if (value instanceof Number) { 832 if (((Number) value).doubleValue() == 0.0) { 833 return true; 834 } 835 } 836 return false; 837 } 838 839 public static double norminv(double p, double mu, double sigma) { 840 if (sigma <= 0) { 841 return Double.NaN; 842 } 843 844 if (MathUtil.isNaNOrInfinite(p)) { 845 return Double.NaN; 846 } 847 848 if (p == 1) { 849 return Double.POSITIVE_INFINITY; 850 } 851 852 if (p == 0) { 853 return Double.NEGATIVE_INFINITY; 854 } 855 856 if (p < 0 || p > 1) { 857 return Double.NaN; 858 } 859 860 double r, val; 861 double p_ = p; 862 double q = p_ - 0.5; 863 864 if (Math.abs(q) <= .425) { 865 r = .180625 - q * q; 866 val = q 867 * (((((((r * 2509.0809287301226727 + 33430.575583588128105) * r + 67265.770927008700853) 868 * r + 45921.953931549871457) 869 * r + 13731.693765509461125) 870 * r + 1971.5909503065514427) 871 * r + 133.14166789178437745) 872 * r + 3.387132872796366608) 873 / (((((((r * 5226.495278852854561 + 28729.085735721942674) * r + 39307.89580009271061) 874 * r + 21213.794301586595867) 875 * r + 5394.1960214247511077) 876 * r + 687.1870074920579083) 877 * r + 42.313330701600911252) 878 * r + 1.); 879 } else { 880 if (q > 0) { 881 r = 1 - p; 882 } else { 883 r = p_; 884 } 885 886 r = Math.sqrt(-Math.log(r)); 887 888 if (r <= 5.) { 889 r += -1.6; 890 val = (((((((r * 7.7454501427834140764e-4 + 0.0227238449892691845833) * r + 0.24178072517745061177) 891 * r + 1.27045825245236838258) 892 * r + 3.64784832476320460504) 893 * r + 5.7694972214606914055) 894 * r + 4.6303378461565452959) 895 * r + 1.42343711074968357734) 896 / (((((((r * 1.05075007164441684324e-9 + 5.475938084995344946e-4) * r + 0.0151986665636164571966) 897 * r + 0.14810397642748007459) 898 * r + 0.68976733498510000455) 899 * r + 1.6763848301838038494) 900 * r + 2.05319162663775882187) 901 * r + 1.0); 902 } else { 903 r += -5.; 904 val = (((((((r * 2.01033439929228813265e-7 + 2.71155556874348757815e-5) * r + 0.0012426609473880784386) 905 * r + 0.026532189526576123093) 906 * r + 0.29656057182850489123) 907 * r + 1.7848265399172913358) 908 * r + 5.4637849111641143699) 909 * r + 6.6579046435011037772) 910 / (((((((r * 2.04426310338993978564e-15 + 1.4215117583164458887e-7) * r + 1.8463183175100546818e-5) 911 * r + 7.868691311456132591e-4) 912 * r + 0.0148753612908506148525) 913 * r + 0.13692988092273580531) 914 * r + 0.59983220655588793769) 915 * r + 1.0); 916 } 917 918 if (q < 0.0) { 919 val = -val; 920 } 921 922 } 923 return mu + sigma * val; 924 } 925 926 public static double f1measure(double tp, double tn, double fp, double fn) { 927 double precision = precision(tp, fp); 928 double recall = recall(tp, fn); 929 return f1Measure(precision, recall); 930 } 931 932 public static final long factorial(int n) { 933 long r = 1; 934 for (int i = 2; i <= n; i++) { 935 r *= i; 936 } 937 return r; 938 } 939 940 public static final BigInteger factorialBig(int n) { 941 BigInteger r = BigInteger.ONE; 942 for (int i = 2; i <= n; i++) { 943 r = r.multiply(BigInteger.valueOf(i)); 944 } 945 return r; 946 } 947 948 public static final long binomialCoefficient(int n, int k) { 949 if (k > n || k < 0) { 950 return 0; 951 } else { 952 return factorial(n) / factorial(k) / factorial(n - k); 953 } 954 } 955 956 public static final BigInteger binomialCoefficientBig(int n, int k) { 957 if (k > n || k < 0) { 958 return BigInteger.ZERO; 959 } else { 960 return factorialBig(n).divide(factorialBig(k)).divide(factorialBig(n - k)); 961 } 962 } 963 964 public static final boolean greater(BigInteger i1, BigInteger i2) { 965 return i1.subtract(i2).signum() > 0; 966 } 967 968 public static final boolean smaller(BigInteger i1, BigInteger i2) { 969 return i1.subtract(i2).signum() < 0; 970 } 971 972 public static int max(int[] values) { 973 int max = -Integer.MAX_VALUE; 974 for (int i = values.length - 1; i != -1; i--) { 975 max = values[i] > max ? values[i] : max; 976 } 977 return max; 978 } 979 980 public static int min(int[] values) { 981 int min = Integer.MAX_VALUE; 982 for (int i = values.length - 1; i != -1; i--) { 983 min = values[i] < min ? values[i] : min; 984 } 985 return min; 986 } 987 988 public static final BigDecimal plus(BigDecimal v1, BigDecimal v2) { 989 if (v1 != null && v2 != null) { 990 return v1.add(v2, getDefaultMathContext()); 991 } else { 992 return null; 993 } 994 } 995 996 public static final BigDecimal minus(BigDecimal v1, BigDecimal v2) { 997 if (v1 != null && v2 != null) { 998 return v1.subtract(v2, getDefaultMathContext()); 999 } else { 1000 return null; 1001 } 1002 } 1003 1004 public static final BigDecimal times(BigDecimal v1, BigDecimal v2) { 1005 if (v1 != null && v2 != null) { 1006 return v1.multiply(v2, getDefaultMathContext()); 1007 } else { 1008 return null; 1009 } 1010 } 1011 1012 public static final BigDecimal divide(BigDecimal v1, BigDecimal v2) { 1013 if (BigDecimal.ZERO.equals(v2)) { 1014 return null; 1015 } else if (v1 != null && v2 != null) { 1016 return v1.divide(v2, getDefaultMathContext()); 1017 } else { 1018 return null; 1019 } 1020 } 1021 1022 public static boolean isGreater(BigDecimal v1, BigDecimal v2) { 1023 return v1.compareTo(v2) > 0; 1024 } 1025 1026 public static boolean isSmaller(BigDecimal v1, BigDecimal v2) { 1027 return v1.compareTo(v2) < 0; 1028 } 1029 1030 public static boolean isEqual(BigDecimal v1, BigDecimal v2) { 1031 return v1.compareTo(v2) == 0; 1032 } 1033 1034 // Compute square root of large numbers using Heron's method 1035 // adapted from http://www.merriampark.com/bigsqrt.htm 1036 public static final BigDecimal sqrt(BigDecimal n) { 1037 if (n.compareTo(BigDecimal.ZERO) <= 0) { 1038 throw new IllegalArgumentException(); 1039 } 1040 1041 final BigDecimal TWO = new BigDecimal("2"); 1042 BigDecimal error; 1043 BigDecimal lastGuess = BigDecimal.ZERO; 1044 BigDecimal guess = BigDecimal.ONE.movePointRight(n.toBigInteger().toString().length() / 2); 1045 int maxIterations = 50; 1046 int iterations = 0; 1047 boolean more = true; 1048 while (more) { 1049 lastGuess = guess; 1050 guess = n.divide(guess, UJMPSettings.getDefaultMathContext()); 1051 guess = guess.add(lastGuess); 1052 guess = guess.divide(TWO, UJMPSettings.getDefaultMathContext()); 1053 error = n.subtract(guess.multiply(guess)); 1054 if (++iterations >= maxIterations) { 1055 more = false; 1056 } else if (lastGuess.equals(guess)) { 1057 more = error.abs().compareTo(BigDecimal.ONE) >= 0; 1058 } 1059 } 1060 return guess; 1061 } 1062 1063 /** 1064 * from numerical recipes in c (p. 214) 1065 */ 1066 public static final double gammaln(double x) { 1067 double ser = 1.00000000090015; 1068 double y = x; 1069 double tmp = x + 5.5; 1070 tmp -= (x + 0.5) * Math.log(tmp); 1071 for (int j = 0; j < +5; j++) { 1072 ser += COFGAMMALN[j] / ++y; 1073 } 1074 return -tmp + Math.log(ser * 2.5066282751072975 / x); 1075 } 1076 1077 public static final long pos2IndexRowMajor(long[] size, long[] pos) { 1078 long sum = 0; 1079 long prod = 1; 1080 final int length = pos.length; 1081 for (int k = length - 1; k >= 0; k--) { 1082 sum += prod * pos[k]; 1083 prod *= size[k]; 1084 } 1085 return sum; 1086 } 1087 1088 public static final long pos2IndexColumnMajor(long[] size, long[] pos) { 1089 long sum = 0; 1090 long prod = 1; 1091 final int length = pos.length; 1092 for (int k = 0; k < length; k++) { 1093 sum += prod * pos[k]; 1094 prod *= size[k]; 1095 } 1096 return sum; 1097 } 1098 1099 public static final long[] index2PosRowMajor(long[] size, long index) { 1100 final long[] pos = new long[size.length]; 1101 long res = index; 1102 for (int k = size.length; --k != -1;) { 1103 pos[k] = res % size[k]; 1104 res /= size[k]; 1105 } 1106 return pos; 1107 } 1108 1109 public static final long[] index2PosColumnMajor(long[] size, long index) { 1110 final int length = size.length; 1111 final long[] pos = new long[length]; 1112 long res = index; 1113 for (int k = 0; k < length; k++) { 1114 pos[k] = res % size[k]; 1115 res /= size[k]; 1116 } 1117 return pos; 1118 } 1119 1120 }