python求和函数从1到m_python 微积分之---黎曼和

黎曼求和

这里有一块形状不规则的土地,要测量它的面积,怎么办呢?一个叫黎曼的德国数学家(Bernhard Riemann, 1826-1866),他想了个办法:将这不规则图形切成一条条的小长条儿,然后将这个长条近似的看成一个矩形,再分别测量出这些小矩形的长度,再计算出它们的面积,把所有矩型面积加起来就是这块不规则地的面积。这就是著名的“黎曼和”。小长条宽度趋于0时,即为面积微分,各个面积求和取极限即为定积分。虽然牛顿时代就给出了定积分的定义,但是定积分的现代数学定义却是用黎曼和的极限给出。

定义

对一个在闭区间有定义的实值函数,关于取样分割、的黎曼和定义为以下和式:

和式中的每一项是子区间长度与在处的函数值的乘积。直观地说,就是以标记点到X轴的距离为高,以分割的子区间为长的矩形的面积。

函数

在分区上:

求和:

每个值在

$ 中每个子间隔中是任意的。

黎曼和很重要,因为提供了一种简便的方法来逼近定积分:

请注意,每个i的乘积$f(x_i^ * ) (x_i - x_{i-1})$是高度为$f(x_i^ * )$且宽度为$x_i - x_{i-1}$的矩形的面积。 我们可以将黎曼和视为N个矩形的面积,其高度由$x_i - x_{i-1}$来确定。

$x_i^$在每个子间隔中选择的是任意的,但是有一些明显的选择: 左黎曼和是指每个$x_i^= x_{i-1}$是子区间$[x_{i-1},x_i]$的左端点 右黎曼和是指每个$xi^= xi$是子区间$[xi-1,xi]$的右端点 中点黎曼和是每个$xi^* =(xi-1 + xi)/ 2$是子区间$[xi-1,xi]$的中点

通过以下举例函数,用Python可视化左、右、中黎曼和: $$f(x) = \frac{1}{1 + x^2}$$ 在间隔$[0,5]$上,分区大小为$N = 10$。

import numpy as np

import matplotlib.pyplot as plt

%matplotlib inline

f = lambda x : 1/(1+x**2)

a = 0; b = 5; N = 10

n = 10 # Use n*N+1 points to plot the function smoothly

x = np.linspace(a,b,N+1)

y = f(x)

X = np.linspace(a,b,n*N+1)

Y = f(X)

plt.figure(figsize=(15,5))

plt.subplot(1,3,1)

plt.plot(X,Y,'b')

x_left = x[:-1] # Left endpoints

y_left = y[:-1]

plt.plot(x_left,y_left,'b.',markersize=10)

plt.bar(x_left,y_left,width=(b-a)/N,alpha=0.2,align='edge',edgecolor='b')

plt.title('Left Riemann Sum, N = {}'.format(N))

plt.subplot(1,3,2)

plt.plot(X,Y,'b')

x_mid = (x[:-1] + x[1:])/2 # Midpoints

y_mid = f(x_mid)

plt.plot(x_mid,y_mid,'b.',markersize=10)

plt.bar(x_mid,y_mid,width=(b-a)/N,alpha=0.2,edgecolor='b')

plt.title('Midpoint Riemann Sum, N = {}'.format(N))

plt.subplot(1,3,3)

plt.plot(X,Y,'b')

x_right = x[1:] # Left endpoints

y_right = y[1:]

plt.plot(x_right,y_right,'b.',markersize=10)

plt.bar(x_right,y_right,width=-(b-a)/N,alpha=0.2,align='edge',edgecolor='b')

plt.title('Right Riemann Sum, N = {}'.format(N))

plt.show()

$$f(x)[a,b]\int_a^b f(x) dx$$ 让我们计算每个黎曼和的值:

dx = (b-a)/N

x_left = np.linspace(a,b-dx,N)

x_midpoint = np.linspace(dx/2,b - dx/2,N)

x_right = np.linspace(dx,b,N)

print("按划分为",N,"个子区间计算:")

left_riemann_sum = np.sum(f(x_left) * dx)

print("左黎曼和:",left_riemann_sum)

midpoint_riemann_sum = np.sum(f(x_midpoint) * dx)

print("中点黎曼和:",midpoint_riemann_sum)

right_riemann_sum = np.sum(f(x_right) * dx)

print("右黎曼和:",right_riemann_sum)

按划分为 10 个子区间计算:

左黎曼和: 1.613488696614725

中点黎曼和: 1.373543428316664

右黎曼和: 1.1327194658454942

实际上$\int_0^5 \frac{1}{1 + x^2} dx = \arctan(5)$

I = np.arctan(5)

print(I)

1.373400766945016

print("左黎曼和误差:",np.abs(left_riemann_sum - I))

print("中点黎曼和:",np.abs(midpoint_riemann_sum - I))

print("右黎曼和误差:",np.abs(right_riemann_sum - I))

左黎曼和误差: 0.24008792966970915

中点黎曼和: 0.00014266137164820059

右黎曼和误差: 0.24068130109952168

误差分析:

左黎曼和误差分析: $$L_N(f) = \sum_{i=1}^N f(x_{i-1} ) \Delta x$$ 其中:$\Delta x = (b-a)/N$,$x_i = a + i \Delta x$ $$E_N^{L}(f) = \left| \ \int_a^b f(x) \ dx - L_N(f) \ \right| \leq \frac{(b-a)^2}{2 N} K_1$$ 有黎曼和误差分析: $$R_N(f) = \sum_{i=1}^N f(x_{i} ) \Delta x$$ 其中:$\Delta x = (b-a)/N$,$x_i = a + i \Delta x$ $$E_N^{R}(f) = \left| \ \int_a^b f(x) \ dx - R_N(f) \ \right| \leq \frac{(b-a)^2}{2 N} K_1$$ 中点黎曼误差分析: $$M_N(f) = \sum_{i=1}^N f(x_i^) \Delta x$$ 其中:$\Delta x = (b-a)/N$,$x_i^ = (x_{i-1} + x_i)/2$,$x_i = a + i \Delta x$ $$E_N^{M}(f) = \left| \ \int_a^b f(x) \ dx - M_N(f) \ \right| \leq \frac{(b-a)^3}{24 N^2} K_2$$ 有几点要注意: 左和右黎曼和具有相同的误差范围,该误差范围取决于一阶导数$f'(x)$ 中点黎曼和误差界取决于二阶导数$f''(x)$ * 我们期望中点黎曼和能够给出更好的近似值,即$N→∞N^2N$

Python求黎曼和的方法

让我们写一个调用的函数riemann_sum这需要5个输入参数f,a,b,N和method并返回黎曼和 $$\sum_{i=1}^N f(x_i^*) \Delta x$$ 其中:$\Delta x = (b-a)/N$,$x_i = a + i\Delta x$

def riemann_sum(f,a,b,N,method='midpoint'):

'''Compute the Riemann sum of f(x) over the interval [a,b].Parameters----------f : functionVectorized function of one variablea , b : numbersEndpoints of the interval [a,b]N : integerNumber of subintervals of equal length in the partition of [a,b]method : stringDetermines the kind of Riemann sum:right : Riemann sum using right endpointsleft : Riemann sum using left endpointsmidpoint (default) : Riemann sum using midpointsReturns-------floatApproximation of the integral given by the Riemann sum.'''

dx = (b - a)/N

x = np.linspace(a,b,N+1)

if method == 'left':

x_left = x[:-1]

return np.sum(f(x_left)*dx)

elif method == 'right':

x_right = x[1:]

return np.sum(f(x_right)*dx)

elif method == 'midpoint':

x_mid = (x[:-1] + x[1:])/2

return np.sum(f(x_mid)*dx)

else:

raise ValueError("Method must be 'left', 'right' or 'midpoint'.")

让我们通过特例来验证下这个函数,比如一下具体例子,我们知道: $$\int_0^{\pi/2} \sin(x) \, dx = 1$$ 对于$\sin(x)[0,\pi/2]$,运行函数:

riemann_sum(np.sin, 0, np.pi/2, 100)

1.0000102809119054

riemann_sum(np.sin, 0, np.pi/2, 100, 'right') # 右黎曼和

1.007833419873582

riemann_sum(np.sin, 0, np.pi/2, 100, 'left') # 左黎曼和

0.992125456605633

再来个例子:$\int_0^1 x \, dx = 1/2$

riemann_sum(lambda x : x,0,1,1)

0.5

你可能感兴趣的:(python求和函数从1到m)