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>
<#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.
<#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:
Find an interval of size .5 (or less) in which <#66616#><#35732#>poly<#35732#><#66616#> contains a
root.~ Solution<#66617#><#66617#>
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:
<#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#>
<#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>
<#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#>