public void stepUntil(final StoppingCriterion stoppingCriterion) throws IOException {
    super.stepUntil(stoppingCriterion);

    for (int i = 0; i < order.length; i++) {
      if (iterationNumber < order[i] / (1 - alpha))
        LOGGER.info(
            "Error bound for derivative of order " + order[i] + " (alpha=" + alpha + "): unknown");
      else {
        final int k = order[i];
        final double delta = alpha * iterationNumber / (iterationNumber + k);
        final double alphak = Math.pow(alpha, k);
        final double nFallingK = Util.falling(iterationNumber, k);
        double infinityNorm = 0;
        for (int j = 0; j < numNodes; j++)
          infinityNorm = Math.max(infinityNorm, nFallingK * (rank[j] - previousRank[j]) / alphak);

        LOGGER.info(
            "Error bound for derivative of order "
                + k
                + " (alpha="
                + alpha
                + "): "
                + infinityNorm * delta / (1 - delta));
      }
    }
  }
  public void init() throws IOException {
    super.init();
    if (start != null && (coeffBasename != null || order.length > 0))
      throw new IllegalArgumentException(
          "You cannot choose a preference vector when computing coefficients or derivatives");
    // Creates the arrays, if necessary
    if (previousRank == null) previousRank = new double[numNodes];
    derivative = new double[order.length][subset != null ? subset.length : g.numNodes()];
    if (IntArrayList.wrap(order).indexOf(0) != -1)
      throw new IllegalArgumentException(
          "You cannot compute the derivative of order 0 (use PageRank instead)");
    if (coeffBasename != null) BinIO.storeDoubles(rank, coeffBasename + "-" + 0);

    logger.info("Completed.");
  }
 public void clear() {
   super.clear();
   previousRank = null;
 }