I have collected known properties of the sqrt function in a wxMaxima
file to document the knowledge of Maxima about the sqrt function.
The file contains e.g. known specific values, symmetry rules, series
representations, differential equations, complex characteristics,
differentiation, integration, integral transforms, limits, and of course
transformations and simplification rules.
The file contains 19 expressions with nested sqrt functions which should
all simplify to zero:
sqrt(-1-z)*sqrt(1/(1+z))*sqrt(1/z)*sqrt(-z)+1;
sqrt((z-1)/z)*sqrt(z/(1-z))-sqrt(-1/z)*sqrt(z);
sqrt(sqrt(z^2+1)-1)/sqrt(1-sqrt(z^2+1))-sqrt(z^2)/sqrt(-z^2);
sqrt(sqrt(1-z^2)-1)/sqrt(1-sqrt(1-z^2))-sqrt(-z^2)/sqrt(z^2);
sqrt(sqrt(z^2+1)-z)/sqrt(z-sqrt(z^2+1))+sqrt(z)*sqrt(-1/z);
sqrt(z+sqrt(z^2+1))/sqrt(-z-sqrt(z^2+1))+sqrt(-z)*sqrt(1/z);
sqrt(sqrt(1-z^2)-%i*z)/sqrt(%i*z-sqrt(1-z^2))+sqrt(%i*z)*sqrt(%i/z);
sqrt(%i*z+sqrt(1-z^2))/sqrt(-%i*z-sqrt(1-z^2))+sqrt(-%i*z)*sqrt(-%i/z);
sqrt(z^2/(1-sqrt(1-z^2)))*sqrt((1-sqrt(1-z^2))/z^2)-1;
sqrt(z/(sqrt(z^2+1)-z))*sqrt((sqrt(z^2+1)-z)/z)-sqrt(1/(z^2+1))
*sqrt(z^2+1)-sqrt(1/z)*sqrt(z)+1;
sqrt(sqrt(z)-1)*sqrt(sqrt(z)+1)-sqrt(z-1);
sqrt(sqrt(z+1)-1)*sqrt((sqrt(z+1)+1))-sqrt(z);
sqrt(2)*sqrt(1-sqrt(1-z))*sqrt(sqrt(1-z)+%i*sqrt(z))
/(%i*(1-sqrt(1-z))+sqrt(z))-1;
sqrt(1-z)*(1+z-%i*sqrt(1-z^2))/(sqrt(z+1)*sqrt(1-z+%i*sqrt(1-z^2)))+%i;
sqrt(1-z)*(1+z+%i*sqrt(1-z^2))/(sqrt(z+1)*sqrt(1-z-%i*sqrt(1-z^2)))-%i;
1/sqrt(1-sqrt(z))+1/sqrt(1+sqrt(z))-sqrt(2)*sqrt(sqrt(1-z)+1)/sqrt(1-z);
1/sqrt(1-sqrt(z))-1/sqrt(1+sqrt(z))-sqrt(2)*sqrt(1-sqrt(1-z))/sqrt(1-z);
sqrt(1+sqrt(z))+sqrt(1-sqrt(z))-sqrt(2)*sqrt(1+sqrt(1-z));
sqrt(1+sqrt(z))-sqrt(1-sqrt(z))-sqrt(2)*sqrt(1-sqrt(1-z));
Only one of this examples (number 9) is simplified by the simplifier to
zero. But this is not the problem.
Three examples in more detail:
EXAMPLE 1 (number 1 from above):
(%i1) declare(z,complex);
(%o1) done
The expression is not simplified by the simplifier:
(%i3) expr:sqrt(-1-z)*sqrt(1/(1+z))*sqrt(1/z)*sqrt(-z)+1;
(%o3) sqrt(-z-1)*sqrt(-z)/(sqrt(z)*sqrt(z+1))+1
We get correct answers for a positive or negative number:
(%i4) expr,z=2;
(%o4) 0
(%i5) expr,z=-2;
(%o5) 0
The answer for a complex number is not simplified:
(%i6) expr,z=1+%i;
(%o6) sqrt(-%i-2)*sqrt(-%i-1)/(sqrt(%i+1)*sqrt(%i+2))+1
But we can evaluate it to be approximately zero:
(%i7) rectform(expr),z=1+%i,bfloat;
(%o7) -4.388541835720876b-18*%i
Radcan simplifies to zero:
(%i8) radcan(expr);
(%o8) 0
But rootscontract simplifies wrongly:
(%i9) rootscontract(expr);
(%o9) 2
EXAMPLE 2 (number 4 from above):
Now an example where radcan fails but rootscontract is correct:
(%i10) expr:sqrt(sqrt(1-z^2)-1)/sqrt(1-sqrt(1-z^2))
-sqrt(-z^2)/sqrt(z^2);
(%o10) sqrt(sqrt(1-z^2)-1)/sqrt(1-sqrt(1-z^2))-%i
For a positive or negative number no simplification to zero, but
approximately zero:
(%i11) expr,z=2;
(%o11) sqrt(sqrt(3)*%i-1)/sqrt(1-sqrt(3)*%i)-%i
(%i13) rectform(expr),z=2,bfloat;
(%o13) 0.0b0
(%i14) expr,z=-2;
(%o14) sqrt(sqrt(3)*%i-1)/sqrt(1-sqrt(3)*%i)-%i
(%i15) rectform(%),z=-2,bfloat;
(%o15) 0.0b0
Radcan simplifies to a wrong result:
(%i16) radcan(expr);
(%o16) -2*%i
For this example rootscontract gets a correct result:
(%i17) rootscontract(expr);
(%o17) 0
EXAMPLE 3 (number 5 from above):
^
(%i18) expr:sqrt(sqrt(z^2+1)-z)/sqrt(z-sqrt(z^2+1))+sqrt(z)*sqrt(-1/z);
(%o18) sqrt(sqrt(z^2+1)-z)/sqrt(z-sqrt(z^2+1))+sqrt(z)/sqrt(-z)
In this case the original expression is already wrong simplified. We get
a wrong answer for a positive number:
(%i19) expr,z=2;
(%o19) sqrt(sqrt(5)-2)/sqrt(2-sqrt(5))-%i
(%i20) expr,z=2,bfloat;
(%o20) -2.0b0*%i
But for a negative or complex value the answer is approximately correct:
(%i21) expr,z=-2,bfloat;
(%o21) 0.0b0
(%i24) rectform(expr),z=1+%i,bfloat;
(%o24) 0.0b0
Both radcan and rootscontract now gives a wrong answer:
(%i25) radcan(expr);
(%o25) -2*%i
(%i26) rootscontract(expr);
(%o26) 2*%i
These three examples shows some of the problems. We have a lot of
possibilities to get wrong answers. For some example radcan is correct
for others rootscontract. By the way, the use of the flags radexpand and
rootsconmode does not help to get better results. Furthermore it does
not help to use a real symbol, or symbols which are assumed to be
positive or negative.
More worse I think is, that we can get wrong results for simple positive
and negative numbers.
These are known bugs which are related to the problems observed with
nested sqrt functions:
BUG ID: 1010768 - sqrt(1/z) - 1/sqrt(z) => 0
BUG ID: 2820202 - rootscontract(%i/2);
Dieter Kaiser