/** Computes the probability <SPAN CLASS="MATH"><I>p</I>(<I>x</I>)</SPAN>. */
  public static double prob(double n, double p, int x) {
    final int SLIM = 15; // To avoid overflow
    final double MAXEXP = (Num.DBL_MAX_EXP - 1) * Num.LN2; // To avoid overflow
    final double MINEXP = (Num.DBL_MIN_EXP - 1) * Num.LN2; // To avoid underflow
    double y;

    if (p < 0.0 || p > 1.0) throw new IllegalArgumentException("p not in [0, 1]");
    if (n <= 0.0) throw new IllegalArgumentException("n <= 0.0");
    if (x < 0) return 0.0;
    if (p >= 1.0) { // In fact, p == 1
      if (x == 0) return 1.0;
      else return 0.0;
    }
    if (p <= 0.0) // In fact, p == 0
    return 0.0;

    y =
        Num.lnGamma(n + x)
            - (Num.lnFactorial(x) + Num.lnGamma(n))
            + n * Math.log(p)
            + x * Math.log1p(-p);

    if (y >= MAXEXP) throw new IllegalArgumentException("term overflow");
    return Math.exp(y);
  }
Example #2
0
 /** Computes the density function @f$f(x)@f$. */
 public static double density(double alpha, double lambda, double x) {
   if (lambda <= 0) throw new IllegalArgumentException("lambda <= 0");
   double z = lambda * (x - alpha);
   if (z >= -100.0) {
     double v = Math.exp(-z);
     return lambda * v / ((1.0 + v) * (1.0 + v));
   }
   return lambda * Math.exp(z);
 }
Example #3
0
  /**
   * Estimates the parameters @f$(\alpha, \lambda)@f$ of the logistic distribution using the maximum
   * likelihood method, from the @f$n@f$ observations @f$x[i]@f$, @f$i = 0, 1,…, n-1@f$. The
   * estimates are returned in a two-element array, in regular order: [@f$\alpha@f$,
   *
   * @f$\lambda@f$]. The maximum likelihood estimators are the values
   * @f$(\hat{\alpha}, \hat{\lambda})@f$ that satisfy the equations:
   * @f{align*}{ \sum_{i=1}^n \frac{1}{1 + e^{\hat{\lambda} (x_i - \hat{\alpha})}} & = \frac{n}{2}
   *     \\ \sum_{i=1}^n \hat{\lambda} (x_i - \hat{\alpha}) \frac{1 - e^{\hat{\lambda} (x_i -
   *     \hat{\alpha})}}{1 + e^{\hat{\lambda} (x_i - \hat{\alpha})}} & = n.
   * @f} See @cite mEVA00a&thinsp; (page 128).
   * @param x the list of observations used to evaluate parameters
   * @param n the number of observations used to evaluate parameters
   * @return returns the parameter [@f$\hat{\alpha}@f$,
   * @f$\hat{\lambda}@f$]
   */
  public static double[] getMLE(double[] x, int n) {
    if (n <= 0) throw new IllegalArgumentException("n <= 0");

    double sum = 0.0;
    for (int i = 0; i < n; i++) sum += x[i];

    double[] param = new double[3];
    param[1] = sum / (double) n;

    sum = 0.0;
    for (int i = 0; i < n; i++) sum += ((x[i] - param[1]) * (x[i] - param[1]));

    param[2] = Math.sqrt(Math.PI * Math.PI * n / (3.0 * sum));

    double[] fvec = new double[3];
    double[][] fjac = new double[3][3];
    int[] iflag = new int[2];
    int[] info = new int[2];
    int[] ipvt = new int[3];
    Optim system = new Optim(x, n);

    Minpack_f77.lmder1_f77(system, 2, 2, param, fvec, fjac, 1e-5, info, ipvt);

    double parameters[] = new double[2];
    parameters[0] = param[1];
    parameters[1] = param[2];

    return parameters;
  }
    public double evaluate(double gam) {
      if (gam <= 0) return 1.0e100;

      double sum = 0.0;
      for (int j = 0; j < m; j++) sum += Num.digamma(gam + x[j]);
      return sum / m + Math.log(p) - Num.digamma(gam);
    }
Example #5
0
  /** Computes the inverse distribution function @f$F^{-1}(u)@f$. */
  public static double inverseF(double alpha, double lambda, double u) {
    if (lambda <= 0) throw new IllegalArgumentException("lambda <= 0");
    if (u < 0.0 || u > 1.0) throw new IllegalArgumentException("u not in [0, 1]");
    if (u >= 1.0) return Double.POSITIVE_INFINITY;
    if (u <= 0.0) return Double.NEGATIVE_INFINITY;

    return Math.log(u / (1.0 - u)) / lambda + alpha;
  }
    public double evaluate(double s) {
      if (s <= 0) return 1.0e100;
      double sum = 0.0;
      double p = s / (s + mean);

      for (int j = 0; j < max; j++) sum += Fj[j] / (s + (double) j);

      return sum + m * Math.log(p);
    }
  /** Computes the distribution function. */
  public static double cdf(double n, double p, int x) {
    final double EPSILON = DiscreteDistributionInt.EPSILON;
    final int LIM1 = 100000;
    double sum, term, termmode;
    int i, mode;
    final double q = 1.0 - p;

    if (p < 0.0 || p > 1.0) throw new IllegalArgumentException("p not in [0, 1]");
    if (n <= 0.0) throw new IllegalArgumentException("n <= 0.0");

    if (x < 0) return 0.0;
    if (p >= 1.0) // In fact, p == 1
    return 1.0;
    if (p <= 0.0) // In fact, p == 0
    return 0.0;

    // Compute the maximum term
    mode = 1 + (int) Math.floor((n * q - 1.0) / p);
    if (mode < 0) mode = 0;
    else if (mode > x) mode = x;

    if (mode <= LIM1) {
      sum = term = termmode = prob(n, p, mode);
      for (i = mode; i > 0; i--) {
        term *= i / (q * (n + i - 1.0));
        if (term < EPSILON) break;
        sum += term;
      }

      term = termmode;
      for (i = mode; i < x; i++) {
        term *= q * (n + i) / (i + 1);
        if (term < EPSILON) break;
        sum += term;
      }
      if (sum <= 1.0) return sum;
      else return 1.0;
    } else
      // return 1.0 - BinomialDist.cdf (x + n, p, n - 1);
      return BetaDist.cdf(n, x + 1.0, 15, p);
  }
Example #8
0
    public void fcn(int m, int n, double[] x, double[] fvec, double[][] fjac, int iflag[]) {
      if (x[2] <= 0.0) {
        final double BIG = 1.0e100;
        fvec[1] = BIG;
        fvec[2] = BIG;
        fjac[1][1] = BIG;
        fjac[1][2] = 0.0;
        fjac[2][1] = 0.0;
        fjac[2][2] = BIG;
        return;
      }

      double sum;
      double prod;

      if (iflag[1] == 1) {
        sum = 0.0;
        for (int i = 0; i < n; i++) sum += (1.0 / (1.0 + Math.exp(x[2] * (xi[i] - x[1]))));
        fvec[1] = sum - n / 2.0;

        sum = 0.0;
        for (int i = 0; i < n; i++) {
          prod = x[2] * (xi[i] - x[1]);
          sum -= prod * Math.tanh(prod / 2.0);
        }
        fvec[2] = sum - n;
      } else if (iflag[1] == 2) {
        sum = 0.0;
        for (int i = 0; i < n; i++) {
          prod = Math.exp(x[2] * (xi[i] - x[1]));
          sum -= x[2] * prod / ((1 + prod) * (1 + prod));
        }
        fjac[1][1] = sum;

        sum = 0.0;
        for (int i = 0; i < n; i++) {
          prod = Math.exp(x[2] * (xi[i] - x[1]));
          sum -= (xi[i] - x[1]) * prod / ((1 + prod) * (1 + prod));
        }
        fjac[1][2] = sum;

        sum = 0.0;
        for (int i = 0; i < n; i++) {
          prod = Math.exp(x[2] * (xi[i] - x[1]));
          sum -=
              (x[2] * ((-1.0 + prod) * (1.0 + prod) - (2.0 * (x[2] * (xi[i] - x[1])) * prod)))
                  / ((1.0 + prod) * (1.0 + prod));
        }
        fjac[2][1] = sum;

        sum = 0.0;
        for (int i = 0; i < n; i++) {
          prod = Math.exp(x[2] * (xi[i] - x[1]));
          sum -=
              ((x[1] - xi[1])
                      * ((-1.0 + prod) * (1.0 + prod) - (2.0 * (x[2] * (xi[i] - x[1])) * prod)))
                  / ((1.0 + prod) * (1.0 + prod));
        }
        fjac[2][2] = sum;
      }
    }
Example #9
0
  /**
   * Computes and returns the standard deviation of the logistic distribution with
   * parameters @f$\alpha@f$ and @f$\lambda@f$.
   *
   * @return the standard deviation of the logistic distribution
   */
  public static double getStandardDeviation(double alpha, double lambda) {
    if (lambda <= 0.0) throw new IllegalArgumentException("lambda <= 0");

    return (Math.sqrt(1.0 / 3.0) * Math.PI / lambda);
  }
Example #10
0
 /** Computes the complementary distribution function @f$1-F(x)@f$. */
 public static double barF(double alpha, double lambda, double x) {
   if (lambda <= 0) throw new IllegalArgumentException("lambda <= 0");
   double z = lambda * (x - alpha);
   if (z <= 100.0) return 1.0 / (1.0 + Math.exp(z));
   return Math.exp(-z);
 }
  /**
   * Sets the parameter <SPAN CLASS="MATH"><I>n</I></SPAN> and <SPAN CLASS="MATH"><I>p</I></SPAN> of
   * this object.
   */
  public void setParams(double n, double p) {
    /* *
     *  Compute all probability terms of the negative binomial distribution;
     *  start at the mode, and calculate probabilities on each side until they
     *  become smaller than EPSILON. Set all others to 0.
     */
    supportA = 0;
    int i, mode, Nmax;
    int imin, imax;
    double sum;
    double[] P; // Negative Binomial mass probabilities
    double[] F; // Negative Binomial cumulative

    if (p < 0.0 || p > 1.0) throw new IllegalArgumentException("p not in [0, 1]");
    if (n <= 0.0) throw new IllegalArgumentException("n <= 0");

    this.n = n;
    this.p = p;

    // Compute the mode (at the maximum term)
    mode = 1 + (int) Math.floor((n * (1.0 - p) - 1.0) / p);

    /* *
     For mode > MAXN, we shall not use pre-computed arrays.
     mode < 0 should be impossible, unless overflow of long occur, in
     which case mode will be = LONG_MIN.
    */

    if (mode < 0.0 || mode > MAXN) {
      pdf = null;
      cdf = null;
      return;
    }

    /* *
      In theory, the negative binomial distribution has an infinite range.
      But for i > Nmax, probabilities should be extremely small.
      Nmax = Mean + 16 * Standard deviation.
    */

    Nmax = (int) (n * (1.0 - p) / p + 16 * Math.sqrt(n * (1.0 - p) / (p * p)));
    if (Nmax < 32) Nmax = 32;
    P = new double[1 + Nmax];

    double epsilon = EPSILON / prob(n, p, mode);

    // We shall normalize by explicitly summing all terms >= epsilon
    sum = P[mode] = 1.0;

    // Start from the maximum and compute terms > epsilon on each side.
    i = mode;
    while (i > 0 && P[i] >= epsilon) {
      P[i - 1] = P[i] * i / ((1.0 - p) * (n + i - 1));
      i--;
      sum += P[i];
    }
    imin = i;

    i = mode;
    while (P[i] >= epsilon) {
      P[i + 1] = P[i] * (1.0 - p) * (n + i) / (i + 1);
      i++;
      sum += P[i];
      if (i == Nmax - 1) {
        Nmax *= 2;
        double[] nT = new double[1 + Nmax];
        System.arraycopy(P, 0, nT, 0, P.length);
        P = nT;
      }
    }
    imax = i;

    // Renormalize the sum of probabilities to 1
    for (i = imin; i <= imax; i++) P[i] /= sum;

    // Compute the cumulative probabilities for F and keep them in the
    // lower part of CDF.
    F = new double[1 + Nmax];
    F[imin] = P[imin];
    i = imin;
    while (i < imax && F[i] < 0.5) {
      i++;
      F[i] = F[i - 1] + P[i];
    }

    // This is the boundary between F (i <= xmed) and 1 - F (i > xmed) in
    // the array CDF
    xmed = i;

    // Compute the cumulative probabilities of the complementary
    // distribution 1 - F and keep them in the upper part of the array
    F[imax] = P[imax];
    i = imax - 1;
    do {
      F[i] = P[i] + F[i + 1];
      i--;
    } while (i > xmed);

    xmin = imin;
    xmax = imax;
    pdf = new double[imax + 1 - imin];
    cdf = new double[imax + 1 - imin];
    System.arraycopy(P, imin, pdf, 0, imax + 1 - imin);
    System.arraycopy(F, imin, cdf, 0, imax + 1 - imin);
  }
 /**
  * Computes and returns the standard deviation of the negative binomial distribution with
  * parameters <SPAN CLASS="MATH"><I>n</I></SPAN> and <SPAN CLASS="MATH"><I>p</I></SPAN>.
  *
  * @return the standard deviation of the negative binomial distribution
  */
 public static double getStandardDeviation(double n, double p) {
   return Math.sqrt(NegativeBinomialDist.getVariance(n, p));
 }
  /** Computes the inverse function without precomputing tables. */
  public static int inverseF(double n, double p, double u) {
    if (u < 0.0 || u > 1.0) throw new IllegalArgumentException("u is not in [0,1]");
    if (p < 0.0 || p > 1.0) throw new IllegalArgumentException("p not in [0, 1]");
    if (n <= 0.0) throw new IllegalArgumentException("n <= 0");
    if (p >= 1.0) // In fact, p == 1
    return 0;
    if (p <= 0.0) // In fact, p == 0
    return 0;
    if (u <= prob(n, p, 0)) return 0;
    if (u >= 1.0) return Integer.MAX_VALUE;

    double sum, term, termmode;
    final double q = 1.0 - p;

    // Compute the maximum term
    int mode = 1 + (int) Math.floor((n * q - 1.0) / p);
    if (mode < 0) mode = 0;
    int i = mode;
    term = prob(n, p, i);
    while ((term >= u) && (term > Double.MIN_NORMAL)) {
      i /= 2;
      term = prob(n, p, i);
    }

    if (term <= Double.MIN_NORMAL) {
      i *= 2;
      term = prob(n, p, i);
      while (term >= u && (term > Double.MIN_NORMAL)) {
        term *= i / (q * (n + i - 1.0));
        i--;
      }
    }

    mode = i;
    sum = termmode = prob(n, p, i);

    for (i = mode; i > 0; i--) {
      term *= i / (q * (n + i - 1.0));
      if (term < EPSILON) break;
      sum += term;
    }

    term = termmode;
    i = mode;
    double prev = -1;
    if (sum < u) {
      // The CDF at the mode is less than u, so we add term to get >= u.
      while ((sum < u) && (sum > prev)) {
        term *= q * (n + i) / (i + 1);
        prev = sum;
        sum += term;
        i++;
      }
    } else {
      // The computed CDF is too big so we substract from it.
      sum -= term;
      while (sum >= u) {
        term *= i / (q * (n + i - 1.0));
        i--;
        sum -= term;
      }
    }
    return i;
  }