001: /*
002: * This program is free software; you can redistribute it and/or modify
003: * it under the terms of the GNU General Public License as published by
004: * the Free Software Foundation; either version 2 of the License, or
005: * (at your option) any later version.
006: *
007: * This program is distributed in the hope that it will be useful,
008: * but WITHOUT ANY WARRANTY; without even the implied warranty of
009: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
010: * GNU General Public License for more details.
011: *
012: * You should have received a copy of the GNU General Public License
013: * along with this program; if not, write to the Free Software
014: * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
015: */
016:
017: /*
018: * SpecialFunctions.java
019: * Copyright (C) 1999 University of Waikato, Hamilton, New Zealand
020: *
021: */
022:
023: package weka.core;
024:
025: import java.lang.Math;
026:
027: /**
028: * Class implementing some mathematical functions.
029: *
030: * @author Eibe Frank (eibe@cs.waikato.ac.nz)
031: * @version $Revision: 1.7 $
032: */
033: public final class SpecialFunctions {
034:
035: /** Some constants */
036: private static double log2 = Math.log(2);
037:
038: /**
039: * Returns natural logarithm of factorial using gamma function.
040: *
041: * @param x the value
042: * @return natural logarithm of factorial
043: */
044: public static double lnFactorial(double x) {
045:
046: return Statistics.lnGamma(x + 1);
047: }
048:
049: /**
050: * Returns base 2 logarithm of binomial coefficient using gamma function.
051: *
052: * @param a upper part of binomial coefficient
053: * @param b lower part
054: * @return the base 2 logarithm of the binominal coefficient a over b
055: */
056: public static double log2Binomial(double a, double b) {
057:
058: if (Utils.gr(b, a)) {
059: throw new ArithmeticException(
060: "Can't compute binomial coefficient.");
061: }
062: return (lnFactorial(a) - lnFactorial(b) - lnFactorial(a - b))
063: / log2;
064: }
065:
066: /**
067: * Returns base 2 logarithm of multinomial using gamma function.
068: *
069: * @param a upper part of multinomial coefficient
070: * @param bs lower part
071: * @return multinomial coefficient of a over the bs
072: */
073: public static double log2Multinomial(double a, double[] bs) {
074:
075: double sum = 0;
076: int i;
077:
078: for (i = 0; i < bs.length; i++) {
079: if (Utils.gr(bs[i], a)) {
080: throw new ArithmeticException(
081: "Can't compute multinomial coefficient.");
082: } else {
083: sum = sum + lnFactorial(bs[i]);
084: }
085: }
086: return (lnFactorial(a) - sum) / log2;
087: }
088:
089: /**
090: * Main method for testing this class.
091: */
092: public static void main(String[] ops) {
093:
094: double[] doubles = { 1, 2, 3 };
095:
096: System.out.println("6!: "
097: + Math.exp(SpecialFunctions.lnFactorial(6)));
098: System.out.println("Binomial 6 over 2: "
099: + Math.pow(2, SpecialFunctions.log2Binomial(6, 2)));
100: System.out.println("Multinomial 6 over 1, 2, 3: "
101: + Math.pow(2, SpecialFunctions.log2Multinomial(6,
102: doubles)));
103: }
104: }
|