<div dir="ltr"><div>Thank you, Jens. I didn't know that the inexactness of floating point numbers could make such a big difference.</div><div><br></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Nov 5, 2013 at 10:01 PM, Jens Axel Søgaard <span dir="ltr"><<a href="mailto:jensaxel@soegaard.net" target="_blank">jensaxel@soegaard.net</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I think I got it now.<br>
<br>
In your solution the x-values are computed as follows:<br>
  h = (b-a)/n<br>
  x1 = a+1<br>
  x3 = x1 +2*h<br>
  x5 = x3 +2*h<br>
 ...<br>
<br>
This means rounding errors slowly accumulate.<br>
It happens when (b-a)/n is not representable as floating point.<br>
<br>
If we instead compute xi as a+ (i*(b-a))/n you will get more accurate results.<br>
<br>
This variant of your solution uses the above method to compute the xi.<br>
<br>
(define (simpson-integral3 f a b n)<br>
<div class="im">  (define h (/ (- b a) n))<br>
</div>  (define (next i) (+ i 2))<br>
  (define (f* i) (f (+ a (/ (* i (- b a)) n))))<br>
<div class="im">  (* (/ h 3)<br>
     (+ (f a)<br>
</div>        (* 4 (sum f* 1 next n))<br>
        (* 2 (sum f* 2 next (- n 1)))<br>
        (f b))))<br>
<br>
<br>
<br>
2013/11/5 Ben Duan <<a href="mailto:yfefyf@gmail.com">yfefyf@gmail.com</a>>:<br>
<div class="HOEnZb"><div class="h5">> Thanks, Jens and Daniel.<br>
><br>
> There's no problem with Simpson's Rule. I got another way to implement<br>
> Simpson's Rule from Eli Bendersky. And re-wrote it in Racket:<br>
><br>
>     (define (simpson-integral2 f a b n)<br>
>       (define h (/ (- b a) n))<br>
>       (define (next counter) (+ counter 1))<br>
>       (define (term counter)<br>
>         (* (f (+ a (* h counter))) (cond<br>
>                                      ((= counter 0) 1)<br>
>                                      ((= counter n) 1)<br>
>                                      ((odd? counter) 4)<br>
>                                      ((even? counter) 2))))<br>
>       (* (/ h 3) (sum term 0 next n)))<br>
><br>
> The result is very accurate:<br>
><br>
>     > (simpson-integral2 cube 0 1.0 10)<br>
>     0.25<br>
>     > (simpson-integral2 cube 0 1.0 100)<br>
>     0.24999999999999992<br>
>     > (simpson-integral2 cube 0 1.0 1000)<br>
>     0.2500000000000003<br>
>     > (simpson-integral2 cube 0 1.0 10000)<br>
>     0.2500000000000011<br>
><br>
> Eli's code and mine are two implementations for the same Rule, but mine is<br>
> far less accurate. So I think there's some wrong with my implementation. But<br>
> I still can't find it out.<br>
><br>
><br>
> On Tue, Nov 5, 2013 at 1:59 AM, Jens Axel Søgaard <<a href="mailto:jensaxel@soegaard.net">jensaxel@soegaard.net</a>><br>
> wrote:<br>
>><br>
>> 2013/11/4 Ben Duan <<a href="mailto:yfefyf@gmail.com">yfefyf@gmail.com</a>>:<br>
>> > I've asked the question on Stack Overflow [1]. Óscar López gave me an<br>
>> > answer. But I still don't understand it. So I re-post it here:<br>
>> ><br>
>> > Following is my code for SICP exercise 1.29 [2]. The exercise asks us to<br>
>> > implement Simpson's Rule using higher order procedure `sum`. It's<br>
>> > supposed<br>
>> > to be more accurate than the original `integral` procedure. But I don't<br>
>> > know why<br>
>> > it's not the case in my code:<br>
>><br>
>> A couple of points:<br>
>><br>
>>  - to compare to methods M1 and M2 we need to specify the class of<br>
>> functions,<br>
>>    we will use the methods on<br>
>>  - when comparing the results of the two methods on a single function f,<br>
>>    we must use the same number of evaluations of f<br>
>>  - the most accurate method for a given number of evaluations n,<br>
>>    is the method which has the best worst case behaviour<br>
>><br>
>> Thus when SICP says:<br>
>> "Simpson's Rule is a more accurate method of numerical integration<br>
>> than the method illustrated above."<br>
>> it doesn't mean that the Simpson rule will work better than, say, the<br>
>> midpoint method for all<br>
>> function. Some methods give very good results for polynomials of a small<br>
>> degree.<br>
>> Try your methods on some non-polynomials: say 1/x , ln(x), sqrt(x) and<br>
>> sin(x).<br>
>><br>
>> See also some interesting examples here:<br>
>><br>
>> <a href="http://www.math.uconn.edu/~heffernan/math1132s13/files/trapezoid_rule.pdf" target="_blank">http://www.math.uconn.edu/~heffernan/math1132s13/files/trapezoid_rule.pdf</a><br>
>><br>
>><br>
>> --<br>
>> Jens Axel Søgaard<br>
><br>
><br>
<br>
<br>
<br>
</div></div><span class="HOEnZb"><font color="#888888">--<br>
--<br>
Jens Axel Søgaard<br>
</font></span></blockquote></div><br></div>