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;
}
CodePudding user response:
while( i <= n )
Was causing an issue, as it was doing an extra iteration.
while( i < n )
Produces the correct values.
CodePudding user response:
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 ) {