@Override
 public void nextIteration() {
   double[] beta = getBestValuesEver();
   for (int i = 0; i < beta.length; i++) {
     double minBound = getMin(i);
     double maxBound = getMax(i);
     if (beta[i] == minBound) {
       minBound -= 1;
       setMin(i, minBound);
       logging.log("decrease lower bound for beta(" + i + ") to + " + minBound);
     }
     if (beta[i] == maxBound) {
       maxBound += 1;
       setMax(i, maxBound);
       logging.log("increase upper bound for beta(" + i + ") to + " + maxBound);
     }
   }
 }
  private double[] estimateVariance() {
    double[] beta = getBestValuesEver();

    Matrix hessian = new Matrix(beta.length, beta.length);
    for (Example example : exampleSet) {
      double[] values = new double[beta.length];
      double eta = 0.0d;
      int j = 0;
      for (Attribute attribute : example.getAttributes()) {
        double value = example.getValue(attribute);
        values[j] = value;
        eta += beta[j] * value;
        j++;
      }
      if (addIntercept) {
        values[beta.length - 1] = 1.0d;
        eta += beta[beta.length - 1];
      }
      double pi = Math.exp(eta) / (1 + Math.exp(eta));

      double weightValue = 1.0d;
      if (weight != null) weightValue = example.getValue(weight);
      for (int x = 0; x < beta.length; x++) {
        for (int y = 0; y < beta.length; y++) {
          // sum is second derivative of log likelihood function
          double h = hessian.get(x, y) - values[x] * values[y] * weightValue * pi * (1 - pi);
          hessian.set(x, y, h);
        }
      }
    }

    double[] variance = new double[beta.length];
    Matrix varianceCovarianceMatrix = null;
    try {
      // asymptotic variance-covariance matrix is inverse of hessian matrix
      varianceCovarianceMatrix = hessian.inverse();
    } catch (Exception e) {
      logging.logWarning("could not determine variance-covariance matrix, hessian is singular");
      for (int j = 0; j < beta.length; j++) {
        variance[j] = Double.NaN;
      }
      return variance;
    }
    for (int j = 0; j < beta.length; j++) {
      // get diagonal elements
      variance[j] = Math.abs(varianceCovarianceMatrix.get(j, j));
    }

    return variance;
  }