Square root of the square of a complex number

Greetings, everyone!

Wolfram knows about the square root of the square of a real number.

In: Or[(z^2)^(1/2) == z, (z^2)^(1/2) == -z]//FullSimplify[#, z \[Element] Reals] &

Out: True

But in the complex domain:

In: Or[(z^2)^(1/2) == z, (z^2)^(1/2) == -z]//FullSimplify[#, z \[Element] Complexes] &

Out: Or[(z^2)^(1/2) == z, (z^2)^(1/2) == -z]

Doesn’t Wolfram know this?

This way it works:

In[12]:= ((z^2)^(1/2) - z) ((z^2)^(1/2) + z) // FullSimplify

Out[12]= 0

You’re right. It works. But it’s a different formula. My formula is theoretical, yours is algebraic. It’s derived from

In: Sqrt[z^2] Sqrt[z^2]

Out: z^2

Try with PowerExpand

In[1]:= Assuming[z\[Element]Complexes,Or[(z^2)^(1/2)==z,(z^2)^(1/2)==-z]//PowerExpand]

Out[1]= True

PowerExpand makes (z^2)^(1/2) into z.

Broadly speaking, simplifying means reducing the number of parts to an expression. In this case, you can help by breaking things up into cases for FullSimplify[] to put back together.

expr = Or[(z^2)^(1/2) == z, (z^2)^(1/2) == -z];
Reduce[expr && (Im[z] != 0 || z == Re[z]), z] // 
 FullSimplify[#, z \[Element] Complexes] &

(*  True  *)

In my reading of the documentation, PowerExpand[] assumes the variables are real by default; and to get PowerExpand[] to use the assumptions in Assuming[], one should use the option Assumptions :> $Assumptions. In that case, we get a different result:

Assuming[z \[Element] Complexes, 
 PowerExpand[Or[(z^2)^(1/2) == z, (z^2)^(1/2) == -z], 
  Assumptions :> $Assumptions]]
(*
E^(I \[Pi] Floor[1/2 - Arg[z]/\[Pi]]) z == z || 
 E^(I \[Pi] Floor[1/2 - Arg[z]/\[Pi]]) z == -z
*)

That’s great! But why didn’t Wolfram do it?

PS. To this we might add:

In: Im[z] != 0 || z == Re[z] // FullSimplify[#, z [Element] Complexes] &

Out: True

Re "But why didn’t Wolfram do it?:

Simplification means reducing the number of parts (so-called “leaves”; see the function LeafCount[]). When a step or sequence of steps creates many more leaves, the step sequence will often be rejected, even if pursuing it would eventually lead to the simplest possible answer. LeafCount[expr] is 21, and the leaf count of the Reduce[] output is 55, I’m not surprised the best solution wasn’t found. Reduce[], on the other hand, usually does not care about the leaf count.