/**
   * Calculates {@code P(D_n < d)} using method described in [1] and doubles (see above).
   *
   * @param d statistic
   * @return the two-sided probability of {@code P(D_n < d)}
   * @throws MathArithmeticException if algorithm fails to convert {@code h} to a {@link
   *     org.apache.commons.math3.fraction.BigFraction} in expressing {@code d} as {@code (k - h) /
   *     m} for integer {@code k, m} and {@code 0 <= h < 1}.
   */
  private double roundedK(double d) throws MathArithmeticException {

    final int k = (int) FastMath.ceil(n * d);
    final FieldMatrix<BigFraction> HBigFraction = this.createH(d);
    final int m = HBigFraction.getRowDimension();

    /*
     * Here the rounding part comes into play: use
     * RealMatrix instead of FieldMatrix<BigFraction>
     */
    final RealMatrix H = new Array2DRowRealMatrix(m, m);

    for (int i = 0; i < m; ++i) {
      for (int j = 0; j < m; ++j) {
        H.setEntry(i, j, HBigFraction.getEntry(i, j).doubleValue());
      }
    }

    final RealMatrix Hpower = H.power(n);

    double pFrac = Hpower.getEntry(k - 1, k - 1);

    for (int i = 1; i <= n; ++i) {
      pFrac *= (double) i / (double) n;
    }

    return pFrac;
  }
 /*  24:    */
 /*  25:    */ private AdamsNordsieckTransformer(int nSteps) /*  26:    */ {
   /*  27:154 */ FieldMatrix<BigFraction> bigP = buildP(nSteps);
   /*  28:155 */ FieldDecompositionSolver<BigFraction> pSolver =
       new FieldLUDecomposition(bigP).getSolver();
   /*  29:    */
   /*  30:    */
   /*  31:158 */ BigFraction[] u = new BigFraction[nSteps];
   /*  32:159 */ Arrays.fill(u, BigFraction.ONE);
   /*  33:160 */ BigFraction[] bigC1 =
       (BigFraction[]) pSolver.solve(new ArrayFieldVector(u, false)).toArray();
   /*  34:    */
   /*  35:    */
   /*  36:    */
   /*  37:    */
   /*  38:    */
   /*  39:166 */ BigFraction[][] shiftedP = (BigFraction[][]) bigP.getData();
   /*  40:167 */ for (int i = shiftedP.length - 1; i > 0; i--) {
     /*  41:169 */ shiftedP[i] = shiftedP[(i - 1)];
     /*  42:    */ }
   /*  43:171 */ shiftedP[0] = new BigFraction[nSteps];
   /*  44:172 */ Arrays.fill(shiftedP[0], BigFraction.ZERO);
   /*  45:173 */ FieldMatrix<BigFraction> bigMSupdate =
       pSolver.solve(new Array2DRowFieldMatrix(shiftedP, false));
   /*  46:    */
   /*  47:    */
   /*  48:    */
   /*  49:177 */ this.update = MatrixUtils.bigFractionMatrixToRealMatrix(bigMSupdate);
   /*  50:178 */ this.c1 = new double[nSteps];
   /*  51:179 */ for (int i = 0; i < nSteps; i++) {
     /*  52:180 */ this.c1[i] = bigC1[i].doubleValue();
     /*  53:    */ }
   /*  54:    */ }
  /**
   * Calculates the exact value of {@code P(D_n < d)} using method described in [1] and {@link
   * org.apache.commons.math3.fraction.BigFraction} (see above).
   *
   * @param d statistic
   * @return the two-sided probability of {@code P(D_n < d)}
   * @throws MathArithmeticException if algorithm fails to convert {@code h} to a {@link
   *     org.apache.commons.math3.fraction.BigFraction} in expressing {@code d} as {@code (k - h) /
   *     m} for integer {@code k, m} and {@code 0 <= h < 1}.
   */
  private double exactK(double d) throws MathArithmeticException {

    final int k = (int) FastMath.ceil(n * d);

    final FieldMatrix<BigFraction> H = this.createH(d);
    final FieldMatrix<BigFraction> Hpower = H.power(n);

    BigFraction pFrac = Hpower.getEntry(k - 1, k - 1);

    for (int i = 1; i <= n; ++i) {
      pFrac = pFrac.multiply(i).divide(n);
    }

    /*
     * BigFraction.doubleValue converts numerator to double and the
     * denominator to double and divides afterwards. That gives NaN quite
     * easy. This does not (scale is the number of digits):
     */
    return pFrac.bigDecimalValue(20, BigDecimal.ROUND_HALF_UP).doubleValue();
  }