@Test
  public void sample() {
    for (double p : new double[] {0.1, 0.2, 0.5, 0.9}) {
      for (int r = 1; r < 5; r++) {
        NegativeBinomial nb = new NegativeBinomial(r, p, new MersenneTwister(1));
        int[] counts = new int[N];
        for (int i = 0; i < N; i++) {
          int k = nb.nextInt();
          if (k < counts.length) {
            counts[k]++;
          }
        }

        // probably should do a chi^2 or LLR test here especially since we know the PDF
        for (int k = 0; k < counts.length; k++) {
          Assert.assertEquals(
              String.format(
                  Locale.ENGLISH,
                  "r=%d,p=%.3f,k=%d,count=%d,pdf=%.3f",
                  r,
                  p,
                  k,
                  counts[k],
                  nb.pdf(k)),
              N * nb.pdf(k),
              counts[k],
              Math.max(3, 4 * Math.sqrt(N * nb.pdf(k) * (1 - nb.pdf(k)))));
        }
      }
    }
  }
 @Test
 public void testDistributionFunctions() throws IOException {
   InputSupplier<InputStreamReader> input =
       Resources.newReaderSupplier(
           Resources.getResource("negative-binomial-test-data.csv"), Charsets.UTF_8);
   boolean header = true;
   for (String line : CharStreams.readLines(input)) {
     if (header) {
       // skip
       header = false;
     } else {
       Iterable<String> values = onComma.split(line);
       int k = Integer.parseInt(Iterables.get(values, 0));
       double p = Double.parseDouble(Iterables.get(values, 1));
       int r = Integer.parseInt(Iterables.get(values, 2));
       double density = Double.parseDouble(Iterables.get(values, 3));
       double cume = Double.parseDouble(Iterables.get(values, 4));
       NegativeBinomial nb = new NegativeBinomial(r, p, new MersenneTwister());
       Assert.assertEquals("cumulative " + k + ',' + p + ',' + r, cume, nb.cdf(k), cume * 1e-05);
       Assert.assertEquals(
           "density " + k + ',' + p + ',' + r, density, nb.pdf(k), density * 1e-05);
     }
   }
 }