3
$\begingroup$

I'm trying to evaluate a series of expressions, which, given a set of parameters, may be complex. Instead of throwing a CompiledFunction::cfn, I'm trying to catch it from within and reset it to some default value. Example:

cf = With[{NOTREAL = -1}, Compile[{{x, _Real}}, {Sqrt[x], Sqrt[-x]}]]
cf[100]

I want the return to be {10, -1} without invoking uncompiled function or MainEvaluate. If I used "RuntimeOptions" per Catching error in middle of evaluation of compiled function, the error would still be thrown and the evaluation wil be aborted. Is it possible to tell Mathematica to not evaluate when it sees a non-numeric value coming up and hand it over to some handler? And in reality Sqrt[x] will be replaced with some complicated function. Reduce can't figure out when it'll be real.

$\endgroup$
3
  • $\begingroup$ What about If[Abs[Im[x]]>1. 10^-12,{Sqrt[x],-1.},{Sqrt[x],Sqrt[-x]}]? $\endgroup$ Commented May 1, 2020 at 15:38
  • $\begingroup$ @HenrikSchumacher It worked! I tried Im/@ before posting but the same error is thrown, but directly applying Im to each result prevents it. Might have to do with how type inference works. $\endgroup$
    – arax
    Commented May 1, 2020 at 19:21
  • $\begingroup$ That's good to hear! Best practice is to catch errors before they occur... ;) $\endgroup$ Commented May 1, 2020 at 19:23

1 Answer 1

3
$\begingroup$

Thanks to @HenrikSchumacher 's comment, I came up with the following

cf = With[{NOTREAL = -1}, Compile[{{x, _Real}},
   Module[{cx = I},
    cx = x;
    If[Abs[Im@#] > 1.*^-12, NOTREAL, Re@#] & /@ {Sqrt[-cx], Sqrt[cx]}]]
  ]

CompilePrint shows that this forces Mathematica to recognize the result of Sqrt as complex, avoiding numerical exception.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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