package ee.ut.ga.util;

import java.math.BigDecimal;

public class MathUtil {
  
  /**
   * Computes p-value (calculation of p-value is reversed)
   */
  public static BigDecimal pValue(BigDecimal good, BigDecimal goodAll, BigDecimal bad, BigDecimal badAll) {
    BigDecimal result = combination(goodAll.add(badAll), good.add(bad));
    result = result.divide(combination(goodAll, good), 3, BigDecimal.ROUND_HALF_DOWN);
    result = result.divide(combination(badAll, bad), 3, BigDecimal.ROUND_HALF_DOWN);
    return result;
  }

  /**
   * Computes combination without repetition: C^r[n].
   */
  public static BigDecimal combination(BigDecimal n, BigDecimal r) throws IllegalArgumentException {
    if (n.compareTo(r) == -1)
      throw new IllegalArgumentException("In combination r parameter can't be larger than n!");

    return factorial(n).divide(factorial(r), 3, BigDecimal.ROUND_HALF_DOWN).divide(factorial(n.subtract(r)),
                                                                                   3,
                                                                                   BigDecimal.ROUND_HALF_DOWN);
  }

  /**
   * Computes factorial: x!
   */
  public static BigDecimal factorial(BigDecimal x) throws IllegalArgumentException {
    if (x.compareTo(new BigDecimal("0")) == -1)
      throw new IllegalArgumentException("x can't be negative!");

    if (x.compareTo(new BigDecimal("9272")) == 1)
      throw new IllegalArgumentException("x can't be larger than 9272!");

    BigDecimal result = new BigDecimal("1");
    for (int i = 1; i <= x.intValue(); i++) {
      result = result.multiply(new BigDecimal("" + i));
    }
    return result;
  }
}
