@Test
 public void testLogExponentialDistribution() {
   assertEquals(
       Math.log(Distributions.exponentialDistribution(5, 6)),
       Distributions.logExponentialDistribution(5, 6),
       DELTA);
 }
示例#2
0
  private static double do_search(
      double y, double[] z, double p, double n, double pr, double incr) {
    if (z[0] >= p) {
      /* search to the left */
      for (; ; ) {
        if (y == 0
            || (z[0] =
                    Distributions.pnbinom(y - incr, (int) n, pr, /*l._t.*/ true, /*log_p*/ false))
                < p) {
          return y;
        }
        y = Math.max(0, y - incr);
      }
    } else {
        /* search to the right */

      for (; ; ) {
        y = y + incr;
        if ((z[0] = Distributions.pnbinom(y, (int) n, pr, /*l._t.*/ true, /*log_p*/ false)) >= p) {
          return y;
        }
      }
    }
  }
示例#3
0
  /**
   * Get a probability estimate for a value.
   *
   * @param data the value to estimate the probability of
   * @return the estimated probability of the supplied value
   */
  public double getProbability(double data) {

    double delta = 0, sum = 0, currentProb = 0;
    double zLower = 0, zUpper = 0;
    if (m_NumValues == 0) {
      zLower = (data - (m_Precision / 2)) / m_StandardDev;
      zUpper = (data + (m_Precision / 2)) / m_StandardDev;
      return (Distributions.normalProbability(zUpper) - Distributions.normalProbability(zLower));
    }
    double weightSum = 0;
    int start = findNearestValue(data);
    for (int i = start; i < m_NumValues; i++) {
      delta = m_Values[i] - data;
      zLower = (delta - (m_Precision / 2)) / m_StandardDev;
      zUpper = (delta + (m_Precision / 2)) / m_StandardDev;
      currentProb =
          (Distributions.normalProbability(zUpper) - Distributions.normalProbability(zLower));
      sum += currentProb * m_Weights[i];
      /*
            System.out.print("zL" + (i + 1) + ": " + zLower + " ");
            System.out.print("zU" + (i + 1) + ": " + zUpper + " ");
            System.out.print("P" + (i + 1) + ": " + currentProb + " ");
      System.out.println("total: " + (currentProb * m_Weights[i]) + " ");
      */
      weightSum += m_Weights[i];
      if (currentProb * (m_SumOfWeights - weightSum) < sum * MAX_ERROR) {
        break;
      }
    }
    for (int i = start - 1; i >= 0; i--) {
      delta = m_Values[i] - data;
      zLower = (delta - (m_Precision / 2)) / m_StandardDev;
      zUpper = (delta + (m_Precision / 2)) / m_StandardDev;
      currentProb =
          (Distributions.normalProbability(zUpper) - Distributions.normalProbability(zLower));
      sum += currentProb * m_Weights[i];
      weightSum += m_Weights[i];
      if (currentProb * (m_SumOfWeights - weightSum) < sum * MAX_ERROR) {
        break;
      }
    }
    return sum / m_SumOfWeights;
  }
示例#4
0
  public static double rbinom(Context.Globals context, double nin, double pp) {

    /* static */
    double c = 0, fm = 0, npq = 0, p1 = 0, p2 = 0, p3 = 0, p4 = 0, qn = 0;
    double xl = 0, xll = 0, xlr = 0, xm = 0, xr = 0;
    double psave = -1.0;
    int nsave = -1;
    int m = 0;
    /* end of static */

    double f, f1, f2, u, v, w, w2, x, x1, x2, z, z2;
    double p, q, np, g, r, al, alv, amaxp, ffm, ynorm;
    int i, ix, k, n;

    if (Double.isInfinite(nin)) {
      return Double.NaN;
    }
    r = Math.floor(nin + 0.5);
    if (r != nin) {
      return Double.NaN;
    }
    if (Double.isInfinite(pp) || r < 0 || pp < 0. || pp > 1.) {
      return Double.NaN;
    }

    if (r == 0 || pp == 0.) {
      return 0;
    }
    if (pp == 1.) {
      return r;
    }

    if (r >= Integer.MAX_VALUE) {
      return Distributions.qbinom(context.rng.unif_rand(), (int) r, pp, false, false);
    }
    /* else */
    n = (int) r;

    p = Math.min(pp, 1. - pp);
    q = 1. - p;
    np = n * p;
    r = p / q;
    g = r * (n + 1);

    /* Setup, perform only when parameters change [using static (globals): */

    /* FIXING: Want this thread safe
    -- use as little (thread globals) as possible
     */
    if (pp != psave || n != nsave) {
      psave = pp;
      nsave = n;
      if (np < 30.0) {
        /* inverse cdf logic for mean less than 30 */
        qn = Math.pow(q, (double) n);

        /*---------------------- np = n*p < 30 : ------------------------- */
        while (true) {
          ix = 0;
          f = qn;
          u = context.rng.unif_rand();
          while (true) {
            if (u < f) {
              if (psave > 0.5) {
                ix = n - ix;
              }
              return (double) ix;
            }
            if (ix > 110) {
              break;
            }
            u -= f;
            ix++;
            f *= (g / ix - r);
          }
        }

      } else {
        ffm = np + p;
        m = (int) ffm;
        fm = m;
        npq = np * q;
        p1 = (int) (2.195 * Math.sqrt(npq) - 4.6 * q) + 0.5;
        xm = fm + 0.5;
        xl = xm - p1;
        xr = xm + p1;
        c = 0.134 + 20.5 / (15.3 + fm);
        al = (ffm - xl) / (ffm - xl * p);
        xll = al * (1.0 + 0.5 * al);
        al = (xr - ffm) / (xr * q);
        xlr = al * (1.0 + 0.5 * al);
        p2 = p1 * (1.0 + c + c);
        p3 = p2 + c / xll;
        p4 = p3 + c / xlr;
      }
    } else if (n == nsave) {
      if (np < 30.0) {}

      /*---------------------- np = n*p < 30 : ------------------------- */
      while (true) {
        ix = 0;
        f = qn;
        u = context.rng.unif_rand();
        while (true) {
          if (u < f) {
            if (psave > 0.5) {
              ix = n - ix;
            }
            return (double) ix;
          }
          if (ix > 110) {
            break;
          }
          u -= f;
          ix++;
          f *= (g / ix - r);
        }
      }
    }

    /*-------------------------- np = n*p >= 30 : ------------------- */
    while (true) {
      u = context.rng.unif_rand() * p4;
      v = context.rng.unif_rand();
      /* triangular region */
      if (u <= p1) {
        ix = (int) (xm - p1 * v + u);

        if (psave > 0.5) {
          ix = n - ix;
        }
        return (double) ix;
      }
      /* parallelogram region */
      if (u <= p2) {
        x = xl + (u - p1) / c;
        v = v * c + 1.0 - Math.abs(xm - x) / p1;
        if (v > 1.0 || v <= 0.) {
          continue;
        }
        ix = (int) x;
      } else {
        if (u > p3) {
            /* right tail */
          ix = (int) (xr - Math.log(v) / xlr);
          if (ix > n) {
            continue;
          }
          v = v * (u - p3) * xlr;
        } else {
            /* left tail */
          ix = (int) (xl + Math.log(v) / xll);
          if (ix < 0) {
            continue;
          }
          v = v * (u - p2) * xll;
        }
      }
      /* determine appropriate way to perform accept/reject test */
      k = Math.abs(ix - m);
      if (k <= 20 || k >= npq / 2 - 1) {
        /* explicit evaluation */
        f = 1.0;
        if (m < ix) {
          for (i = m + 1; i <= ix; i++) {
            f *= (g / i - r);
          }
        } else if (m != ix) {
          for (i = ix + 1; i <= m; i++) {
            f /= (g / i - r);
          }
        }
        if (v <= f) {
          if (psave > 0.5) {
            ix = n - ix;
          }
          return (double) ix;
        }

      } else {
        /* squeezing using upper and lower bounds on log(f(x)) */
        amaxp = (k / npq) * ((k * (k / 3. + 0.625) + 0.1666666666666) / npq + 0.5);
        ynorm = -k * k / (2.0 * npq);
        alv = Math.log(v);
        if (alv < ynorm - amaxp) {
          if (psave > 0.5) {
            ix = n - ix;
          }
          return (double) ix;
        }

        if (alv <= ynorm + amaxp) {
          /* stirling's formula to machine accuracy */
          /* for the final acceptance/rejection test */
          x1 = ix + 1;
          f1 = fm + 1.0;
          z = n + 1 - fm;
          w = n - ix + 1.0;
          z2 = z * z;
          x2 = x1 * x1;
          f2 = f1 * f1;
          w2 = w * w;
          if (alv
              <= xm * Math.log(f1 / x1)
                  + (n - m + 0.5) * Math.log(z / w)
                  + (ix - m) * Math.log(w * p / (x1 * q))
                  + (13860.0 - (462.0 - (132.0 - (99.0 - 140.0 / f2) / f2) / f2) / f2)
                      / f1
                      / 166320.0
                  + (13860.0 - (462.0 - (132.0 - (99.0 - 140.0 / z2) / z2) / z2) / z2)
                      / z
                      / 166320.0
                  + (13860.0 - (462.0 - (132.0 - (99.0 - 140.0 / x2) / x2) / x2) / x2)
                      / x1
                      / 166320.0
                  + (13860.0 - (462.0 - (132.0 - (99.0 - 140.0 / w2) / w2) / w2) / w2)
                      / w
                      / 166320.) {}

          if (psave > 0.5) {
            ix = n - ix;
          }
          return (double) ix;
        }
      }
    }
  }
示例#5
0
  public static double qnbinom(
      double p, double size, double prob, boolean lower_tail, boolean log_p) {
    double P, Q, mu, sigma, gamma, y;
    double[] z = new double[1];

    if (DoubleVector.isNaN(p) || DoubleVector.isNaN(size) || DoubleVector.isNaN(prob)) {
      return p + size + prob;
    }

    if (prob <= 0 || prob > 1 || size <= 0) {
      return DoubleVector.NaN;
    }

    /* FIXME: size = 0 is well defined ! */
    if (prob == 1) {
      return 0;
    }

    // R_Q_P01_boundaries(p, 0, ML_POSINF);
    // #define R_Q_P01_boundaries(p, _LEFT_, _RIGHT_)
    // This macro is defined in /src/nmath/dpq.h
    if (log_p) {
      if (p > 0) {
        return DoubleVector.NaN;
      }
      if (p == 0) {
          /* upper bound*/
        return lower_tail ? Double.POSITIVE_INFINITY : 0;
      }
      if (p == Double.NEGATIVE_INFINITY) {
        return lower_tail ? 0 : Double.POSITIVE_INFINITY;
      }
    } else {
        /* !log_p */
      if (p < 0 || p > 1) {
        return DoubleVector.NaN;
      }
      if (p == 0) {
        return lower_tail ? 0 : Double.POSITIVE_INFINITY;
      }
      if (p == 1) {
        return lower_tail ? Double.POSITIVE_INFINITY : 0;
      }
    }

    Q = 1.0 / prob;
    P = (1.0 - prob) * Q;
    mu = size * P;
    sigma = Math.sqrt(size * P * Q);
    gamma = (Q + P) / sigma;

    /* Note : "same" code in qpois.c, qbinom.c, qnbinom.c --
     * FIXME: This is far from optimal [cancellation for p ~= 1, etc]: */
    if (!lower_tail || log_p) {
      // p = R_DT_qIv(p); /* need check again (cancellation!): */
      p = Normal.R_DT_qIv(p, lower_tail ? 1.0 : 0.0, log_p ? 1.0 : 0.0);
      if (p == SignRank.R_DT_0(lower_tail, log_p)) {
        return 0;
      }
      if (p == SignRank.R_DT_1(lower_tail, log_p)) {
        return Double.POSITIVE_INFINITY;
      }
    }
    /* temporary hack --- FIXME --- */
    if (p + 1.01 * SignRank.DBL_EPSILON >= 1.) {
      return Double.POSITIVE_INFINITY;
    }

    /* y := approx.value (Cornish-Fisher expansion) :  */
    z[0] = Distributions.qnorm(p, 0., 1., /*lower_tail*/ true, /*log_p*/ false);
    y = Math.floor(mu + sigma * (z[0] + gamma * (z[0] * z[0] - 1) / 6) + 0.5);

    z[0] = Distributions.pnbinom(y, (int) size, prob, /*lower_tail*/ true, /*log_p*/ false);

    /* fuzz to ensure left continuity: */
    p *= 1 - 64 * SignRank.DBL_EPSILON;

    /* If the C-F value is not too large a simple search is OK */
    if (y < 1e5) {
      return do_search(y, z, p, size, prob, 1);
    }
    /* Otherwise be a bit cleverer in the search */
    {
      double incr = Math.floor(y * 0.001), oldincr;
      do {
        oldincr = incr;
        y = do_search(y, z, p, size, prob, incr);
        incr = Math.max(1, Math.floor(incr / 100));
      } while (oldincr > 1 && incr > y * 1e-15);
      return y;
    }
  }