Example #1
0
  /**
   * Tests the hypergeometric distribution code, or other functions provided in this module.
   *
   * @param args Either none, and the log add rountines are tested, or the following 4 arguments: k
   *     (cell), n (total), r (row), m (col)
   */
  public static void main(String[] args) {
    if (args.length == 0) {
      System.err.println(
          "Usage: java edu.stanford.nlp.math.SloppyMath "
              + "[-logAdd|-fishers k n r m|-binomial r n p");
    } else if (args[0].equals("-logAdd")) {
      System.out.println("Log adds of neg infinity numbers, etc.");
      System.out.println(
          "(logs) -Inf + -Inf = " + logAdd(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY));
      System.out.println("(logs) -Inf + -7 = " + logAdd(Double.NEGATIVE_INFINITY, -7.0));
      System.out.println("(logs) -7 + -Inf = " + logAdd(-7.0, Double.NEGATIVE_INFINITY));
      System.out.println("(logs) -50 + -7 = " + logAdd(-50.0, -7.0));
      System.out.println("(logs) -11 + -7 = " + logAdd(-11.0, -7.0));
      System.out.println("(logs) -7 + -11 = " + logAdd(-7.0, -11.0));
      System.out.println("real 1/2 + 1/2 = " + logAdd(Math.log(0.5), Math.log(0.5)));
    } else if (args[0].equals("-fishers")) {
      int k = Integer.parseInt(args[1]);
      int n = Integer.parseInt(args[2]);
      int r = Integer.parseInt(args[3]);
      int m = Integer.parseInt(args[4]);
      double ans = SloppyMath.hypergeometric(k, n, r, m);
      System.out.println("hypg(" + k + "; " + n + ", " + r + ", " + m + ") = " + ans);
      ans = SloppyMath.oneTailedFishersExact(k, n, r, m);
      System.out.println(
          "1-tailed Fisher's exact(" + k + "; " + n + ", " + r + ", " + m + ") = " + ans);
      double ansChi = SloppyMath.chiSquare2by2(k, n, r, m);
      System.out.println("chiSquare(" + k + "; " + n + ", " + r + ", " + m + ") = " + ansChi);

      System.out.println("Swapping arguments should give same hypg:");
      ans = SloppyMath.hypergeometric(k, n, r, m);
      System.out.println("hypg(" + k + "; " + n + ", " + m + ", " + r + ") = " + ans);
      int othrow = n - m;
      int othcol = n - r;
      int cell12 = m - k;
      int cell21 = r - k;
      int cell22 = othrow - (r - k);
      ans = SloppyMath.hypergeometric(cell12, n, othcol, m);
      System.out.println("hypg(" + cell12 + "; " + n + ", " + othcol + ", " + m + ") = " + ans);
      ans = SloppyMath.hypergeometric(cell21, n, r, othrow);
      System.out.println("hypg(" + cell21 + "; " + n + ", " + r + ", " + othrow + ") = " + ans);
      ans = SloppyMath.hypergeometric(cell22, n, othcol, othrow);
      System.out.println(
          "hypg(" + cell22 + "; " + n + ", " + othcol + ", " + othrow + ") = " + ans);
    } else if (args[0].equals("-binomial")) {
      int k = Integer.parseInt(args[1]);
      int n = Integer.parseInt(args[2]);
      double p = Double.parseDouble(args[3]);
      double ans = SloppyMath.exactBinomial(k, n, p);
      System.out.println("Binomial p(X >= " + k + "; " + n + ", " + p + ") = " + ans);
    } else {
      System.err.println("Unknown option: " + args[0]);
    }
  }
Example #2
0
  /**
   * Find a one-tailed Fisher's exact probability. Chance of having seen this or a more extreme
   * departure from what you would have expected given independence. I.e., k >= the value passed in.
   * Warning: this was done just for collocations, where you are concerned with the case of k being
   * larger than predicted. It doesn't correctly handle other cases, such as k being smaller than
   * expected.
   *
   * @param k The number of black balls drawn
   * @param n The total number of balls
   * @param r The number of black balls
   * @param m The number of balls drawn
   * @return The Fisher's exact p-value
   */
  public static double oneTailedFishersExact(int k, int n, int r, int m) {
    if (k < 0 || k < (m + r) - n || k > r || k > m || r > n || m > n) {
      throw new IllegalArgumentException(
          "Invalid Fisher's exact: "
              + "k="
              + k
              + " n="
              + n
              + " r="
              + r
              + " m="
              + m
              + " k<0="
              + (k < 0)
              + " k<(m+r)-n="
              + (k < (m + r) - n)
              + " k>r="
              + (k > r)
              + " k>m="
              + (k > m)
              + " r>n="
              + (r > n)
              + "m>n="
              + (m > n));
    }
    // exploit symmetry of problem
    if (m > n / 2) {
      m = n - m;
      k = r - k;
    }
    if (r > n / 2) {
      r = n - r;
      k = m - k;
    }
    if (m > r) {
      int temp = m;
      m = r;
      r = temp;
    }
    // now we have that k <= m <= r <= n/2

    double total = 0.0;
    if (k > m / 2) {
      // sum from k to m
      for (int k0 = k; k0 <= m; k0++) {
        // System.out.println("Calling hypg(" + k0 + "; " + n +
        // 		   ", " + r + ", " + m + ")");
        total += SloppyMath.hypergeometric(k0, n, r, m);
      }
    } else {
      // sum from max(0, (m+r)-n) to k-1, and then subtract from 1
      int min = Math.max(0, (m + r) - n);
      for (int k0 = min; k0 < k; k0++) {
        // System.out.println("Calling hypg(" + k0 + "; " + n +
        // 		   ", " + r + ", " + m + ")");
        total += SloppyMath.hypergeometric(k0, n, r, m);
      }
      total = 1.0 - total;
    }
    return total;
  }
Example #3
0
 public double iScore(Edge edge) {
   return SloppyMath.min(scorer1.iScore(edge), scorer2.iScore(edge));
 }