class IntegralLimitCalculator {

  public double solve(final Function1D<ComplexNumber, ComplexNumber> psi, final double alpha, final double tol) {
    Validate.notNull(psi, "psi null");
    Validate.isTrue(alpha != 0.0 && alpha != -1.0, "alpha cannot be -1 or 0");
    Validate.isTrue(tol > 0.0, "need tol > 0");

    final double k = Math.log(tol) + Math.log(ComplexMathUtils.mod(psi.evaluate(new ComplexNumber(0.0, -(1 + alpha)))));
    final Function1D<Double, Double> f = new Function1D<Double, Double>() {
      @Override
      public Double evaluate(final Double x) {
        final ComplexNumber z = new ComplexNumber(x, -(1 + alpha));
        return Math.log(ComplexMathUtils.mod(psi.evaluate(z))) - k;
      }
    };
    double[] range = null;
    try {
      range = s_bracketRoot.getBracketedPoints(f, 0.0, 200.0);
    } catch (MathException e) {
      s_log.warn("Could not find integral limit. Using default of 500");
      return 500.0;
    }
    return s_root.getRoot(f, range[0], range[1]);
  }

}