Directed infinities



I think we had serveral attempts to handle infinities more correct. I have tried
a next one.

At first I have introduced the generalized concept of a directed infinity and
implemented it as a simplifying Maxima function:

   directed_infinity(z)   z is in general a complex value

The internal representation is

   ((%directed_infinity) z)

I have chossen the following definitions:

directed_infinity(1)     ---> '$inf
directed_infinity(-1)    ---> '$minf
directed_infinity(0)     ---> '$infinity
directed_infinity(false) ---> '$und or '$ind

I have not distinguished beetween '$und and '$ind and call both cases
indeterminate.

Next I have implemented the arithmetic (addition, multiplication,
exponentiation) for directed infinities. The code is directly implemented in the
simplifying functions for add, mul and power. I have tried to be complete. These
are examples:

Numbers and symbols are absorbed from the directed infinity:

(%i5) 10+x+y+directed_infinity(z)+0+a+1+2*a
(%o5) directed_infinity(z)

The addition of inf and inf gives inf:

(%i19) directed_infinity(1)+directed_infinity(1)
(%o19) directed_infinity(1)

The addition of inf and minf gives indeterminate:

(%i33) directed_infinity(1)+directed_infinity(-1)
(%o33) directed_infinity(false)

But subtraction of inf and minf gives again inf:

(%i101) directed_infinity(1)-directed_infinity(-1)
(%o101) directed_infinity(1)

Multiplication with Zero gives indeterminate:

(i165) 0*directed_infinity(1)
(%o165) directed_infinity(false)
(%i167) 0*directed_infinity(-1)
(%o167) directed_infinity(false)
(%i169) 0*directed_infinity(0)
(%o169) directed_infinity(false)

Expressions in a multiplication are absorbed as an argument of the directed
infinity. The argument is simplified to the complex signum value:

(%i423) z*directed_infinity(1);
(%o423) directed_infinity(z/abs(z))

(%i424) (1+%i)*directed_infinity(1);
(%o424) directed_infinity((%i+1)/sqrt(2))
(%i425) sin(x)*directed_infinity(1);
(%o425) directed_infinity(sin(x)/abs(sin(x)))

The general case which simplifies to the correct expressions:

(%i243) directed_infinity(x)*directed_infinity(y)
(%o243) directed_infinity(x*y/(abs(x)*abs(y)))

Division of Zero through infinities:

(%i245) 0/directed_infinity(1)
(%o245) 0

But 

(%i251) 0/directed_infinity(false)
(%o251) directed_infinity(false)

Zero and a directed infinity as a power:

(%i325) 0^directed_infinity(1)
(%o325) 0
(%i327) 0^directed_infinity(-1)
(%o327) directed_infinity(0)

Nested directed infinities are simplified:

(%i430) directed_infinity(directed_infinity(z));
(%o430) directed_infinity(z/abs(z))

Because the directed infinity is implemented as a function, Maxima has no
problems. Nothing has changed. But it might be possible to introduce the
directed infinity step by step into the algorithm of Maxima.

To do this in principle it should be possible to replace e.g.

'$inf  --> ((%directed_infinity) 1)

Next we have to change the tests against the symbol '$inf, '$minf, ... e. g.

(eq sym '$inf)            --> (infinity-p sym)
(eq sym '$minf)           --> (minus-infinity-p sym)
(eq sym '$infinity)       --> (complex-infinity-p sym)

(member sym '($inf $min)) --> (real-infinity-p sym)

It is also possible to simplify the directed infinities to the symbols
'$inf,'$minf, ... and call the algorithm.

I think there are a lot of possible solutions and extensions which will work
with a more general concept like the directed infinities.

This is an example of a piece of code which handles the case with a directed
infinity as the base of a power function. This code is added to simpexpt:

;; The base is one of the infinities or indeterminate
((directed-infinity-p gr)
 (cond ((or (zerop1 pot)
            (indeterminate-p pot)
            (indeterminate-p gr))
        (return (list '(%directed_infinity) nil)))
       ((onep1 (mul -1 pot))
        (cond ((not (indeterminate-p gr))
               (return 0))
              (t
               (return (list '(%directed_infinity) nil)))))
       ((infinity-p gr)
        (cond ((infinity-p pot)
               (return (list '(%directed_infinity) 0)))
              ((minus-infinity-p pot)
               (return 0))
              (t
               (return (list '(%directed_infinity) nil)))))
       ((minus-infinity-p gr)
        (cond ((infinity-p pot)
               (return (list '(%directed_infinity) 0)))
              ((minus-infinity-p pot)
               (return 0))
              (t
               (return (list '(%directed_infinity) nil)))))
             ((complex-infinity-p gr)
              (cond ((infinity-p pot)
                     (return (list '(%directed_infinity) 0)))
                    ((minus-infinity-p pot)
                     (return 0))
             (t
              (return (list '(%directed_infinity) nil)))))
       ((not (indeterminate-p gr))
        (cond ((infinity-p pot)
               (return (list '(%directed_infinity) 0)))
              ((minus-infinity-p pot)
               (return 0))
              (t
               (return (list '(%directed_infinity) nil)))))
       (t
         (return (list '(%directed_infinity) nil)))))

This is the simplifying function for a directed infinity (here a simplification
to the symbols '$inf,... can be added):

(defun simp-directed-infinity (expr z simpflag)
  (oneargcheck expr)
  (setq z (simpcheck (cadr expr) simpflag))
  (cond 
    ((eq z nil)
     (eqtest (list '(%directed_infinity) z) expr))
    ((directed-infinity-p z)
     (simplify (list '(%directed_infinity) (cadr z))))
    ((not (eq ($csign z) '$zero))
     (eqtest (list '(%directed_infinity) 
                   (div z (simplify (list '(mabs) z)))) expr))
    (t
      (eqtest (list '(%directed_infinity) z) expr))))

Comments are welcome.

Dieter Kaiser