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$
  • $\begingroup$ What about If[Abs[Im[x]]>1. 10^-12,{Sqrt[x],-1.},{Sqrt[x],Sqrt[-x]}]? $\endgroup$ – Henrik Schumacher May 1 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 May 1 at 19:21
  • $\begingroup$ That's good to hear! Best practice is to catch errors before they occur... ;) $\endgroup$ – Henrik Schumacher May 1 at 19:23
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.

| improve this answer | |
$\endgroup$

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.