Simplification of sqrt(1/z)



We have the bug reports

Bug ID: 1010768 - sqrt(1/z) - 1/sqrt(z) => 0
Bug ID: 2852992 - sqrt(-1/x)-%i/sqrt(x) not zero

Furthermore, I think we can trigger a lot of more related bugs.

These problems are caused by different parts of code in the routine
simpexpt. The code which is responsible for these bugs can be cut out.

First, the changes to correct the problem sqrt(1/z) -> 1/sqrt(z):

;; Handle (z^a)^b: gr = z^a and pot = b
     
(cond ((or (eq $radexpand '$all)
           (simplexpon pot)
           (noneg (cadr gr))
           ;; The following causes the simplification (1/z)^a -> 1/z^a.
           ;; This is not correct in general. We cut it out. DK 09/2009
;           (equal (caddr gr) -1)
           (and (eq $domain '$real)
                ;; Do not simplify (1/z)^a -> 1/z^a.
                (not (equal (caddr gr) -1))
                (odnump (caddr gr))))
       (setq pot (mult pot (caddr gr)) gr (cadr gr)))
      ((and (eq $domain '$real)
            (free gr '$%i)
            $radexpand
            (not (decl-complexp (cadr gr)))
            (evnump (caddr gr)))
       (setq pot (mult pot (caddr gr)) 
             gr (radmabs (cadr gr))))
      ;; The following simplifies (z^(-a))^b -> 1/(z^a)^b
      ;; Again this is wrong in general, e.g. for (z^(-1))^(1/2)
      ;; We cut out this code. DK 09/2009.
;      ((mminusp (caddr gr))
;       (setq pot (neg pot)
;             gr (list (car gr) (cadr gr) (neg (caddr gr)))))
      (t (go up)))

The following shows the code which is responsible for the second
problem.

      ;; The following code does the simplification:
      ;;    (-1/x)^a -> 1/(-x)^a
      ;; In general this is wrong and causes e.g. the bug
      ;;    sqrt(-1/x) -> -%i/sqrt(x) for x>0. See Bug ID: 2852992.
      ;; We cut out this code. DK 09/2009.
;      ((and (or (not (numberp (cadr gr))) (equal (cadr gr) -1))
;            (setq w (member ($num gr) '(1 -1) :test #'equal)))
;       (setq pot (mult -1 pot) gr (mul2 (car w) ($denom gr)))

If we cut out the code which causes the wrong simplifications we will
get e.g.

(%i1) assume(x>0)$

x is positive. The difference simplifies to zero:

(%i2) sqrt(1/x)-1/sqrt(x);
(%o2) 0

The argument is negative. The sum simplifies to zero:

(%i3) sqrt(1/-x)+1/sqrt(-x);
(%o3) 0

We get a correct sign:

(%i5) sqrt(-1/x);
(%o5) %i/sqrt(x)

The simplification is correct for positive and negative numbers:

(%i6) sqrt(-1/x)-%i/sqrt(x);
(%o6) 0
(%i7) sqrt(-1/-x)-%i/sqrt(-x);
(%o7) 0

The testsuite has no serious problems: 

4 tests in rtest14.mac simplifes differently, because sqrt(1/x) is no
longer 1/sqrt(x).

In rtest_taylor.mac the following example gives a break with the message
"Unhandled var in stronger-var?":

   taylor(exp(sqrt(log(x)*log(log(x)))), x, inf, 2);

In rtest_integrate.mac 162 examples which involves sqrt expressions
fails, because sqrt(1/x) does not simplify to 1/sqrt(x).

Remark:

Only the code which causes wrong simplifications is cut out. There is no
further improvement. In a next step it is possible to add again some
rules to get more special simplifications.

Dieter Kaiser