Simplification of infinities



Understood that you first wanted to prototype the functionality before
working on efficiency -- I agree that this is the best way to do things.  As
Fateman points out, though, the simplus/times/etc. routines are central to
Maxima and their efficiency may actually matter in some cases (though not of
course in simple cases).

So here are some ideas you may be able to use to make your simplification
functions run more efficiently:

1) Take advantage of the sort order so that you don't have to inspect all
arguments.  Since inf/und/etc. are sysconst's, they sort with %pi, %e, etc.
-- between explicit numbers and non-constant objects. I haven't looked to
see if simplus etc. take advantage of this in any way today, but it is a
possibility.

2) Do as much as possible in a single pass; rather than calling intersection
on all the arguments, call memq (that is, member with an eq test) on each
argument along with other tests.

Thanks for adding this useful functionality!

             -s


On Sun, Dec 6, 2009 at 2:10 PM, Dieter Kaiser <drdieterkaiser at web.de> wrote:

> Am Sonntag, den 06.12.2009, 10:25 -0800 schrieb Richard Fateman:
> > Dieter Kaiser wrote:
> > > I think I have found a way to implement the simplification of
> > > infinities, which will work well with the testsuite.
> > >
> >
> > There is another issue here, which is the following:
> >
> > Does the change slow down the system?
>
> Yes, this is an issue. I have not done any timing experiments at this
> time. But I will check this. At first I was interested in a working
> algorithm.
>
> The main idea of the code is to have a function which simplifies
> expressions which contains infinities in general. This is the main
> simplifying routine:
>
> (defun simp-infinities (expr)
>  (cond
>    ((or (atom expr) (mnump expr)) expr)
>    ((not (intersection '($inf $minf $infinity $und $ind) expr)) expr)
>    ((member '$und expr) '$und)
>    ((mplusp expr) (simpplus-infinities expr))
>    ((mmminusp expr) (simp-infinities (mul -1 (cadr expr))))
>    ((mtimesp expr) (simptimes-infinities expr))
>    ((mexptp expr) (simpexpt-infinities expr))
>    (t
>     (cons (car expr) (mapcar #'simp-infinities (cdr expr))))))
>
> This routine calls the appropriate simplifying function for an operator.
> The following routine implements the logic to simplify the sum of
> infinities and indeterminates:
>
> (defun simpplus-infinities (expr)
>  (let ((args (if (atom expr) expr (cdr expr))) cnt)
>    (setq args (mapcar #'simp-infinities args))
>    (if (intersection '($inf $minf $infinity $ind $und) args)
>        (cond
>          ((or (atom args)
>               (mnump args)) args)
>          ((member '$und args) '$und)
>          ((member '$ind args) '$und)
>          ((and (member '$inf args)
>                (member '$minf args)) '$und)
>          ((> (setq cnt (count '$infinity args)) 0)
>           (if (= cnt 1) '$infinity '$und))
>          ((member '$inf args) '$inf)
>          ((member '$minf args) '$minf)
>          (t '$und))
>        (simplify (cons '(mplus) args)))))
>
> The simplification for an mplus expression is invoked in simplus:
>
> (defmfun simplus (x w z)                ; W must be 1
>  (prog (res check eqnflag matrixflag sumflag)
>     (if (null (cdr x)) (return 0))
>     (setq check x)
> -->  (if (intersection '($inf $minf $infinity $ind $und) x)
>         (return (simp-infinities x)))
>     ...
>
> The code will slow down because we have to check if one of the arguments
> to the "+"-operator is one of the infinities or indeterminates. Similar
> checks are implemented for the operator "*" in simptimes and for the
> operator "^" in simpexpt.
>
> One advantage of this approach is, that the simplification of infinities
> is completely separated from the current simplifier. This allows to
> separate possible problems too. Furthermore, I think this is the reason,
> why the code works so well with the testsuite.
>
> The disadvantage is, that we have to check every time we enter the
> simplifying routine like simplus for infinities.
>
> > now  if 1/inf or  1/infinity   is simplified to 0, several of the rules
>
> The implementation of rules is very flexible. It is a matter of
> agreement what rules actually are needed. At this time the following
> simplifications will occur for the reciprocal of infinities:
>
> (%i14) 1/inf;
> (%o14) 0
> (%i15) 1/minf;
> (%o15) 0
> (%i16) 1/infinity;
> (%o16) 0
>
> Dieter Kaiser
>
>
> _______________________________________________
> Maxima mailing list
> Maxima at math.utexas.edu
> http://www.math.utexas.edu/mailman/listinfo/maxima
>