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

Re: comparison operators and *typos

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



 | 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).
 | 
 |