Integrate a function by the trapezoidal rule- Python

时光毁灭记忆、已成空白 提交于 2021-02-07 11:07:21

问题


Here is the homework assignment I'm trying to solve:

A further improvement of the approximate integration method from the last question is to divide the area under the f(x) curve into n equally-spaced trapezoids.

Based on this idea, the following formula can be derived for approximating the integral:

!(https://www.dropbox.com/s/q84mx8r5ml1q7n1/Screenshot%202017-10-01%2016.09.32.png?dl=0)!

where h is the width of the trapezoids, h=(b−a)/n, and xi=a+ih,i∈0,...,n, are the coordinates of the sides of the trapezoids. The figure above visualizes the idea of the trapezoidal rule.

Implement this formula in a Python function trapezint( f,a,b,n ). You may need to check and see if b > a, otherwise you may need to swap the variables.

For instance, the result of trapezint( math.sin,0,0.5*math.pi,10 ) should be 0.9979 (with some numerical error). The result of trapezint( abs,-1,1,10 ) should be 2.0

This is my code but It doesn't seem to return the right values.
For print ((trapezint( math.sin,0,0.5*math.pi,10)))
I get 0.012286334153465965, when I am suppose to get 0.9979
For print (trapezint(abs, -1, 1, 10))
I get 0.18000000000000002, when I am suppose to get 1.0.

import math
def trapezint(f,a,b,n):

    g = 0
    if b>a:
        h = (b-a)/float(n)
        for i in range (0,n):
            k = 0.5*h*(f(a+i*h) + f(a + (i+1)*h))
            g = g + k
            return g
    else:
        a,b=b,a
        h = (b-a)/float(n)
        for i in range(0,n):
            k = 0.5*h*(f(a + i*h) + f(a + (i + 1)*h))
            g = g + k
            return g

print ((trapezint( math.sin,0,0.5*math.pi,10)))
print (trapezint(abs, -1, 1, 10))

回答1:


Essentially, your return g statement was indented, when it should not have been.

Also, I removed your duplicated code, so it would adhere to "DRY" "Don't Repeat Yourself" principle, which prevents errors, and keeps code simplified and more readable.

import math
def trapezint(f, a, b, n):

    g = 0
    if b > a:
        h = (b-a)/float(n)
    else:
        h = (a-b)/float(n)

    for i in range (0, n):
        k = 0.5 * h * ( f(a + i*h) + f(a + (i+1)*h) )
        g = g + k

    return g


print ( trapezint( math.sin, 0, 0.5*math.pi, 10) )
print ( trapezint(abs, -1, 1, 10) )

0.9979429863543573
1.0000000000000002




回答2:


This variation reduces the complexity of branches and reduces number of operations. The summation in last step is reduced to single operation on an array.

from math import pi, sin
def trapezoid(f, a, b, n):
    if b < a:
        a,b = b, a
    h = (b - a)/float(n)
    g = [(0.5 * h * (f(a + (i * h)) + f(a  + ((i + 1) * h)))) for i in range(0, n)]
    return sum(g)

assert trapezoid(sin, 0, 0.5*pi, 10) == 0.9979429863543573
assert trapezoid(abs, -1, 1, 10) == 1.0000000000000002


来源:https://stackoverflow.com/questions/46516967/integrate-a-function-by-the-trapezoidal-rule-python

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!