/**
   * Estimates the mean of array <code>y</code>. <code>robustMu</code> uses a Gaussian model to
   * remove outliers iteratively.
   *
   * @param y an array
   * @return the estimated mean of <code>y</code>
   */
  private double robustMu(double[] y) {

    ArrayList<Double> x = new ArrayList<Double>(y.length);

    for (int i = 0; i < y.length; i++) {
      x.add(y[i]);
    }

    double sigma = 0;
    NormalDist gaussian = new NormalDist();
    double cutoff = 0;
    double cutoff1 = 0;
    double cutoff2 = 0;

    int xSize = x.size();

    sigma = std(x);
    double areaRemoved = 0.5 / xSize;

    cutoff = abs(gaussian.inverseF(areaRemoved));

    cutoff1 = -cutoff * sigma + mean(x);
    cutoff2 = cutoff * sigma + mean(x);

    while (true) {

      Iterator<Double> iter = x.iterator();

      int numRemoved = 0;
      while (iter.hasNext()) {

        double cn = iter.next();
        if (cn < cutoff1 || cn > cutoff2) {
          numRemoved++;
          iter.remove();
        }
      }

      if (numRemoved == 0) {
        break;
      }

      sigma = std(x);
      sigma =
          sigma
              / sqrt(
                  (1 - 2 * areaRemoved - 2 * cutoff * exp(-pow(cutoff, 2) / 2) / sqrt(2 * PI))
                      / (1 - 2 * areaRemoved));

      xSize = x.size();
      areaRemoved = 0.5 / xSize;

      cutoff = abs(gaussian.inverseF(areaRemoved));

      cutoff1 = -cutoff * sigma + mean(x);
      cutoff2 = cutoff * sigma + mean(x);
    }

    return mean(x);
  }