Hybr1d Hybr1d - 4 years ago 630
Python Question

Integration with Riemann Sum Python

I have been trying to solve integration with riemann sum. My function has 3 arguments a,b,d so a is lower limit b is higher limit and d is the part where

a +(n-1)*d < b
. This is my code so far but. My output is
28.652667999999572
what I should get is
28.666650000000388
. Also if the input b is lower than a it has to calculate but I have solved that problem already.

def integral(a, b, d):
if a > b:
a,b = b,a
delta_x = float((b-a)/1000)
j = abs((b-a)/delta_x)
i = int(j)
n = s = 0
x = a
while n < i:
delta_A = (x**2+3*x+4) * delta_x
x += delta_x
s += delta_A

n += 1

return abs(s)

print(integral(1,3,0.01))

Answer Source

There is no fault here, neither with the algorithm nor with your code (or python). The Riemann sum is an approximation of the integral and per se not "exact". You approximate the area of a (small) stripe of width dx, say between x and x+dx, and f(x) with the area of an rectangle of the same width and the height of f(x) as it's left upper corner. If the function changes it's value when you go from x to x+dx then the area of the rectangle deviates from the true integral.
As you have noticed, you can make the approximation closer by making thinner and thinner slices, at the cost of more computational effort and time. In your example, the function is f(x) = x^2 + 3*x + 4, and it's exact integral over x in [1.0,3.0) is 28 2/3 or 28.66666...

The approximation by rectangles is a crude one, you cannot change that. But what you could change is the time it takes for your code to evaluate, say, 10^8 steps instead of 10^3. Look at this code:

def riemann(a, b, dx):
    if a > b:
        a,b = b,a
    # dx = (b-a)/n
    n = int((b - a) / dx)
    s = 0.0
    x = a
    for i in xrange(n):
        f_i = (x + 3.0) * x + 4.0
        s += f_i
        x += dx
    return s * dx  

Here, I've used 3 tricks for speedup, and one for greater precision. First, if you write a loop and you know the number of repetions in advance then use a for-loop instead of a while-loop. It's faster. (BTW, loop variables conventionally are i, j, k ... whereas a limit or final value is n). Secondly, using xrange instead of range is faster for users of python 2.x. Thirdly, factorize polynoms when calculating them often. You should see from the code what I mean here. This way, the result is numerically stable. Last trick: operations within the loop which do not depend on the loop variable can be extracted and applied after the loop has ended. Here, the final multiplication with dx.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download