Area under a parabola revisited
I was unable to go from the previous question because I was not a member of the website so I was unable to comment on it when I returned. Here is my question:
To find the area of a region bounded by the graph y=x^2 and the x-axis on the interval [a,b] we can approximate the region by drawing a number of "thin" rectangles and taking the sum of their areas. Let us divide [a,b] into n smaller intervals of the same widght h=b-1/n. On each interval there is a rectangle with the height y=r where r is the middle of that small interval on the x-axis. The area of that rectangle is hy. Write a Python function that takes a,b, and n as parameters and returns the approximate area of the region under the parabola y=x^2 using the above method. If you could please explain as to why your program works that would be helpful.
Thanks to helpful members, I found the following program(please edit the program for i am unable/ don't know how to
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 = f开发者_运维问答loat(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)
However, I would need to place this under one entire function. Any ideas on how I can do this?
Okay, by changing the function to y = x
and trying some known input values, I conclude that it works fine:
0 .. 1 => 0.5
0 .. 2 => 2.0
1 .. 2 => 1.5
0 .. 9 => 40.5
If you want it all in one function, just get rid of parabola()
, remove the first parameter from the approx_area()
function (and call), then change:
height = fn(mid)
to:
height = mid * mid
as in:
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)
Note that I wouldn't normally give this much explicit help for homework but, since you've done the bulk of the work yourself, it's only a small nudge to push you across the line.
I would warn you against handing in this code as-is since a simple web search will easily find it here and your grades may suffer for that.
Examine it, understand how it works thoroughly, then try to re-code it yourself without looking at this source. That will assist you far more in your career than just blind copying, trust me.
And just so you understand the theory behind this method, consider the slice of the function y = x
:
7 .
6 /|
5 / |
| |
| |
| |
| |
| |
0 +-+
567
The midpoint y co-ordinate (and also the height) of the top is (5 + 7) / 2
, or 6
, and the width is 2
so the area is 12
.
Now this is in fact the actual area but that's only because of the formula we're using. For a non-linear formula, there will be inaccuracies because of the nature of the "line" at the top. Specifically, in your case, a parabola is curved.
But these inaccuracies get less and less and you use thinner and thinner slices since any line tends towards a straight line (linear) as you shorten it. For the case above, if you divided that into two slices, the areas would be 5.5 x 1
and 6.5 x 1
for a total of 12
. If you line weren't straight, the two-slice answer would be closer to reality than the one-slice answer.
For your parabola (but from x = 0 .. 1
to make my life easier, just double everything for x = -1 .. 1
since it's symmetrical around the y-axis), the worst case in a one-slice solution. In that case, the midpoint is at x = 0.5, y = 0.25
and, when you multiply that y
by the width of 1
, you get an area of 0.25
.
With two slices (width = 0.5
), the midpoints are at:
x y y x width
---- ------ ---------
0.25 0.0625 0.03125
0.75 0.5625 0.28125
---------
0.31250
So the area estimate there is 0.3125
.
With four slices (width = 0.25
), the midpoints are at:
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
So the area estimate there is 0.328125
.
With eight slices (width = 0.125
), the midpoints are at:
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
So the area estimate there is 0.332031248
.
As you can see, this is becoming closer and closer to the actual area of 1/3
(I know this since I know calculus, see below).
Hopefully, that will assist you in understanding the code you have.
If you really want to know how this works, you need to look into calculus, specifically integration and differentiation. These methods can take a formula and give you another formula for calculating the slope of a line and the area under the line.
But, unless you're going to be using it a lot and need real (mathematical) accuracy, you can probably just use the approximation methods you're learning about.
There is also a good visualization of this at http://en.wikipedia.org/wiki/Integral#Formal_definitions
We look at the section of the parabola between a and b, and we divide it into a set of vertical rectangular slices such that the top-center of each rectangle is exactly on the parabola.
This leaves one corner of each rectangle "hanging over" the parabola, and the other too low, leaving unfilled space; so the area under the parabola is equal to the area of the rectangle, plus a bit, minus a bit. But how do we compare the bits? Is the area of the rectangle a bit too much, or not quite enough?
If we draw a line tangent to the parabola at the top-center of the rectangle, we can "cut off" the overlapping bit, flip it over, and add it to the other side; note that this does not change the total area of the rectangle (now a trapezoid).
We can now see that there is a little bit of space left on either side under the parabola, so the area of the trapezoid is slightly less than the area under the parabola. We can now think of the trapezoid-tops as forming a bunch of straight-line segments (a "linear piecewise approximation") along the bottom of the parabola; and the area under the segments is almost the same as (but always slightly less than) the actual area we are seeking.
So how do we minimize the "slightly less than" amount, to make our calculated area more accurate? One way is to use curved approximation-pieces instead of straight lines; this leads into splines (Bezier curves, NURBS, etc). Another way is to use a larger number of shorter line-pieces, to "increase the resolution". Calculus takes this idea to the limit (pun intended), using an infinite number of infinitely short pieces.
精彩评论