Given a perfect cube that encloses 27mWe know from geometry that if the length of a cube's side is x, the enclosed space is#tex2html_wrap_inline73624#. What area do its six walls cover?
Once we solved the equation, the covered area is
The value <#66589#><#35590#>r<#35590#><#66589#> is called the <#35591#>root<#35591#> of <#35592#>f<#35592#>. In our above
example,
<#66590#>Figure: A numeric function <#35597#>f<#35597#> with root in interval [a,b] (stage~1)<#66590#>
It partitions the interval [a,b] into two smaller, equally large
intervals. We can now compute the value of f at m and see whether it is
below or above 0. Here f(m) ;SPMgt; 0, so according to the Mean Value Theorem,
the root is in the right interval: [m,b]. Our picture confirms this
because the root is in the right half of the interval, labeled ``range 2''
in figure~#figroot#35602>
Find an interval of size .5 (or less) in which <#66616#><#35732#>poly<#35732#><#66616#> contains a
root.~ Solution<#66617#><#66617#>
<#36125#>Step 1<#36125#>: Develop the algorithm <#66685#><#36126#>integrate-dc<#36126#><#66685#>, which
integrates a function <#66686#><#36127#>f<#36127#><#66686#> between the boundaries <#66687#><#36128#>left<#36128#><#66687#> and
<#66688#><#36129#>right<#36129#><#66688#> via the divide-and-conquer strategy employed in
<#66689#><#36130#>find-root<#36130#><#66689#>. Use rectangle approximations when an interval has
become small enough.
Although the area of a rectangle is easy to compute, a rectangle is often
a bad approximation of the area under a function graph. A better geometric
shape is the trapezoid limited by a, <#66690#><#36131#>(f<#36131#>\ <#36132#>a)<#36132#><#66690#>, b, and
<#66691#><#36133#>(f<#36133#>\ <#36134#>b)<#36134#><#66691#>. Its area is:
<#36140#>Step 2<#36140#>: Modify <#66693#><#36141#>integrate-dc<#36141#><#66693#> so that it uses
trapezoids instead of rectangles.
The plain divide-and-conquer approach is wasteful. Consider a function
graph is level in one part and rapidly changes in another. For the level
part it is pointless to keep splitting the interval. We could just compute
the trapezoid over a and b instead of the two halves.
To discover when <#36142#>f<#36142#> is level, we can change the algorithm as
follows. Instead of just testing how large the interval is, the new
algorithm computes the area of three trapezoids: the given one, and the two
halves. Suppose the difference between the two is less than
This area represents a small rectangle, of height <#66694#><#36146#>TOLERANCE<#36146#><#66694#>, and
represents the error margin of our computation. In other words, the
algorithm determines whether <#36147#>f<#36147#> changes enough to affect the error
margin, and if not, it stops. Otherwise, it continues with the
divide-and-conquer approach.
<#36148#>Step 3<#36148#>: Develop <#66695#><#36149#>integrate-adaptive<#36149#><#66695#>, which
integrates a function <#36150#>f<#36150#> between <#36151#>left<#36151#> and <#36152#>right<#36152#>
according to the suggested method. Do not discuss the termination
of <#66696#><#36153#>integrate-adaptive<#36153#><#66696#>.
<#36154#>Note<#36154#>: The algorithm is called ``adaptive integration''
because it automatically adapts its strategy. For those parts of <#36155#>f<#36155#>
that are level, it performs just a few calculations; for the other parts,
it inspects very small intervals so that the error margin is also decreased
accordingly.~ Solution<#66697#><#66697#>
The Mean Value Theorem says that a continuous function f has a root in an
interval [a,b] if the signs of f(a) and f(b) differ. By <#35599#>continuous<#35599#> we mean a function that doesn't ``jump'', that doesn't have
gaps, and that always continues in a ``smooth'' fashion. The theorem is best
illustrated with the graph of a function. The function f in
figure~#figroot#35600><#35613#>(or<#35613#> <#35614#>(;SPMlt;=<#35614#> <#35615#>(f<#35615#> <#35616#>left)<#35616#> <#35617#>0<#35617#> <#35618#>(f<#35618#> <#35619#>right))<#35619#>
<#35620#>(;SPMlt;=<#35620#> <#35621#>(f<#35621#> <#35622#>right)<#35622#> <#35623#>0<#35623#> <#35624#>(f<#35624#> <#35625#>left)))<#35625#>
holds. This assumption expresses in Scheme the condition of the Mean Value
Theorem that the function must have different signs for <#66597#><#35629#>left<#35629#><#66597#> and
<#66598#><#35630#>right<#35630#><#66598#>.
According to the informal process description, the task of
<#66599#><#35631#>find-root<#35631#><#66599#> is to find an interval that contains a root and that is
tolerably small. The size of the given interval is <#66600#><#35632#>(-<#35632#>\ <#35633#>right<#35633#><#35634#> <#35634#><#35635#>left)<#35635#><#66600#>. For the moment, we assume that the tolerance is defined as a top-level
variable <#66601#><#35636#>TOLERANCE<#35636#><#66601#>. Given that, <#66602#><#35637#>find-root<#35637#><#66602#> can produce one
of the two boundaries of the interval because we know what its size is;
let's pick the left one.
Here is a translation of our discussion into a contract, a purpose
statement, and a header, including the assumption on the parameters:
<#71506#>;; <#66603#><#35642#>find-root<#35642#> <#35643#>:<#35643#> <#35644#>(number<#35644#> <#35645#><#35645#><#35646#>-;SPMgt;<#35646#><#35647#><#35647#> <#35648#>number)<#35648#> <#35649#>number<#35649#> <#35650#>number<#35650#> <#35651#><#35651#><#35652#>-;SPMgt;<#35652#><#35653#><#35653#> <#35654#>number<#35654#><#66603#><#71506#>
<#71507#>;; to determine <#66604#><#35655#>R<#35655#><#66604#> such that <#66605#><#35656#>f<#35656#><#66605#> has a root in [<#66606#><#35657#>R<#35657#><#66606#>,<#66607#><#35658#>(+<#35658#> <#35659#>R<#35659#> <#35660#>TOLERANCE)<#35660#><#66607#>]<#71507#>
<#35661#>;; <#35661#>
<#71508#>;; <#35662#>ASSUMPTION<#35662#>: <#66608#><#35663#>(or<#35663#> <#35664#>(;SPMlt;=<#35664#> <#35665#>(f<#35665#> <#35666#>left)<#35666#> <#35667#>0<#35667#> <#35668#>(f<#35668#> <#35669#>right))<#35669#> <#35670#>(;SPMlt;=<#35670#> <#35671#>(f<#35671#> <#35672#>right)<#35672#> <#35673#>0<#35673#> <#35674#>(f<#35674#> <#35675#>left)))<#35675#><#66608#><#71508#>
<#35676#>(define<#35676#> <#35677#>(find-root<#35677#> <#35678#>f<#35678#> <#35679#>left<#35679#> <#35680#>right)<#35680#> <#35681#>...)<#35681#>
At this stage, we should develop an example of how the function works. We
have already seen one; the following exercise develops a second one.
<#35687#>Exercise 27.3.1<#35687#>
<#71509#>;; <#66609#><#35693#>poly<#35693#> <#35694#>:<#35694#> <#35695#>number<#35695#> <#35696#><#35696#><#35697#>-;SPMgt;<#35697#><#35698#><#35698#> <#35699#>number<#35699#><#66609#><#71509#>
<#35700#>(<#35700#><#35701#>define<#35701#> <#35702#>(poly<#35702#> <#35703#>x)<#35703#>
<#35704#>(*<#35704#> <#35705#>(-<#35705#> <#35706#>x<#35706#> <#35707#>2)<#35707#> <#35708#>(-<#35708#> <#35709#>x<#35709#> <#35710#>4)))<#35710#>
It defines a binomial for which we can determine its roots by hand---they
are <#66610#><#35714#>2<#35714#><#66610#> and <#66611#><#35715#>4<#35715#><#66611#>. But it is also a non-trivial input for
<#66612#><#35716#>find-root<#35716#><#66612#>, so that it makes sense to use it as an example.
Mimic the root-finding process based on the Mean Value Theorem for
<#66613#><#35717#>poly<#35717#><#66613#>, starting with the interval <#66614#><#35718#>3<#35718#><#66614#> and
<#66615#><#35719#>6<#35719#><#66615#>. Tabulate the information as follows:
Next we turn our attention to the definition of <#66618#><#35740#>find-root<#35740#><#66618#>. We start
from <#66619#><#35741#>generative-recursive-fun<#35741#><#66619#> and ask the four relevant questions:
The completed function is displayed in figure~#figrootoff#35897><#35750#>(;SPMlt;=<#35750#> <#35751#>(-<#35751#> <#35752#>right<#35752#> <#35753#>left)<#35753#> <#35754#>TOLERANCE)<#35754#>
The matching result is <#66623#><#35758#>left<#35758#><#66623#>.
<#35765#>(local<#35765#> <#35766#>((define<#35766#> <#35767#>mid<#35767#> <#35768#>(/<#35768#> <#35769#>(+<#35769#> <#35770#>left<#35770#> <#35771#>right)<#35771#> <#35772#>2)))<#35772#> <#35773#>...)<#35773#>
Choosing an interval is more complicated than that.
Consider the Mean Value Theorem again. It says that a given interval is an
interesting candidate if the function values at the boundaries have different
signs. For the function's purpose statement, we expressed this constraint
using
<#35781#>(or<#35781#> <#35782#>(;SPMlt;=<#35782#> <#35783#>(f<#35783#> <#35784#>left)<#35784#> <#35785#>0<#35785#> <#35786#>(f<#35786#> <#35787#>right))<#35787#> <#35788#>(;SPMlt;=<#35788#> <#35789#>(f<#35789#> <#35790#>right)<#35790#> <#35791#>0<#35791#> <#35792#>(f<#35792#> <#35793#>left)))<#35793#>
Accordingly, the interval between <#66626#><#35797#>left<#35797#><#66626#> and <#66627#><#35798#>mid<#35798#><#66627#> is the next
candidate if
<#35803#>(or<#35803#> <#35804#>(;SPMlt;=<#35804#> <#35805#>(f<#35805#> <#35806#>left)<#35806#> <#35807#>0<#35807#> <#35808#>(f<#35808#> <#35809#>mid))<#35809#> <#35810#>(;SPMlt;=<#35810#> <#35811#>(f<#35811#> <#35812#>mid)<#35812#> <#35813#>0<#35813#> <#35814#>(f<#35814#> <#35815#>left)))<#35815#>
And, the interval between <#66628#><#35819#>mid<#35819#><#66628#> and <#66629#><#35820#>right<#35820#><#66629#> is it, if
<#35825#>(or<#35825#> <#35826#>(;SPMlt;=<#35826#> <#35827#>(f<#35827#> <#35828#>mid)<#35828#> <#35829#>0<#35829#> <#35830#>(f<#35830#> <#35831#>right))<#35831#> <#35832#>(;SPMlt;=<#35832#> <#35833#>(f<#35833#> <#35834#>right)<#35834#> <#35835#>0<#35835#> <#35836#>(f<#35836#> <#35837#>mid)))<#35837#>
In short, the body of the <#66630#><#35841#>local<#35841#>-expression<#66630#> must be a conditional:
<#35846#>(l<#35846#><#35847#>ocal<#35847#> <#35848#>((define<#35848#> <#35849#>mid<#35849#> <#35850#>(/<#35850#> <#35851#>(+<#35851#> <#35852#>left<#35852#> <#35853#>right)<#35853#> <#35854#>2)))<#35854#>
<#35855#>(c<#35855#><#35856#>ond<#35856#>
<#35857#>[<#35857#><#35858#>(or<#35858#> <#35859#>(;SPMlt;=<#35859#> <#35860#>(f<#35860#> <#35861#>left)<#35861#> <#35862#>0<#35862#> <#35863#>(f<#35863#> <#35864#>mid))<#35864#> <#35865#>(;SPMlt;=<#35865#> <#35866#>(f<#35866#> <#35867#>mid)<#35867#> <#35868#>0<#35868#> <#35869#>(f<#35869#> <#35870#>left)))<#35870#>
<#35871#>(find-root<#35871#> <#35872#>left<#35872#> <#35873#>mid)]<#35873#>
<#35874#>[<#35874#><#35875#>(or<#35875#> <#35876#>(;SPMlt;=<#35876#> <#35877#>(f<#35877#> <#35878#>mid)<#35878#> <#35879#>0<#35879#> <#35880#>(f<#35880#> <#35881#>right))<#35881#> <#35882#>(;SPMlt;=<#35882#> <#35883#>(f<#35883#> <#35884#>right)<#35884#> <#35885#>0<#35885#> <#35886#>(f<#35886#> <#35887#>mid)))<#35887#>
<#35888#>(find-root<#35888#> <#35889#>mid<#35889#> <#35890#>right)]<#35890#><#35891#>))<#35891#>
In both clauses, we use <#66631#><#35895#>find-root<#35895#><#66631#> to continue the search.
<#71510#>;; <#66632#><#35902#>find-root<#35902#> <#35903#>:<#35903#> <#35904#>(number<#35904#> <#35905#><#35905#><#35906#>-;SPMgt;<#35906#><#35907#><#35907#> <#35908#>number)<#35908#> <#35909#>number<#35909#> <#35910#>number<#35910#> <#35911#><#35911#><#35912#>-;SPMgt;<#35912#><#35913#><#35913#> <#35914#>number<#35914#><#66632#><#71510#>
<#71511#>;; to determine a number R such that <#66633#><#35915#>f<#35915#><#66633#> has a <#71511#>
<#71512#>;; root between R and <#66634#><#35916#>(+<#35916#> <#35917#>R<#35917#> <#35918#>TOLERANCE)<#35918#><#66634#> <#71512#>
<#35919#>;; <#35919#>
<#66635#>;; <#35920#>ASSUMPTION<#35920#>: <#35921#>f<#35921#> is continuous and monotonic<#66635#>
<#35922#>(d<#35922#><#35923#>efine<#35923#> <#35924#>(find-root<#35924#> <#35925#>f<#35925#> <#35926#>left<#35926#> <#35927#>right)<#35927#>
<#35928#>(c<#35928#><#35929#>ond<#35929#>
<#35930#>[<#35930#><#35931#>(;SPMlt;=<#35931#> <#35932#>(-<#35932#> <#35933#>right<#35933#> <#35934#>left)<#35934#> <#35935#>TOLERANCE)<#35935#> <#35936#>left]<#35936#>
<#35937#>[<#35937#><#35938#>e<#35938#><#35939#>lse<#35939#>
<#35940#>(l<#35940#><#35941#>ocal<#35941#> <#35942#>((define<#35942#> <#35943#>mid<#35943#> <#35944#>(/<#35944#> <#35945#>(+<#35945#> <#35946#>left<#35946#> <#35947#>right)<#35947#> <#35948#>2)))<#35948#>
<#35949#>(c<#35949#><#35950#>ond<#35950#>
<#35951#>[<#35951#><#35952#>(;SPMlt;=<#35952#> <#35953#>(f<#35953#> <#35954#>mid)<#35954#> <#35955#>0<#35955#> <#35956#>(f<#35956#> <#35957#>right))<#35957#>
<#35958#>(find-root<#35958#> <#35959#>mid<#35959#> <#35960#>right)]<#35960#>
<#35961#>[<#35961#><#35962#>else<#35962#>
<#35963#>(find-root<#35963#> <#35964#>left<#35964#> <#35965#>mid)]<#35965#><#35966#>))]<#35966#><#35967#>))<#35967#>
<#66636#>Figure: The root-finding algorithm <#35971#>find-root<#35971#><#66636#>
<#35975#>Exercise 27.3.2<#35975#>
<#71513#>;; <#66664#><#36037#>g<#36037#> <#36038#>:<#36038#> <#36039#>N<#36039#> <#36040#><#36040#><#36041#>-;SPMgt;<#36041#><#36042#><#36042#> <#36043#>num<#36043#><#66664#><#71513#>
<#71514#>;; <#36044#>ASSUMPTION<#36044#>: <#66665#><#36045#>i<#36045#><#66665#> is between 0 and <#66666#><#36046#>VL<#36046#><#66666#><#71514#>
<#36047#>(d<#36047#><#36048#>efine<#36048#> <#36049#>(g<#36049#> <#36050#>i)<#36050#>
<#36051#>(c<#36051#><#36052#>ond<#36052#>
<#36053#>[<#36053#><#36054#>(=<#36054#> <#36055#>i<#36055#> <#36056#>0)<#36056#> <#36057#>-10]<#36057#>
<#36058#>[<#36058#><#36059#>(=<#36059#> <#36060#>i<#36060#> <#36061#>1)<#36061#> <#36062#>...]<#36062#>
<#36063#>...<#36063#>
<#36064#>[<#36064#><#36065#>(=<#36065#> <#36066#>i<#36066#> <#36067#>(-<#36067#> <#36068#>VL<#36068#> <#36069#>1))<#36069#> <#36070#>...]<#36070#>
<#36071#>[<#36071#><#36072#>else<#36072#> <#36073#>(error<#36073#> <#36074#>'<#36074#><#36075#>g<#36075#> <#36076#>``is<#36076#> <#36077#>defined<#36077#> <#36078#>only<#36078#> <#36079#>between<#36079#> <#36080#>0<#36080#> <#36081#>and<#36081#> <#36082#>VL<#36082#> <#36083#>(exclusive)'')]<#36083#><#36084#>))<#36084#>
The number <#66667#><#36088#>VL<#36088#><#66667#> is called the <#36089#>table's length<#36089#>. The <#36090#>root of a table<#36090#> is the number in the table that is closest to <#66668#><#36091#>0<#36091#><#66668#>. Even
if we can't read the definition of a table, we can find its root with a
search function.
Develop the function <#66669#><#36092#>find-root-linear<#36092#><#66669#>, which consumes a table, the
table's length, and finds the root of the table. Use structural induction
on natural numbers. This kind of root-finding process is often called a
<#36093#>linear search<#36093#>.
A table <#66670#><#36094#>t<#36094#><#66670#> is sorted in ascending order if <#66671#><#36095#>(t<#36095#>\ <#36096#>0)<#36096#><#66671#> is less
then <#66672#><#36097#>(t<#36097#>\ <#36098#>1)<#36098#><#66672#>, <#66673#><#36099#>(t<#36099#>\ <#36100#>1)<#36100#><#66673#> is less than <#66674#><#36101#>(t<#36101#>\ <#36102#>2)<#36102#><#66674#>, and so
on. If a table is monotonic, we can determine the root using binary
search. Specifically, we can use binary search to find an interval of size
<#66675#><#36103#>1<#36103#><#66675#> such that either the left or the right boundary is the root's
index. Develop <#66676#><#36104#>find-root-discrete<#36104#><#66676#>, which consumes a table and its
length, and finds the table's root.
<#36105#>Hints:<#36105#> (1) The interval boundary arguments for <#66677#><#36106#>find-root-discrete<#36106#><#66677#>
must always be natural numbers. Consider how this affects the mid-point
computation. (2) Also contemplate how the first hint affects the discovery
of trivially solvable problem instances. (3) Does the termination argument
from exercise~#exfindroottermination#36107>
Here the area of interest is that enclosed by the bold vertical
lines at a and b, the <#36123#>x<#36123#>-axis, and the graph of the
function.
In section~#secintegrate1#36124>