4
$\begingroup$

I'm trying to implement a complex square root with branch cut on the negative real axis; the (real part of the) second argument determines which branch to take.

sqrt[x_?NumberQ, y_?NumberQ] = 
 Piecewise[{{I Sqrt[-x], Re[x] < 0 && y >= 0}, {-I Sqrt[-x], 
    Re[x] < 0 && y < 0}}, Sqrt[x]]

enter image description here

This works fine except when during calculations $y$ obtains a small imaginary part. Evaluating

sqrt[-1, 1 + 10^-12 I]

returns the error

GreaterEqual::nord: Invalid comparison with 1+I/1000000000000 attempted.

Now I could do the comparison with Re[y] instead of y and be done with it, but I'd actually like to know about it, if $y$ ever developed a significant imaginary part during my calculations so Chop[y] seems more prudent. But adding this to the definition of sqrt changes its behavior in no way whatsoever. In fact, the Chop doesn't even make it into the output when evaluating

sqrt[x_?NumberQ, y_?NumberQ] = 
 Piecewise[{{I Sqrt[-x], Re[x] < 0 && Chop[y] >= 0}, {-I Sqrt[-x], 
    Re[x] < 0 && Chop[y] < 0}}, Sqrt[x]]

Can someone explain why? Does this have something to do with Piecewise not having the attribute Hold?

$\endgroup$
2
  • 3
    $\begingroup$ "Can someone explain why? Does this have something to do with Piecewise not having the attribute Hold?" That seems likely. You could avoid this by using SetDelayed (:=) to define sqrt. Otherwise define, chop[x_?NumericQ]:=Chop[x] at use the new chop instead (which will not evaluate for non-numeric arguments). $\endgroup$
    – mmeent
    Jun 13 '17 at 11:16
  • $\begingroup$ @mmeent And the reason it works with Re is because "Re[expr] is left unevaluated if expr is not a numeric quantity."? (See doc). $\endgroup$
    – Casimir
    Jun 13 '17 at 15:11
5
$\begingroup$

From the documentation for Chop, "Chop[expr] replaces approximate real numbers in expr that are close to zero by the exact integer 0." Compare

Chop[{10^-12, 10^-12 // N}]

(*  {1/1000000000000, 0}  *)

Recommend that you use NumericQ rather than NumberQ

Clear[sqrt]

sqrt[x_?NumericQ, y_?NumericQ] :=
 Module[{yc = Chop[y // N]},
  Piecewise[{{I Sqrt[-x], Re[x] < 0 && yc >= 0}, {-I Sqrt[-x], 
     Re[x] < 0 && yc < 0}}, Sqrt[x]]]

sqrt[-1, 1 + 10^-12 I]

(*  I  *)
$\endgroup$
1
  • $\begingroup$ Good point. I meant to change that a while back but forgot about it in the meantime. $\endgroup$
    – Casimir
    Jun 13 '17 at 13:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.