Skip to content
Advertisement

Why is my trapezoid rule implementation not producing expected results?

I have implemented a function to find the trapezoid rule of a given function, the function produces poor results for

log _{2}(x).

When I try to calculate the trapezoid rule with n < 8 it produces a value much larger than the actual area, which is unexpected, I have graphed f(x) and drawn how I believe the first few numbers of trapezoids would look, and they all should be producing less than the target area.

However, as n increases, the error becomes lower and lower and at n = 10000000 it is within a 0.001 of the solution.

  private interface MathFunc {
    double apply(double value);
  }
  private static final double A = 1;
  private static final double B = 9;
  public static void main(String args[]) {
    MathFunc func = (x) -> Math.log(x) / Math.log(2);
    double realValue = 16.98776493946568;
    for(int i = 1; i <= 8; i*=2) {
      double value = trapezoidRule(A, B, func, i);
      System.out.println(i + " Trapezoid Summation for f(x): " + value);
      double absError = Math.abs(value - realValue);
      System.out.println("Abs Error: " + absError);
      System.out.println("% Error: " + (absError/realValue)*100);
      System.out.println();
    }
  }
  static double trapezoidRule(double a, double b, MathFunc f, double n) {
    double deltaX = (b-a)/n;
    double i = 0;
    double sum = 0.0;
    while( i++ <= n ) {
      if(i == 0 || i == n) {
        sum += f.apply(a + (i*deltaX));
      } else {
        sum += 2 * f.apply(a + (i*deltaX));
      }
    }
    return (deltaX * sum) / 2.0;
  }

Advertisement

Answer

If you step through trapezoidRule for n = 1 in a debugger, you’ll see that the loop is executed for i=1 and i=2. Since i=2 is treated as a midpoint, it is counted twice.

Why is the loop executed for wrong values of i? The expression i++ uses the post-increment operator, which increments the variable after returning its value. You should be using a pre-increment operator ++i, or a for loop like any sane person:

for (double i = 0; i <= n; i++) {
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement