[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [srfi-70] Limit

This page is part of the web mail archives of SRFI 70 from before July 7th, 2015. The new archives for SRFI 70 contain all messages, not just those from before July 7th, 2015.




Jens Axel Søgaard wrote:
> The draft says
>
>    Function: limit proc z1 z2
>    Function: limit proc -1/0
>    Function: limit proc 1/0
>
>      Proc must be a procedure taking a single inexact argument.
>
>      Limit computes the mathematical limit of proc as its argument
>      approaches z1 from z1 + z2. Limit returns a complex number or
>      real infinity if the limit exists; and `#f' otherwise.
>
> Is this well defined?

No, of course it is not.

It is another smoke screen of the "wish it were so" type related to floating point
representations of rational numbers.

It might be amusing to see what an implementation of LIMIT makes of
the usual suspects. I tried some in the reference implementation (after
killing the infinite loop for almost-zero in sequence->limit and replacing
the not-yet-introduced syntax "1/0" by +inf.0 using PLT.) Examples:

1. The "mathematical limit" for f(x) = sin(x)/x for x -> 1 exists. It is equal to 1,
as can be shown by applying l'Hospital's Theorem once.

In the program:

        (limit (lambda (x) (/ (sin x) x)) 0 1) => "division by zero"

(As sin(x)/x is the Fourier-transform of a rectangle this function does actually
crop up in practice; it is usually coded to catch the "small |x|" case explicitly.)

2. The function f(x) = sin(c/x) for some constant c > 0 has no limit for x -> 0.
It comes arbitrarily close to each point in {(0, y) : -1 <= y <= 1}.

With the program you can select your favorite limiting value by varying c:

        (limit (lambda (x) (sin (/ 1.0 x))) 0 1) => #f                ; according to spec
        (limit (lambda (x) (sin (/ 0.2 x))) 0 1) => 1/0
        (limit (lambda (x) (sin (/ 0.3 x))) 0 1) => -1/0


But seriously... The problem with LIMIT is that it tries to solve an unsolvable
problem. There is no "finite-precision version" of taking general limits. For
certain types of limits, e.g. integrals, there is a theory what you get and how
useful that might be. These computations are usually not limits of simple
sequences but some sort of infinite summation with known convergence
properties (e.g. all the standard transcendental functions, exp/log/sin/cos etc.)

A general LIMIT procedure on the other hand can only be specified as "returns
what the reference implementation computes." Unless you want to redefine the
meaning of "mathematical limit", which might be exceptionally controversal.

What I said until now is just the famous "It might work in practice, but it will
never work in theory." Now my real problem is that I missed which important
problem the LIMIT procedure solves (satisfactorily or not) in Scheme.

Cetero censeo...
1. Make sure the language does have arbitary rational numbers.
2. Get rid of "inexact numbers."
3. Define separate industrial-strength floating point libraries.

Sebastian.