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