/**
   * Removes from the receiver all elements that are contained in the specified list. Tests for
   * identity.
   *
   * @param other the other list.
   * @return <code>true</code> if the receiver changed as a result of the call.
   */
  public boolean removeAll(AbstractShortList other) {
    // overridden for performance only.
    if (!(other instanceof ShortArrayList)) return super.removeAll(other);

    /*
     * There are two possibilities to do the thing a) use other.indexOf(...)
     * b) sort other, then use other.binarySearch(...)
     *
     * Let's try to figure out which one is faster. Let M=size,
     * N=other.size, then a) takes O(M*N) steps b) takes O(N*logN + M*logN)
     * steps (sorting is O(N*logN) and binarySearch is O(logN))
     *
     * Hence, if N*logN + M*logN < M*N, we use b) otherwise we use a).
     */
    if (other.size() == 0) {
      return false;
    } // nothing to do
    int limit = other.size() - 1;
    int j = 0;
    short[] theElements = elements;
    int mySize = size();

    double N = (double) other.size();
    double M = (double) mySize;
    if ((N + M) * cern.jet.math.Arithmetic.log2(N) < M * N) {
      // it is faster to sort other before searching in it
      ShortArrayList sortedList = (ShortArrayList) other.clone();
      sortedList.quickSort();

      for (int i = 0; i < mySize; i++) {
        if (sortedList.binarySearchFromTo(theElements[i], 0, limit) < 0)
          theElements[j++] = theElements[i];
      }
    } else {
      // it is faster to search in other without sorting
      for (int i = 0; i < mySize; i++) {
        if (other.indexOfFromTo(theElements[i], 0, limit) < 0) theElements[j++] = theElements[i];
      }
    }

    boolean modified = (j != mySize);
    setSize(j);
    return modified;
  }
Beispiel #2
0
  /** Returns a random number from the distribution; bypasses the internal state. */
  public int nextInt(double theMean) {
    /**
     * **************************************************************** * Poisson Distribution -
     * Patchwork Rejection/Inversion * *
     * ***************************************************************** * For parameter my < 10
     * Tabulated Inversion is applied. * For my >= 10 Patchwork Rejection is employed: * The area
     * below the histogram function f(x) is rearranged in * its body by certain point reflections.
     * Within a large center * interval variates are sampled efficiently by rejection from * uniform
     * hats. Rectangular immediate acceptance regions speed * up the generation. The remaining tails
     * are covered by * exponential functions. * *
     * ***************************************************************
     */
    // RandomEngine gen =this.randomGenerator;
    double my = theMean;

    double t, g, my_k;

    double gx, gy, px, py, e, x, xx, delta, v;
    int sign;

    // static double p,q,p0,pp[36];
    // static long ll,m;
    double u;
    int k, i;

    if (my < SWITCH_MEAN) { // CASE B: Inversion- start new table and calculate p0
      if (my != my_old) {
        my_old = my;
        llll = 0;
        p = Math.exp(-my);
        q = p;
        p0 = p;
        // for (k=pp.length; --k >=0; ) pp[k] = 0;
      }
      m = (my > 1.0) ? (int) my : 1;
      for (; ; ) {
        u = random.nextDouble(); // gen.raw(); // Step U. Uniform sample
        k = 0;
        if (u <= p0) return (k);
        if (llll != 0) { // Step T. Table comparison
          i = (u > 0.458) ? Math.min(llll, m) : 1;
          for (k = i; k <= llll; k++) if (u <= pp[k]) return (k);
          if (llll == 35) continue;
        }
        for (k = llll + 1; k <= 35; k++) { // Step C. Creation of new prob.
          p *= my / (double) k;
          q += p;
          pp[k] = q;
          if (u <= q) {
            llll = k;
            return (k);
          }
        }
        llll = 35;
      }
    } // end my < SWITCH_MEAN
    else if (my < MEAN_MAX) { // CASE A: acceptance complement
      // static double my_last = -1.0;
      // static long int m, k2, k4, k1, k5;
      // static double dl, dr, r1, r2, r4, r5, ll, lr, l_my, c_pm,
      // f1, f2, f4, f5, p1, p2, p3, p4, p5, p6;
      int Dk, X, Y;
      double Ds, U, V, W;

      m = (int) my;
      if (my != my_last) { // set-up
        my_last = my;

        // approximate deviation of reflection points k2, k4 from my - 1/2
        Ds = Math.sqrt(my + 0.25);

        // mode m, reflection points k2 and k4, and points k1 and k5, which
        // delimit the centre region of h(x)
        k2 = (int) Math.ceil(my - 0.5 - Ds);
        k4 = (int) (my - 0.5 + Ds);
        k1 = k2 + k2 - m + 1;
        k5 = k4 + k4 - m;

        // range width of the critical left and right centre region
        dl = (double) (k2 - k1);
        dr = (double) (k5 - k4);

        // recurrence constants r(k) = p(k)/p(k-1) at k = k1, k2, k4+1, k5+1
        r1 = my / (double) k1;
        r2 = my / (double) k2;
        r4 = my / (double) (k4 + 1);
        r5 = my / (double) (k5 + 1);

        // reciprocal values of the scale parameters of expon. tail envelopes
        ll = Math.log(r1); // expon. tail left
        lr = -Math.log(r5); // expon. tail right

        // Poisson constants, necessary for computing function values f(k)
        l_my = Math.log(my);
        c_pm = m * l_my - Arithmetic.logFactorial(m);

        // function values f(k) = p(k)/p(m) at k = k2, k4, k1, k5
        f2 = f(k2, l_my, c_pm);
        f4 = f(k4, l_my, c_pm);
        f1 = f(k1, l_my, c_pm);
        f5 = f(k5, l_my, c_pm);

        // area of the two centre and the two exponential tail regions
        // area of the two immediate acceptance regions between k2, k4
        p1 = f2 * (dl + 1.0); // immed. left
        p2 = f2 * dl + p1; // centre left
        p3 = f4 * (dr + 1.0) + p2; // immed. right
        p4 = f4 * dr + p3; // centre right
        p5 = f1 / ll + p4; // expon. tail left
        p6 = f5 / lr + p5; // expon. tail right
      } // end set-up

      for (; ; ) {
        // generate uniform number U -- U(0, p6)
        // case distinction corresponding to U
        if ((U = random.nextDouble() * p6) < p2) { // centre left

          // immediate acceptance region R2 = [k2, m) *[0, f2), X = k2, ... m -1
          if ((V = U - p1) < 0.0) return (k2 + (int) (U / f2));
          // immediate acceptance region R1 = [k1, k2)*[0, f1), X = k1, ... k2-1
          if ((W = V / dl) < f1) return (k1 + (int) (V / f1));

          // computation of candidate X < k2, and its counterpart Y > k2
          // either squeeze-acceptance of X or acceptance-rejection of Y
          Dk = (int) (dl * random.nextDouble()) + 1;
          if (W <= f2 - Dk * (f2 - f2 / r2)) { // quick accept of
            return (k2 - Dk); // X = k2 - Dk
          }
          if ((V = f2 + f2 - W) < 1.0) { // quick reject of Y
            Y = k2 + Dk;
            if (V <= f2 + Dk * (1.0 - f2) / (dl + 1.0)) { // quick accept of
              return (Y); // Y = k2 + Dk
            }
            if (V <= f(Y, l_my, c_pm)) return (Y); // final accept of Y
          }
          X = k2 - Dk;
        } else if (U < p4) { // centre right
          // immediate acceptance region R3 = [m, k4+1)*[0, f4), X = m, ... k4
          if ((V = U - p3) < 0.0) return (k4 - (int) ((U - p2) / f4));
          // immediate acceptance region R4 = [k4+1, k5+1)*[0, f5)
          if ((W = V / dr) < f5) return (k5 - (int) (V / f5));

          // computation of candidate X > k4, and its counterpart Y < k4
          // either squeeze-acceptance of X or acceptance-rejection of Y
          Dk = (int) (dr * random.nextDouble()) + 1;
          if (W <= f4 - Dk * (f4 - f4 * r4)) { // quick accept of
            return (k4 + Dk); // X = k4 + Dk
          }
          if ((V = f4 + f4 - W) < 1.0) { // quick reject of Y
            Y = k4 - Dk;
            if (V <= f4 + Dk * (1.0 - f4) / dr) { // quick accept of
              return (Y); // Y = k4 - Dk
            }
            if (V <= f(Y, l_my, c_pm)) return (Y); // final accept of Y
          }
          X = k4 + Dk;
        } else {
          W = random.nextDouble();
          if (U < p5) { // expon. tail left
            Dk = (int) (1.0 - Math.log(W) / ll);
            if ((X = k1 - Dk) < 0) continue; // 0 <= X <= k1 - 1
            W *= (U - p4) * ll; // W -- U(0, h(x))
            if (W <= f1 - Dk * (f1 - f1 / r1)) return (X); // quick accept of X
          } else { // expon. tail right
            Dk = (int) (1.0 - Math.log(W) / lr);
            X = k5 + Dk; // X >= k5 + 1
            W *= (U - p5) * lr; // W -- U(0, h(x))
            if (W <= f5 - Dk * (f5 - f5 * r5)) return (X); // quick accept of X
          }
        }

        // acceptance-rejection test of candidate X from the original area
        // test, whether W <= f(k), with W = U*h(x) and U -- U(0, 1)
        // log f(X) = (X - m)*log(my) - log X! + log m!
        if (Math.log(W) <= X * l_my - Arithmetic.logFactorial(X) - c_pm) return (X);
      }
    } else { // mean is too large
      return (int) my;
    }
  }
Beispiel #3
0
 private static double f(int k, double l_nu, double c_pm) {
   return Math.exp(k * l_nu - Arithmetic.logFactorial(k) - c_pm);
 }