python求积分面积的几个方法

示例

已知积分公式如下

求[0.5,5]上积分,即求下图阴影部分面积

根据积分公式求源函数等于:

则确切解等与F(5)-F(0.5)=3.9002072872864524

当不知道源函数时使用以下方法可以求得积分面积

首先定义函数

def func(x):
  
    return np.cos(np.pi) * np.exp(-x) + 1

1、通过迭代计算每个步长矩形面积求和

    x = np.linspace(0.5, 5, 1000)
    dx = (5-0.5)/1000
    y = func(x)
    area = np.sum(y * dx)

结果等于:3.8994262124710404

2、通过scipy模块quad直接求积分

area, error = quad(func, 0.5, 5)

quad的结果是 3.9002072872864515

3、使用蒙特卡洛模拟估算积分面积

原理是已知区间【0.5,5】上矩形面积,在矩形范围内随机打点,统计在阴影部分点的占比,从而估算出阴影部分面积。

    k = 0
    for i in range(N):
        r_x = np.random.uniform(low=0.5, high=5, size=1)
        r_y = np.random.uniform(low=0, high=1, size=1)
        c_v = func(r_x)
        if r_y <= c_v:
            k += 1
    area = k / N * 4.5

蒙特卡洛的结果是 3.9393
 

所有代码如下

# @Time : 2020/8/26
# @Author : 大太阳小白
# @Software: PyCharm
# @blog:https://blog.csdn.net/weixin_41579863

import numpy as np
from scipy.integrate import quad
from matplotlib import pyplot as plt


def func(x):

    return np.cos(np.pi) * np.exp(-x) + 1


def drawing_question(fig):
    x = np.linspace(0, 6, 1000)
    y = func(x)
    fig = plt.figure()
    ax1 = fig.add_subplot()
    ax1.axis([np.min(x), np.max(x), 0, np.max(y)])  # 坐标范围
    ax1.plot(x, y, label="$cos(π)e^{-x}+1$")  # 画曲线,带图示
    ax1.fill_between(x, y1=y, y2=0, where=(x >= 0.5) & (x <= 5),  # 填充积分区域
                     facecolor='blue', alpha=0.2)
    ax1.text(0.5 * (0.7 + 4), 0.4, r"$\int_{0.5}^5(cos(π)e^{-x}+1)\mathrm{d}x$",
             horizontalalignment='center', fontsize=14)  # 增加说明文本
    ax1.legend()  # 显示图示
    plt.show()


def area_sum():
    x = np.linspace(0.5, 5, 1000)
    dx = (5-0.5)/1000
    y = func(x)
    area = np.sum(y * dx)
    return area


def area_quad():
    area, error = quad(func, 0.5, 5)
    return area


def montecarlo(N=5000):
    k = 0
    for i in range(N):
        r_x = np.random.uniform(low=0.5, high=5, size=1)
        r_y = np.random.uniform(low=0, high=1, size=1)
        c_v = func(r_x)
        if r_y <= c_v:
            k += 1
    area = k / N * 4.5
    return area


def montecarlo_show(N=5000):
    k = 0
    x0 = []
    x1 = []
    for i in range(N):
        r_x = np.random.uniform(low=0.5, high=5, size=1)
        r_y = np.random.uniform(low=0, high=1, size=1)
        c_v = func(r_x)
        if r_y <= c_v:
            k += 1
            x0.append([r_x, r_y])
        else:
            x1.append([r_x, r_y])
    x = np.linspace(0, 6, 1000)
    y = func(x)
    x0 = np.array(x0)
    x1 = np.array(x1)
    fig = plt.figure()
    ax1 = fig.add_subplot()
    ax1.axis([np.min(x), np.max(x), 0, np.max(y)])
    ax1.plot(x, y, label="$cos(π)e^{-x}+1$")
    ax1.scatter(x0[:, 0], x0[:, 1])
    ax1.scatter(x1[:, 0], x1[:, 1])
    ax1.fill_between(x, y1=y, y2=0, where=(x >= 0.5) & (x <= 5),
                     facecolor='blue', alpha=0.2)
    ax1.text(0.5 * (0.7 + 4), 0.4, r"$\int_{0.5}^5(cos(π)e^{-x}+1)\mathrm{d}x$",
             horizontalalignment='center', fontsize=14)  # 增加说明文本
    ax1.legend()  # 显示图示
    plt.show()


if __name__ == '__main__':
    # drawing_question()
    original = lambda x: np.exp(-x) + x
    print('期望值是:', original(5)-original(0.5))
    print('基于矩形面积求和的结果是', area_sum())
    print('quad的结果是', area_quad())
    print('蒙特卡洛的结果是', montecarlo())
    montecarlo_show(N=500)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值