The [trapezoidal rule][1] has a big `/2` fraction (each term is `(f(i) + f(i+1))/2`, not `f(i) + f(i+1))`, which you've left out of your code.
You've used the common optimization that treats the first and last pair specially so you can use `2 * f(i)` instead of calculating `f(i)` twice (once as `f(j+1)` and once as `f(i))`, so you have to add the `/ 2` to the loop step and to the special first and last steps:
s += h * f(a) / 2.0
for i in range(1, n):
s += 2.0 * h * f(a + i*h) / 2.0
s += h * f(b) / 2.0
You can obviously simplify the loop step by replacing the `2.0 * … / 2.0` with just ….
However, even more simply, you can just divide the whole thing by 2 at the end, changing nothing but this line:
return s / 2.0
[1]: https://en.wikipedia.org/wiki/Trapezoidal_rule
The [trapezoidal rule](http://en.wikipedia.org/wiki/Trapezoidal_rule) has a big `/2` fraction (each term is `(f(i) + f(i+1))/2`, not `f(i) + f(i+1)`), which you've left out of your code.
You've used the common optimization that treats the first and last pair specially so you can use `2 * f(i)` instead of calculating `f(i)` twice (once as `f(j+1)` and once as `f(i)`), so you have to add the `/ 2` to the loop step and to the special first and last steps:
s += h * f(a) / 2.0
for i in range(1, n):
s += 2.0 * h * f(a + i*h) / 2.0
s += h * f(b) / 2.0
You can obviously simplify the loop step by replacing the `2.0 * … / 2.0` with just `…`.
However, even more simply, you can just divide the whole thing by 2 at the end, changing nothing but this line:
return s / 2.0