Changes to the simplification of the sqrt function
Subject: Changes to the simplification of the sqrt function
From: Dieter Kaiser
Date: Sun, 17 Jan 2010 14:42:00 +0100
I have committed a patch to simp.lisp to get the simplification of the
sqrt function more correct.
The corrections are related to the following bug reports:
Bug ID: 1010768 - sqrt(1/z) - 1/sqrt(z) => 0
Bug ID: 2852992 - sqrt(-1/x)-%i/sqrt(x) not zero
Bug ID: 2933440 - sqrt(-z^2) simplifies to %i*sqrt(z^2) for z complex
Most interesting is that we now get correct numerical results for all
nested sqrt examples in the file rtest_sqrt.mac. This is because we no
longer have wrong simplifications of this expressions.
Now we get the following:
sqrt(1/x) no longer simplifies to 1/sqrt(x) when the sign of the
argument is not known:
(%i2) sqrt(1/x);
(%o2) sqrt(1/x)
It simplifies for a positive argument:
(%i3) assume(x>0)$
(%i4) sqrt(1/x);
(%o4) 1/sqrt(x)
We get the correct phase factor for the following:
(%i5) sqrt(-1/x);
(%o5) %i/sqrt(x)
For a complex argument z sqrt(-z^2) no longer simplifies wrongly:
(%i6) declare(z,complex)$
(%i7) sqrt(-z^2);
(%o7) sqrt(-z^2)
That is the result for a positive argument:
(%i8) sqrt(-x^2);
(%o8) %i*x
I have only tried to get the sqrt function more correct. More work is
needed to get the power function more correct too. This is a first step.
It is difficult to do the improvements without doing to much changes at
a lot of places at one time.
Another point is that it might be useful to implement some more
simplification which are correct in general. To get not to much problems
I have already introduced the simplification of sqrt(1/z) -> 1/sqrt(z)
for z a complex and constant expression:
(%i4) sqrt(1/(2+%i*sqrt(3)));
(%o4) 1/sqrt(sqrt(3)*%i+2)
If we insert specific values in the 19 examples for nested sqrt
functions in the file rtest_sqrt.mac we can identify useful
simplifications which are necessary to get a fully simplified result.
E.g. the following can be improved:
(%i1) assume(x>0)$
(%i2) sqrt(1/(x+1)); /* OK we have a positive expression */
(%o2) 1/sqrt(x+1)
(%i3) sqrt(-1/(x+1)); /* OK correctly simplified */
(%o3) %i/sqrt(x+1)
(%i4) sqrt(1/-(x+1)); /* Bad should simplify too */
(%o4) sqrt(1/(-x-1))
As written the most serious problem was to get the function radcan to
work with the improved simplification of the sqrt function. radcan
already introduces the flag $ratsimpexpons. This flag is used to switch
on the simplification sqrt(1/x) -> 1/sqrt(x) when we are in radcan.
Radcan depends on this simplification and will hang without it.
I hope we will not get too much unexpected errors at other places of the
code.
Dieter Kaiser