/**
   * Returns the integral of 1/N(x) between t and g+t, calling either the getAnalyticalIntegral or
   * getNumericalIntegral function as appropriate.
   */
  private double getIntegral(double g, double t) {

    if (g == 0.0) {
      // integral value equals 0 if g=0
      return 0.0;
    }

    if (demographicFunction.hasIntegral()) {
      // Calculate integral analytically
      return demographicFunction.getIntegral(t, t + g);
    } else {
      // Calculate integral numerically
      return getNumericalIntegral(t, t + g);
    }
  }
  /** Performs the trapezoid rule. */
  private double doTrapezoid(int n, double low, double high, double lastS) {

    double s;

    if (n == 1) {
      // On the first iteration s is reset
      double demoLow = demographicFunction.getDemographic(low); // Value of N(x) obtained here
      assert (demoLow > 0.0);

      double demoHigh = demographicFunction.getDemographic(high);
      assert (demoHigh > 0.0);

      s = 0.5 * (high - low) * ((1.0 / demoLow) + (1.0 / demoHigh));
    } else {
      int it = 1;
      for (int j = 1; j < n - 1; j++) {
        it *= 2;
      }

      double tnm = it; // number of points
      double del = (high - low) / tnm; // width of spacing between points

      double x = low + 0.5 * del;

      double sum = 0.0;
      for (int j = 1; j <= it; j++) {
        double demoX = demographicFunction.getDemographic(x); // Value of N(x) obtained here
        assert (demoX > 0.0);

        sum += (1.0 / demoX);
        x += del;
      }
      s = 0.5 * (lastS + (high - low) * sum / tnm); // New s uses previous s value
    }

    return s;
  }