重新审视抛物线下的面积
我之前无法从之前的问题中找到答案,因为我不是这个网站的会员,所以回来的时候无法评论。现在我有个问题:
为了找出被图形y=x^2和x轴围起来的区域在[a,b]区间内的面积,我们可以通过画一些“薄薄的”矩形来近似这个区域,然后把这些矩形的面积加起来。我们可以把区间[a,b]分成n个宽度相同的小区间,宽度h=(b-a)/n。在每个小区间里,我们可以画一个矩形,矩形的高度y=r,其中r是这个小区间在x轴上的中间值。这个矩形的面积就是h乘以y。请写一个Python函数,接受a、b和n作为参数,并使用上述方法返回在抛物线y=x^2下的近似面积。如果你能解释一下你的程序为什么能这样工作,那就太好了。
感谢热心的成员,我找到了以下程序(请编辑这个程序,因为我不知道怎么做)
def parabola(x):
y = x*x
return y
def approx_area(fn, a, b, n):
"""
Approximate the area under fn in the interval [a,b]
by adding the area of n rectangular slices.
"""
a = float(a)
b = float(b)
area = 0.0
for slice in range(n):
left = a + (b-a)*slice/n
right = a + (b-a)*(slice+1)/n
mid = (left + right)*0.5
height = fn(mid)
width = right - left
area += height * width
return area
print "Area is", approx_area(parabola, -1.0, 1.0, 500)
不过,我需要把这个放在一个完整的函数里。你有什么想法吗?
2 个回答
这里有一个不错的可视化效果,可以在 这个链接 找到。
我们来看一下抛物线在a和b之间的部分,然后把它分成一系列垂直的矩形切片,每个矩形的顶部正好在抛物线上。
这样,每个矩形的一角就会“悬空”在抛物线的上面,而另一角则太低,留下了未填充的空间。因此,抛物线下的面积等于矩形的面积,加上一点,再减去一点。但是,我们怎么比较这些小部分呢?矩形的面积是多了一点,还是少了一点呢?
如果我们在矩形的顶部中心画一条切线,就可以“切掉”重叠的部分,把它翻过来,放到另一边;注意,这样做并不会改变矩形的总面积(现在变成了一个梯形)。
现在我们可以看到,在抛物线的两侧还有一点空间,所以梯形的面积稍微小于抛物线下的面积。我们可以把梯形的顶部看作是在抛物线底部形成的一系列直线段(这叫做“线性分段近似”);而这些线段下的面积几乎和我们想要的实际面积相同,但总是稍微少一点。
那么,我们怎么才能把这个“稍微少一点”的量减到最小,以使我们计算的面积更准确呢?一种方法是使用曲线近似,而不是直线;这就引出了样条曲线(比如贝塞尔曲线、NURBS等)。另一种方法是使用更多的短线段,以“提高分辨率”。微积分把这个想法推向极限(有双关的意思),使用无限多个无限短的线段。
好吧,通过把函数改成 y = x
并尝试一些已知的输入值,我得出结论,它运行得很好:
0 .. 1 => 0.5
0 .. 2 => 2.0
1 .. 2 => 1.5
0 .. 9 => 40.5
如果你想把所有内容放在一个函数里,只需去掉 parabola()
,把 approx_area()
函数的第一个参数(和调用)去掉,然后把:
height = fn(mid)
改成:
height = mid * mid
就像这样:
def approx_area(a, b, n):
"""
Approximate the area under fn in the interval [a,b]
by adding the area of n rectangular slices.
"""
a = float(a)
b = float(b)
area = 0.0
for slice in range(n):
left = a + (b-a)*slice/n
right = a + (b-a)*(slice+1)/n
mid = (left + right)*0.5
height = mid * mid
width = right - left
area += height * width
return area
print "Area is", approx_area(-1, 1, 500)
请注意,我通常不会给作业提供这么多明确的帮助,但因为你已经完成了大部分工作,所以这只是一个小小的推动,帮助你完成。
我建议你不要直接提交这段代码,因为简单的网络搜索就能轻易找到它,这样可能会影响你的成绩。
仔细研究它,彻底理解它是怎么工作的,然后尝试自己重新编码,而不是直接抄袭。相信我,这对你的职业生涯帮助会更大。
为了让你理解这个方法背后的理论,考虑一下函数 y = x
的一部分:
7 .
6 /|
5 / |
| |
| |
| |
| |
| |
0 +-+
567
顶部的中点 y 坐标(也是高度)是 (5 + 7) / 2
,也就是 6
,宽度是 2
,所以面积是 12
。
现在,这实际上是真实的面积,但这只是因为我们使用的公式。对于非线性公式,由于“线”的顶部的特性,会有一些不准确性。具体来说,在你的例子中,抛物线是弯曲的。
但是,随着你使用越来越薄的切片,这些不准确性会越来越小,因为任何线在缩短时都会趋向于一条直线(线性)。对于上面的例子,如果你把它分成两个切片,面积将是 5.5 x 1
和 6.5 x 1
,总共 12
。如果你的线不是直的,两个切片的结果会比一个切片的结果更接近真实值。
对于你的抛物线(但为了让我更简单,从 x = 0 .. 1
开始,只需把所有值翻倍到 x = -1 .. 1
,因为它在 y 轴周围是对称的),在一个切片的情况下,最糟糕的情况是中点在 x = 0.5, y = 0.25
,当你把这个 y
乘以宽度 1
时,得到的面积是 0.25
。
用两个切片(宽度 = 0.5
),中点在:
x y y x width
---- ------ ---------
0.25 0.0625 0.03125
0.75 0.5625 0.28125
---------
0.31250
所以那里的面积估计是 0.3125
。
用四个切片(宽度 = 0.25
),中点在:
x y y x width
----- -------- ----------
0.125 0.015625 0.00390625
0.375 0.140625 0.03515625
0.625 0.390625 0.09765625
0.875 0.765625 0.19140625
----------
0.32812500
所以那里的面积估计是 0.328125
。
用八个切片(宽度 = 0.125
),中点在:
x y y x width
------ ---------- -----------
0.0625 0.00390625 0.000488281
0.1875 0.03515625 0.004394531
0.3125 0.09765625 0.012207031
0.4375 0.19140625 0.023925781
0.5625 0.31640625 0.039550781
0.6875 0.47265625 0.059082031
0.8125 0.66015625 0.082519531
0.9375 0.87890625 0.109863281
-----------
0.332031248
所以那里的面积估计是 0.332031248
。
正如你所看到的,这个值越来越接近真实的面积 1/3
(我知道这一点,因为我懂微积分,见下文)。
希望这能帮助你理解你手上的代码。
如果你真的想知道这个是怎么工作的,你需要了解微积分,特别是积分和导数。这些方法可以将一个公式转化为另一个公式,用于计算线的斜率和线下的面积。
但是,除非你会经常使用它并需要真正的(数学上的)准确性,否则你可能只需使用你正在学习的近似方法。