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

Re: comparison operators and *typos



 | Date: Mon, 27 Jun 2005 02:29:12 -0400
 | From: Paul Schlie <schlie@xxxxxxxxxxx>
 | 
 | I wonder if the following may represent a reasonable balance between
 | existing assumptions/practice/code and the benefits of a virtually
 | bounded reciprocal real number system:
 | 
 |   1/0    ==  inf   ; exact sign-less 0 and corresponding reciprocal.
 |   1/0.0  ==  inf.0 ; inexact sign-less 0.0 and corresponding reciprocal.
 |   1/-0   == -inf   ; exact signed 0, and corresponding reciprocal.
 |   1/-0.0 == -inf.0 ; inexact signed 0, and corresponding reciprocal.
 |   1/+0   == +inf   ; exact signed 0, and corresponding reciprocal.
 |   1/+0.0 == +inf.0 ; inexact signed 0, and corresponding reciprocal.
 | 
 |   (where sign-less infinities ~ nan's as their sign is ambiguous)
 | 
 | And realize I've taken liberties designating values without decimal points
 | as being exact, but only did so to enable their symbolic designation if
 | desired to preserve the correspondence between exact and inexact
 | designations. (as if -0 is considered exact, then so presumably must -1/0)
 | 
 | Thereby one could define that an unsigned 0 compares = to signed 0's to
 | preserve existing code practices which typically compare a value against
 | a sign-less 0. i.e.:
 | 
 |  (= 0 0.0 -0 -0.0) => #t
 |  (= 0 0.0 +0 +0.0) => #t
 | 
 |  (= -0 -0.0 +0 +0.0) => #f

The `=' you propose is not transitive, which is a requirement of R5RS.

 | While preserving the ability to define a relative relationship between
 | the respective 0 values:
 | 
 |  (< 1/-0 -0 +0 1/+0) => #t
 | 
 |  (<= 1/-0 1/-0.0 -0 -0.0 0 +0 +0.0 1/+0 1/+0.0) => #t
 | 
 |  (= 1/0 1/0.0) => #t ; essentially nan's
 |  (= 1/0 1/+0)  => #f ; as inf (aka nan) != +inf
 | 
 | Correspondingly, it seems desirable, although apparently contentious:
 | 
 |  1/0 == inf :: 1/inf == 0 :: 0/0 == 1/1 == inf/inf == 1

Are you saying that (/ 0 0) ==> 1 or that (= 0/0 1)?

Mathematical division by 0 is undefined; if you return 1, then code
receiving that value can't detect that a boundary case occured.

 | and (although most likely more relevant to SRFI 70):
 | 
 |   x^y == 1 
 | 
 | As lim{|x|==|y|->0} x^y :: lim{|x|==|y|->0} (exp (* x (log y))) = 1
 | 
 | As it seems that the expression should converge to 1 about the
 | limit of 0; as although it may be argued that the (log 0) -> -inf,
 | it does so at an exponentially slower rate than it's operand,
 | therefore: lim{|x|==|y|->0} (* x (log y)) = 0, and lim{|x|==|y|->0}
 | (exp (* x (log y))) = (exp 0) = 1; and although it can argued that
 | it depends on it's operands trajectories and rates, I see no valid
 | argument to assume that it's operands will not approach that limit
 | at equivalent rates from equidistances,

That would mean that the program was computing some variety of x^x.

Lets look at some real examples.  FreeSnell is a program which
computes optical properties of multilayer thin-film coatings.
It has three occurrences of EXPT:

  opticolr.scm:152: (let ((thk (* (expt ratio-thk (/ (+ -1 ydx) (+ -1 cnt-thk)))
  opticolr.scm:173: (let ((thk (* (expt ratio-thk (/ (+ -1 ydx) (+ -1 cnt-thk)))

These two are computing a geometric sequence of thicknesses.  It is an
error if either argument to EXPT is 0.

  opticompute.scm:131: (let ((winc (expt (/ wmax wmin) (/ (+ -1 samples)))))

This one computes a ratio for a geometric sequence of wavelengths.  It
is an error if either argument to EXPT is 0.

There is also one occurence of EXP, which computes the phase
difference between reflected and/or transmitted paths:

  fresneleq.scm:82:  (define phase (exp (/ (* +2i pi h_j n_j (cos th_j)) w)))

Nearly all of the SLIB occurences of EXPT have at least one literal
constant argument.  In these cases, (expt 0 0) signaling an error
would catch coding errors.  MODULAR:EXPT tests for a zero base (and
returns 0) before calling EXPT.

 | which will also typically yield the most useful result, and tend
 | not to introduce otherwise useless value discontinuities and/or
 | ambiguities.

Grepping through a large body of Scheme code found no use of EXPT
where the two arguments are related.

(expt 0 0) ==> 1 is one of the possibilities for SRFI-70.  But I am
leaning toward the "0/0 or signal an error" choice to catch the rare
coding error.

 | Where I understand that all inf's are not strictly equivalent, but
 | when expressed as inexact values it seems more ideal to consider
 | +-inf.0 to be equivalent to the bounds of the inexact
 | representation number system, thereby +-inf.0 are simply treated as
 | the greatest, and +-0.0 the smallest representable inexact value;

<http://srfi.schemers.org/srfi-70/srfi-70.html#6.2.2x> shows that
inexact real numbers correspond to intervals of the real number line.
Infinities corresponding to the remaining half-lines gives very clean
semantics for inexact real numbers.  Infinitesimals (+-0.0) are a
solution in search of a problem.

 | as +-1/0 and +-0 may be considered abstractions of exact infinite
 | precision values if desired.
 | 
 | However as it's not strictly compatible with many existing floating
 | point implementations, efficiency may be a problem? (but do like
 | it's simplifying symmetry).
 | 
 |