I have implemented a function to find the trapezoid rule of a given function, the function produces poor results for
.
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++) {