Re: lisp function questions



Jon Harrop <usenet@xxxxxxxxxxxxxx> writes:

> Pascal Bourguignon wrote:
>> There's no loop so there's no concern about numerical stability.
>
> Loops are irrelevant. There _is_ concern about numerical stability.
>
>> (defun solve-quadratic (a b c)
>> (if (zerop a)
>> (solve-linear b c)
>> (let ((delta (- (* b b) (* 4 a c))))
>> (delete-duplicates (list (/ (- (- b) (sqrt delta)) 2 a)
>> (/ (+ (- b) (sqrt delta)) 2 a))
>> :test (function =)))))
>
> Consider why your code gives the wrong answer in this case:
>
> * (solve-quadratic 1d0 1d9 1d0)
> ;
>
> ; Warning: This function is undefined:
> ; SOLVE-LINEAR
> ;
> (-1.0d+9 0.0d0)
>
> The correct roots are roughly -1.0e+9 and 1.0e+9. For more information, read
> Knuth's bible or my OCaml book. Quadratic solutions are a pedagogical
> example of numerical stability problems. Thus, if the person asking is an
> undergraduate, perhaps he is expected to give a better answer?

If you want more precision, ask for more precision:

[22]> (solve-quadratic 1L0 1L9 1L0)
(-9.99999999999999999L8 -9.895302355289459229L-10)

Note that: (and (float-equal -9.99999999999999999L8 -1.0d+9)
(float-equal -9.895302355289459229L-10 0.0d0))

with: (defun float-equal (x y)
(cond ((not (zerop y)) (< (abs (- 1 (/ x y))) 0.0001))
((not (zerop x)) (< (abs (- 1 (/ y x))) 0.0001))
(t t)))


> Could you elaborate on what you think is incorrect about my average
> function? It was a joke, but I believe it is correct.

It fails on lists longer than CALL-ARGUMENTS-LIMIT which may be as
small as 50, and it "fails" when the items in the list are not
self-evaluating, giving unsuspected results, like erasing your hard disk.

--
__Pascal Bourguignon__ http://www.informatimago.com/
Our enemies are innovative and resourceful, and so are we. They never
stop thinking about new ways to harm our country and our people, and
neither do we. -- Georges W. Bush
.